Decompiled source of ExperimentalEnemyInteraction v0.4.0

DLLs/fandovec03.NaturalSelection.dll

Decompiled 2 days 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 LethalNetworkAPI;
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("990.2.4.0")]
[assembly: AssemblyInformationalVersion("990.2.4+0d441de9e8c41a8404d7d925addafe14a8bce8e3")]
[assembly: AssemblyProduct("NaturalSelection")]
[assembly: AssemblyTitle("fandovec03.NaturalSelection")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("990.2.4.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", "990.2.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Script : BaseUnityPlugin
	{
		internal static bool stableToggle;

		internal static float clampedAgentRadius;

		internal static bool isExperimental;

		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);
			if ("990.2.4".Contains("99"))
			{
				isExperimental = true;
			}
			Patch();
			Logger.LogInfo((object)"fandovec03.NaturalSelection v990.2.4 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 ...");
			if (isExperimental)
			{
				Logger.LogError((object)("LOADING EXPERIMENTAL " + "NaturalSelection".ToUpper() + ", DOWNLOAD STABLE NATURAL SELECTION INSTEAD!"));
			}
			Harmony.PatchAll(typeof(AICollisionDetectPatch));
			Harmony.PatchAll(typeof(EnemyAIPatch));
			Harmony.PatchAll(typeof(Networking));
			Harmony.PatchAll(typeof(NetworkingMethods));
			try
			{
				NaturalSelectionLib.LibrarySetup(Logger, BoundingConfig.spammyLogs.Value, BoundingConfig.debugTriggerFlags.Value);
				Logger.LogMessage((object)"Library successfully setup! Version 0.6.2-beta");
			}
			catch
			{
				Logger.LogError((object)"Failed to setup library!");
			}
			Harmony.PatchAll(typeof(RoundManagerPatch));
			if (BoundingConfig.enableLeviathan.Value)
			{
				Harmony.PatchAll(typeof(SandWormAIPatch));
			}
			if (BoundingConfig.enableSlime.Value)
			{
				Harmony.PatchAll(typeof(BlobAIPatch));
			}
			if (BoundingConfig.enableHoardingBug.Value)
			{
				Harmony.PatchAll(typeof(HoarderBugPatch));
			}
			if (BoundingConfig.enableRedBees.Value)
			{
				Harmony.PatchAll(typeof(BeeAIPatch));
			}
			if (BoundingConfig.enableGiant.Value)
			{
				Harmony.PatchAll(typeof(ForestGiantPatch));
			}
			if (!stableToggle)
			{
				if (BoundingConfig.enableNutcracker.Value)
				{
					Harmony.PatchAll(typeof(NutcrackerAIPatch));
				}
				if (BoundingConfig.enableSporeLizard.Value)
				{
					Harmony.PatchAll(typeof(PufferAIPatch));
				}
				if (BoundingConfig.enableSpider.Value)
				{
					Harmony.PatchAll(typeof(SandSpiderAIPatch));
				}
				Harmony.PatchAll(typeof(SandSpiderWebTrapPatch));
				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 = "990.2.4";
	}
}
namespace NaturalSelection.Generics
{
	internal class MyModConfig
	{
		public readonly ConfigEntry<bool> sandwormCollisionOverride;

		public readonly ConfigEntry<bool> blobAICantOpenDoors;

		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> enableNutcracker;

		public readonly ConfigEntry<bool> enableGiant;

		public readonly ConfigEntry<bool> enableHoardingBug;

		public readonly ConfigEntry<int> giantExtinguishChance;

		public readonly ConfigEntry<float> beesSetGiantsOnFireMinChance;

		public readonly ConfigEntry<float> beesSetGiantsOnFireMaxChance;

		public readonly ConfigEntry<bool> blobConsumesCorpses;

		public readonly ConfigEntry<bool> blobPathfindToCorpses;

		public readonly ConfigEntry<bool> blobPathfind;

		public readonly ConfigEntry<bool> sandwormDoNotEatPlayersInsideLeavingShip;

		public readonly ConfigEntry<bool> sandwormFilterTypes;

		public readonly ConfigEntry<string> beeBlacklist;

		public readonly ConfigEntry<string> blobBlacklist;

		public readonly ConfigEntry<string> sandwormBlacklist;

		public readonly ConfigEntry<bool> debugBool;

		public readonly ConfigEntry<bool> spammyLogs;

		public readonly ConfigEntry<bool> debugTriggerFlags;

		public readonly ConfigEntry<bool> debugNetworking;

		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;
			sandwormCollisionOverride = cfg.Bind<bool>("Experimental Fixes", "Sandworm collision override", false, "Override vanilla sandworm collisions. May fix lag when sandworm collides with multiple enemies at once");
			blobAICantOpenDoors = cfg.Bind<bool>("Experimental Fixes", "Blob cannot open doors", true, "Blob can't open doors.");
			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, "Enable changes to spider and modify it's behavior. DEV ONLY");
			enableSlime = cfg.Bind<bool>("Entity settings", "Enable slime", true, "Enable changes to slime and modify it's behavior.");
			enableLeviathan = cfg.Bind<bool>("Entity settings", "Enable leviathan", true, "Enable changes to leviathan and modify it's behavior.");
			enableSporeLizard = cfg.Bind<bool>("WIP", "Enable SporeLizard", false, "Enable changes to spore lizard. DEV ONLY");
			enableRedBees = cfg.Bind<bool>("Entity settings", "Enable Red bees (Circuit bees)", true, "Enable changes red bees and modify it's behavior.");
			enableNutcracker = cfg.Bind<bool>("WIP", "Enable Nutcracker", false, "Enable changes to nutcracker and modify its behavior. DEV ONLY");
			enableGiant = cfg.Bind<bool>("Entity settings", "Enable Giant", false, "Enable changes to forest giant.");
			enableHoardingBug = cfg.Bind<bool>("WIP", "Enable Hoarding bug", false, "Enable changes to hoarding bug");
			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");
			blobConsumesCorpses = cfg.Bind<bool>("Entity settings", "(Blob) Consume corpses", true, "Hydrogire consume enemy corpses");
			blobPathfindToCorpses = cfg.Bind<bool>("Entity settings", "(Blob) Pathfind to corpses", true, "Hydrogire move towards corpses to consume");
			blobPathfind = cfg.Bind<bool>("Entity settings", "(Blob) Pathfind", true, "Pathfind to other entities");
			sandwormDoNotEatPlayersInsideLeavingShip = cfg.Bind<bool>("Entity settings", "(Sandworm) Do not eat players inside leaving ship", false, "Worms do not eat players inside ship leaving the moon.");
			sandwormFilterTypes = cfg.Bind<bool>("Entity settings", "(Sandworm) Filter out enemy types", true, "Filter out enemies by the enemy type. Disabling this allows sandworms to attack other enemies. Blacklisting enemies is highly recommended when this setting is disabled.");
			beeBlacklist = cfg.Bind<string>("Blacklists", "Bees Blacklist", "", "Any enemy inside the blacklist will be ignored by others. \n \n [The ',' acts as a separator]");
			blobBlacklist = cfg.Bind<string>("Blacklists", "Blob Blacklist", "", "Any enemy inside the blacklist will be ignored by others. \n \n [The ',' acts as a separator]");
			sandwormBlacklist = cfg.Bind<string>("Blacklists", "Sandworm Blacklist", "", "Any enemy inside the blacklist will be ignored by others. \n \n [The ',' acts as a separator]");
			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.");
			debugNetworking = cfg.Bind<bool>("Debug", "Debug networking", false, "Enables debug logs for networking.");
			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();
		}
	}
	public class Networking
	{
		public static Dictionary<string, int> NetworkingDictionary = new Dictionary<string, int>();

		private static bool logNetworking = Script.BoundingConfig.debugNetworking.Value;

		public static LNetworkVariable<float> NSEnemyNetworkVariableFloat(string NWID)
		{
			if (!NetworkingDictionary.ContainsKey(NWID))
			{
				NetworkingDictionary.Add(NWID, 31);
			}
			return LNetworkVariable<float>.Connect(NWID, 0f, (LNetworkVariableWritePerms)0, (Action<float, float>)null);
		}

		public static LNetworkEvent NSEnemyNetworkEvent(string NWID)
		{
			if (!NetworkingDictionary.ContainsKey(NWID))
			{
				NetworkingDictionary.Add(NWID, 2);
			}
			return LNetworkEvent.Connect(NWID, (Action<ulong>)null, (Action)null, (Action<ulong>)null);
		}

		public static void ClearSubscribtionsInDictionary()
		{
			foreach (KeyValuePair<string, int> item in NetworkingDictionary)
			{
				switch (item.Value)
				{
				case 2:
					if (logNetworking)
					{
						Script.Logger.LogDebug((object)("Clearing subscriptions of event " + item.Key));
					}
					LNetworkEvent.Connect(item.Key, (Action<ulong>)null, (Action)null, (Action<ulong>)null).ClearSubscriptions();
					break;
				case 31:
					if (logNetworking)
					{
						Script.Logger.LogDebug((object)("Disposing of network float " + item.Key));
					}
					LNetworkVariable<float>.Connect(item.Key, 0f, (LNetworkVariableWritePerms)0, (Action<float, float>)null).Dispose();
					break;
				}
			}
			Script.Logger.LogInfo((object)"/Networking/ Finished clearing dictionary.");
			NetworkingDictionary.Clear();
		}
	}
	internal class NetworkingMethods
	{
		[HarmonyPatch(typeof(GameNetworkManager), "ResetGameValuesToDefault")]
		[HarmonyPostfix]
		private static void ResetGameValuesToDefaultPatch()
		{
			Script.Logger.LogInfo((object)"/Networking-ResetGameValuesToDefault/ Clearing all subscribtions and globalEnemyLists.");
			Networking.ClearSubscribtionsInDictionary();
			NaturalSelectionLib.globalEnemyLists.Clear();
		}

		[HarmonyPatch(typeof(RoundManager), "ResetEnemyVariables")]
		[HarmonyPostfix]
		private static void ResetEnemyVariablesPatch()
		{
			Script.Logger.LogInfo((object)"/Networking-ResetEnemyVariables/ Clearing all subscribtions and globalEnemyLists.");
			Networking.ClearSubscribtionsInDictionary();
			NaturalSelectionLib.globalEnemyLists.Clear();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		private static float nextUpdate = 0f;

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

		public static float updateListInterval = 1f;

		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 (KeyValuePair<Type, bool> 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(new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside)) && ((NetworkBehaviour)instance).IsOwner)
			{
				checkedTypes.Add(new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside), 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 && !((NetworkBehaviour)instance).IsOwner)
			{
				Script.Logger.LogDebug((object)"/RoundManager/ request was Denied. Not owner of the instance.");
			}
			else if (logUnspecified && logSpam)
			{
				Script.Logger.LogDebug((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(new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside)))
			{
				checkedTypes[new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside)] = list;
			}
			if (!NaturalSelectionLib.globalEnemyLists.ContainsKey(new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside)))
			{
				Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead(instance) + "global enemy list for this enemy does not exist! Creating a new one."));
				NaturalSelectionLib.UpdateListInsideDictionrary(new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside), checkedTypes[new KeyValuePair<Type, bool>(((object)instance).GetType(), instance.isOutside)]);
			}
		}
	}
}
namespace NaturalSelection.EnemyPatches
{
	internal class BeeValues
	{
		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 List<string> blacklist = Script.BoundingConfig.beeBlacklist.Value.ToUpper().Split(",").ToList();

		[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 (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetInsideOrOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), beeList[__instance].enemyTypes, blacklist, (EnemyAI)(object)__instance, inverseToggle: true, Script.BoundingConfig.IgnoreImmortalEnemies.Value));
			}
		}

		[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_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_0525: Unknown result type (might be due to invalid IL or missing references)
			//IL_0807: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0816: Unknown result type (might be due to invalid IL or missing references)
			//IL_081b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0820: Unknown result type (might be due to invalid IL or missing references)
			//IL_0859: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b29: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b57: Unknown result type (might be due to invalid IL or missing references)
			//IL_0948: Unknown result type (might be due to invalid IL or missing references)
			//IL_0958: Unknown result type (might be due to invalid IL or missing references)
			//IL_060b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Unknown result type (might be due to invalid IL or missing references)
			//IL_0980: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dd7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d95: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cd5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cda: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce1: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d8: Unknown result type (might be due to invalid IL or missing references)
			BeeValues beeValues = beeList[__instance];
			KeyValuePair<Type, bool> key = new KeyValuePair<Type, bool>(((object)__instance).GetType(), ((EnemyAI)__instance).isOutside);
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			case 0:
			{
				EnemyAI val4 = null;
				if (EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 360f, 16, 1f).Count > 0)
				{
					if (NaturalSelectionLib.globalEnemyLists[key].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[key].Remove((EnemyAI)(object)__instance);
					}
					val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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[key], 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[key].Remove((EnemyAI)(object)__instance);
						}
						val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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[key], 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 flag2 = false;
				Dictionary<EnemyAI, float> enemiesInLOS2 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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)
				{
					flag2 = 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 (!flag2 && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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 flag = false;
				Dictionary<EnemyAI, float> enemiesInLOS = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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)
				{
					flag = 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 (!flag && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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;
			}
			}
		}

		private static LNetworkVariable<float> NSSetOnFireChance(RedLocustBees instance)
		{
			string nWID = "NSSetOnFireChance" + ((NetworkBehaviour)instance).NetworkObjectId;
			return Networking.NSEnemyNetworkVariableFloat(nWID);
		}

		private static LNetworkVariable<float> NSSetOnFireMaxChance(RedLocustBees instance)
		{
			string nWID = "NSSetOnFireMaxChance" + ((NetworkBehaviour)instance).NetworkObjectId;
			return Networking.NSEnemyNetworkVariableFloat(nWID);
		}

		private static LNetworkEvent NetworkSetGiantOnFire(ForestGiantAI forestGiantAI)
		{
			string nWID = "NSSetGiantOnFire" + ((NetworkBehaviour)forestGiantAI).NetworkObjectId;
			return Networking.NSEnemyNetworkEvent(nWID);
		}

		public static void OnCustomEnemyCollision(RedLocustBees __instance, EnemyAI mainscript2)
		{
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			if (!beeList.ContainsKey(__instance))
			{
				return;
			}
			if ((beeList[__instance].timeSinceHittingEnemy > 1.7f && ((EnemyAI)__instance).currentBehaviourStateIndex > 0 && !mainscript2.isEnemyDead) || (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;
				}
				if (((NetworkBehaviour)__instance).IsOwner)
				{
					NSSetOnFireChance(__instance).Value = Random.Range(0f, 100f);
					if (((EnemyAI)__instance).currentBehaviourStateIndex != 2)
					{
						NSSetOnFireMaxChance(__instance).Value = Script.BoundingConfig.beesSetGiantsOnFireMinChance.Value;
					}
					else
					{
						NSSetOnFireMaxChance(__instance).Value = Script.BoundingConfig.beesSetGiantsOnFireMaxChance.Value;
					}
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: Giant hit. Chance to set on fire: " + NSSetOnFireMaxChance(__instance).Value + ", rolled " + (object)NSSetOnFireChance(__instance)));
				}
				else if (logBees)
				{
					Script.Logger.LogMessage((object)"Client not elligible to determine chance to set giant on fire");
				}
				if (NSSetOnFireChance(__instance).Value <= NSSetOnFireMaxChance(__instance).Value && ((NetworkBehaviour)__instance).IsOwner)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: SET GIANT ON FIRE! Random number: " + NSSetOnFireChance(__instance).Value));
					ForestGiantAI forestGiantAI = (ForestGiantAI)mainscript2;
					NetworkSetGiantOnFire(forestGiantAI).InvokeServer();
				}
			}
			else
			{
				beeList[__instance].timeSinceHittingEnemy += Time.deltaTime;
			}
		}
	}
	internal class BlobData
	{
		public float timeSinceHittingLocalMonster = 0f;

		public EnemyAI? closestEnemy = null;

		public bool playSound = false;
	}
	[HarmonyPatch(typeof(BlobAI))]
	public class BlobAIPatch
	{
		private static Dictionary<BlobAI, BlobData> slimeList = new Dictionary<BlobAI, BlobData>();

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

		private static List<string> blacklist = Script.BoundingConfig.blobBlacklist.Value.ToUpper().Split(",").ToList();

		private static LNetworkEvent BlobEatCorpseEvent(BlobAI instance)
		{
			string nWID = "NSSlimeEatEvent" + ((NetworkBehaviour)instance).NetworkObjectId;
			return Networking.NSEnemyNetworkEvent(nWID);
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(BlobAI __instance)
		{
			BlobAI __instance2 = __instance;
			if (!slimeList.ContainsKey(__instance2))
			{
				slimeList.Add(__instance2, new BlobData());
			}
			if (Script.BoundingConfig.blobAICantOpenDoors.Value)
			{
				((EnemyAI)__instance2).openDoorSpeedMultiplier = 0f;
			}
			BlobEatCorpseEvent(__instance2).OnClientReceived += EventReceived;
			void EventReceived()
			{
				slimeList[__instance2].playSound = true;
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool DoAIIntervalPrefixPatch(BlobAI __instance)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			BlobData blobData = slimeList[__instance];
			if (Script.BoundingConfig.blobPathfind.Value && (((Object)(object)((EnemyAI)__instance).GetClosestPlayer(false, false, false) != (Object)null && (!((EnemyAI)__instance).PlayerIsTargetable(((EnemyAI)__instance).GetClosestPlayer(false, false, false), false, false) || ((Object)(object)blobData.closestEnemy != (Object)null && Vector3.Distance(((Component)blobData.closestEnemy).transform.position, ((Component)__instance).transform.position) < Vector3.Distance(((Component)((EnemyAI)__instance).GetClosestPlayer(false, false, false)).transform.position, ((Component)__instance).transform.position)))) || (Object)(object)((EnemyAI)__instance).GetClosestPlayer(false, false, false) == (Object)null))
			{
				if (((EnemyAI)__instance).moveTowardsDestination)
				{
					((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
				}
				((EnemyAI)__instance).SyncPositionToClients();
				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];
			KeyValuePair<Type, bool> key = new KeyValuePair<Type, bool>(((object)__instance).GetType(), ((EnemyAI)__instance).isOutside);
			blobData.timeSinceHittingLocalMonster += Time.deltaTime;
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetInsideOrOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance, FilterThemselves: true, 1), (EnemyAI)(object)__instance), null, blacklist, (EnemyAI)(object)__instance));
			}
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				blobData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[key], blobData.closestEnemy, (EnemyAI)(object)__instance, Script.BoundingConfig.blobPathfindToCorpses.Value);
			}
			if (blobData.playSound)
			{
				Script.Logger.LogMessage((object)("Playing sound. NetworkObjectID: " + ((NetworkBehaviour)__instance).NetworkObjectId));
				((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.killPlayerSFX);
				blobData.playSound = false;
			}
		}

		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 && Script.BoundingConfig.blobConsumesCorpses.Value)
			{
				if (((NetworkBehaviour)__instance).IsOwner && mainscript2.thisNetworkObject.IsSpawned)
				{
					BlobEatCorpseEvent(__instance).InvokeClients();
					Script.Logger.LogMessage((object)"Send event");
					mainscript2.thisNetworkObject.Despawn(true);
				}
			}
			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: false, 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 enableBees = Script.BoundingConfig.enableRedBees.Value;

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

		private static bool triggerFlag = Script.BoundingConfig.debugTriggerFlags.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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			if (logUnspecified && debugSpam && triggerFlag)
			{
				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 && triggerFlag)
				{
					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 && triggerFlag)
					{
						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 && enableBees)
			{
				BeeAIPatch.OnCustomEnemyCollision((RedLocustBees)mainscript, mainscript2);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAICollisionDetect), "OnTriggerStay")]
	public class AICollisionDetectPatch
	{
		private static bool Prefix(Collider other, EnemyAICollisionDetect __instance)
		{
			if ((Object)(object)other == (Object)null)
			{
				Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead(__instance.mainScript) + "Collider is null! Using original function..."));
				return true;
			}
			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> GetInsideOrOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetInsideOrOutsideEnemyList!");
			}
			return NaturalSelectionLib.GetInsideOrOutsideEnemyList(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, List<string>? blacklist, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library filterEnemyList!");
			}
			return NaturalSelectionLib.FilterEnemyList(importEnemyList, targetTypes, blacklist, 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;
		}
	}
	[HarmonyPatch]
	public class ReversePatchAI
	{
		public static void ReverseUpdate(EnemyAI instance)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: 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_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			if (instance.enemyType.isDaytimeEnemy && !instance.daytimeEnemyLeaving)
			{
				instance.CheckTimeOfDayToLeave();
			}
			if (instance.stunnedIndefinitely <= 0)
			{
				if (instance.stunNormalizedTimer >= 0f)
				{
					instance.stunNormalizedTimer -= Time.deltaTime / instance.enemyType.stunTimeMultiplier;
				}
				else
				{
					instance.stunnedByPlayer = null;
					if (instance.postStunInvincibilityTimer >= 0f)
					{
						instance.postStunInvincibilityTimer -= Time.deltaTime * 5f;
					}
				}
			}
			if (!instance.ventAnimationFinished && instance.timeSinceSpawn < instance.exitVentAnimationTime + 0.005f * (float)RoundManager.Instance.numberOfEnemiesInScene)
			{
				instance.timeSinceSpawn += Time.deltaTime;
				if (!((NetworkBehaviour)instance).IsOwner)
				{
					_ = instance.serverPosition;
					if (instance.serverPosition != Vector3.zero)
					{
						((Component)instance).transform.position = instance.serverPosition;
						((Component)instance).transform.eulerAngles = new Vector3(((Component)instance).transform.eulerAngles.x, instance.targetYRotation, ((Component)instance).transform.eulerAngles.z);
					}
				}
				else if (instance.updateDestinationInterval >= 0f)
				{
					instance.updateDestinationInterval -= Time.deltaTime;
				}
				else
				{
					instance.SyncPositionToClients();
					instance.updateDestinationInterval = 0.1f;
				}
				return;
			}
			if (!instance.inSpecialAnimation && !instance.ventAnimationFinished)
			{
				instance.ventAnimationFinished = true;
				if ((Object)(object)instance.creatureAnimator != (Object)null)
				{
					instance.creatureAnimator.SetBool("inSpawningAnimation", false);
				}
			}
			if (!((NetworkBehaviour)instance).IsOwner)
			{
				if (instance.currentSearch.inProgress)
				{
					instance.StopSearch(instance.currentSearch, true);
				}
				instance.SetClientCalculatingAI(false);
				if (!instance.inSpecialAnimation)
				{
					if (RoundManager.Instance.currentDungeonType == 4 && Vector3.Distance(((Component)instance).transform.position, RoundManager.Instance.currentMineshaftElevator.elevatorInsidePoint.position) < 1f)
					{
						instance.serverPosition += RoundManager.Instance.currentMineshaftElevator.elevatorInsidePoint.position - RoundManager.Instance.currentMineshaftElevator.previousElevatorPosition;
					}
					((Component)instance).transform.position = Vector3.SmoothDamp(((Component)instance).transform.position, instance.serverPosition, ref instance.tempVelocity, instance.syncMovementSpeed);
					((Component)instance).transform.eulerAngles = new Vector3(((Component)instance).transform.eulerAngles.x, Mathf.LerpAngle(((Component)instance).transform.eulerAngles.y, instance.targetYRotation, 15f * Time.deltaTime), ((Component)instance).transform.eulerAngles.z);
				}
				instance.timeSinceSpawn += Time.deltaTime;
				return;
			}
			if (instance.isEnemyDead)
			{
				instance.SetClientCalculatingAI(false);
				return;
			}
			if (!instance.inSpecialAnimation)
			{
				instance.SetClientCalculatingAI(true);
			}
			if (instance.movingTowardsTargetPlayer && (Object)(object)instance.targetPlayer != (Object)null)
			{
				if (instance.setDestinationToPlayerInterval <= 0f)
				{
					instance.setDestinationToPlayerInterval = 0.25f;
					instance.destination = RoundManager.Instance.GetNavMeshPosition(((Component)instance.targetPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1);
				}
				else
				{
					instance.destination = new Vector3(((Component)instance.targetPlayer).transform.position.x, instance.destination.y, ((Component)instance.targetPlayer).transform.position.z);
					instance.setDestinationToPlayerInterval -= Time.deltaTime;
				}
				if (instance.addPlayerVelocityToDestination > 0f)
				{
					if ((Object)(object)instance.targetPlayer == (Object)(object)GameNetworkManager.Instance.localPlayerController)
					{
						instance.destination += Vector3.Normalize(instance.targetPlayer.thisController.velocity * 100f) * instance.addPlayerVelocityToDestination;
					}
					else if (instance.targetPlayer.timeSincePlayerMoving < 0.25f)
					{
						instance.destination += Vector3.Normalize((instance.targetPlayer.serverPlayerPosition - instance.targetPlayer.oldPlayerPosition) * 100f) * instance.addPlayerVelocityToDestination;
					}
				}
			}
			if (instance.inSpecialAnimation)
			{
				return;
			}
			if (instance.updateDestinationInterval >= 0f)
			{
				instance.updateDestinationInterval -= Time.deltaTime;
			}
			else
			{
				instance.DoAIInterval();
				instance.updateDestinationInterval = instance.AIIntervalTime + Random.Range(-0.015f, 0.015f);
			}
			if (Mathf.Abs(instance.previousYRotation - ((Component)instance).transform.eulerAngles.y) > 6f)
			{
				instance.previousYRotation = ((Component)instance).transform.eulerAngles.y;
				instance.targetYRotation = instance.previousYRotation;
				if (((NetworkBehaviour)instance).IsServer)
				{
					instance.UpdateEnemyRotationClientRpc((short)instance.previousYRotation);
				}
				else
				{
					instance.UpdateEnemyRotationServerRpc((short)instance.previousYRotation);
				}
			}
		}
	}
	internal class GiantData
	{
		public bool logGiant = Script.BoundingConfig.debugGiants.Value;

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

		public int extinguished = 0;

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

		private static LNetworkEvent NetworkSetGiantOnFire(ForestGiantAI forestGiantAI)
		{
			string nWID = "NSSetGiantOnFire" + ((NetworkBehaviour)forestGiantAI).NetworkObjectId;
			return Networking.NSEnemyNetworkEvent(nWID);
		}

		private static LNetworkEvent NetworkExtinguish(ForestGiantAI forestGiantAI)
		{
			string nWID = "NSExtinguish" + ((NetworkBehaviour)forestGiantAI).NetworkObjectId;
			return Networking.NSEnemyNetworkEvent(nWID);
		}

		private static LNetworkVariable<float> NetworkOwnerPostfixResult(ForestGiantAI forestGiantAI)
		{
			string nWID = "NSOwnerrealtimeSinceStartup" + ((NetworkBehaviour)forestGiantAI).NetworkObjectId;
			return Networking.NSEnemyNetworkVariableFloat(nWID);
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void startPostfix(ForestGiantAI __instance)
		{
			ForestGiantAI __instance2 = __instance;
			if (!giantDictionary.ContainsKey(__instance2))
			{
				giantDictionary.Add(__instance2, new GiantData());
			}
			NetworkSetGiantOnFire(__instance2).OnServerReceived += UpdateSetGiantOnFireServer;
			NetworkExtinguish(__instance2).OnClientReceived += ExtuinguishGiant;
			void ExtuinguishGiant()
			{
				((EnemyAI)__instance2).SwitchToBehaviourState(0);
				__instance2.burningParticlesContainer.SetActive(false);
				__instance2.giantBurningAudio.Stop();
				((EnemyAI)__instance2).creatureAnimator.SetBool("burning", false);
				giantDictionary[__instance2].extinguished = 1;
			}
			void UpdateSetGiantOnFireServer(ulong client)
			{
				if (((NetworkBehaviour)__instance2).IsOwner)
				{
					__instance2.timeAtStartOfBurning = Time.realtimeSinceStartup;
					((EnemyAI)__instance2).SwitchToBehaviourState(2);
					Script.Logger.LogInfo((object)"Received UpdateSetGiantOnFire event");
				}
			}
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void KillEnemyPatchPostfix(ForestGiantAI __instance)
		{
			GiantData giantData = giantDictionary[__instance];
			if (giantData.extinguished != 1 && ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				__instance.burningParticlesContainer.SetActive(true);
			}
			if (giantData.logGiant)
			{
				Script.Logger.LogInfo((object)EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance));
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefix(ForestGiantAI __instance)
		{
			GiantData giantData = giantDictionary[__instance];
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning > 9.5f && ((EnemyAI)__instance).enemyHP > 20 && giantData.extinguished == 0 && !((EnemyAI)__instance).isEnemyDead && ((NetworkBehaviour)__instance).IsOwner)
			{
				int num = Random.Range(0, 100);
				if (num <= Script.BoundingConfig.giantExtinguishChance.Value)
				{
					NetworkExtinguish(__instance).InvokeClients();
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " successfully extinguished itself. Skipping Update. Rolled " + num));
				}
				else
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " failed to extinguish itself. rolled " + num));
					giantData.extinguished = 2;
				}
			}
			if (giantData.extinguished == 1)
			{
				((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - 20;
				giantData.extinguished = 2;
				return false;
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(ForestGiantAI __instance)
		{
			GiantData giantData = giantDictionary[__instance];
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				NetworkOwnerPostfixResult(__instance).Value = Time.realtimeSinceStartup - __instance.timeAtStartOfBurning;
			}
			if (((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).currentBehaviourStateIndex == 2 && NetworkOwnerPostfixResult(__instance).Value < 20f)
			{
				if (((NetworkBehaviour)__instance).IsOwner)
				{
					NetworkOwnerPostfixResult(__instance).Value = Time.realtimeSinceStartup - __instance.timeAtStartOfBurning;
				}
				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 && NetworkOwnerPostfixResult(__instance).Value > 26f && __instance.burningParticlesContainer.activeSelf)
			{
				__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>();

		public bool limitSpeed = false;

		public float limitedSpeed = 0f;
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal class HoarderBugPatch
	{
		private static Dictionary<HoarderBugAI, HoarderBugValues> hoarderBugList = new Dictionary<HoarderBugAI, HoarderBugValues>();

		public static HoarderBugValues ReturnEnemyValuesFromDictionary(HoarderBugAI hoarderBug)
		{
			return hoarderBugList[hoarderBug];
		}

		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");
			if (playHitSFX)
			{
				WalkieTalkie.TransmitOneShotAudio(((EnemyAI)__instance).creatureVoice, ((EnemyAI)__instance).enemyType.hitBodySFX, 1f);
				((EnemyAI)__instance).creatureVoice.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
			}
			if ((Object)(object)((EnemyAI)__instance).creatureVoice != (Object)null)
			{
				((EnemyAI)__instance).creatureVoice.PlayOneShot(((EnemyAI)__instance).enemyType.hitEnemyVoiceSFX);
			}
			RoundManager.PlayRandomClip(((EnemyAI)__instance).creatureVoice, __instance.angryScreechSFX, true, 1f, 0, 1000);
			((EnemyAI)__instance).SwitchToBehaviourState(1);
			if (((EnemyAI)__instance).enemyHP <= 0)
			{
				((EnemyAI)__instance).KillEnemyOnOwnerClient(false);
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(HoarderBugAI __instance)
		{
			if (!hoarderBugList.ContainsKey(__instance))
			{
				hoarderBugList.Add(__instance, new HoarderBugValues());
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(HoarderBugAI __instance)
		{
			HoarderBugValues hoarderBugValues = hoarderBugList[__instance];
			if (hoarderBugValues.limitSpeed)
			{
				((EnemyAI)__instance).agent.speed = hoarderBugValues.limitedSpeed;
			}
		}
	}
	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 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			NutcrackerData nutcrackerData = NutcrackerData[__instance];
			enemyList = EnemyAIPatch.GetInsideOrOutsideEnemyList(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_0088: Unknown result type (might be due to invalid IL or missing references)
			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 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)
		{
			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(typeof(SandSpiderAI))]
	internal class SandSpiderAIPatch
	{
		private static float refreshCDtimeSpider = 1f;

		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_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: 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_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_07af: 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_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0763: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
			SpiderData spiderData = spiderList[__instance];
			KeyValuePair<Type, bool> key = new KeyValuePair<Type, bool>(((object)__instance).GetType(), ((EnemyAI)__instance).isOutside);
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.GetInsideOrOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance));
			}
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				spiderData.enemiesInLOSDictionary = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[key], 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)
			{
				ReversePatchAI.ReverseUpdate((EnemyAI)(object)__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)
	

DLLs/fandovec03.NaturalSelectionLib.dll

Decompiled 2 days 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 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")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Personal Library with functions for getting, sorting and filtering enemies")]
[assembly: AssemblyFileVersion("0.6.2.0")]
[assembly: AssemblyInformationalVersion("0.6.2+a7372022355d2d1bbca750870ae9a07d7de3ff8a")]
[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.6.2.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.6.2")]
	public class NaturalSelectionLib : BaseUnityPlugin
	{
		public static bool debugUnspecified = false;

		public static bool debugSpam = false;

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

		public static Dictionary<KeyValuePair<Type, bool>, List<EnemyAI>> globalEnemyLists = new Dictionary<KeyValuePair<Type, bool>, List<EnemyAI>>();

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

		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) + ", local ID: " + ((__instance != null) ? new int?(((Object)__instance).GetInstanceID()) : null) + ", ID: " + ((__instance != null) ? new ulong?(((NetworkBehaviour)__instance).NetworkObjectId) : null) + ":";
		}

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

		public static List<EnemyAI> GetInsideOrOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			List<EnemyAI> list = new List<EnemyAI>(importEnemyList);
			foreach (EnemyAI importEnemy in importEnemyList)
			{
				if (((importEnemy.isOutside && !instance.isOutside) || (!importEnemy.isOutside && instance.isOutside)) && (Object)(object)importEnemy != (Object)(object)instance)
				{
					list.Remove(importEnemy);
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogDebug((object)(DebugStringHead(instance) + " Removed " + 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, List<string>? blacklist, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true)
		{
			List<EnemyAI> list = new List<EnemyAI>(importEnemyList);
			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! Removing..."));
					}
					list.Remove(importEnemyList[i]);
				}
				if (blacklist != null && blacklist.Count > 0 && (Object)(object)importEnemyList[i] != (Object)null && (blacklist.Contains(importEnemyList[i].enemyType.enemyName.ToUpper()) || blacklist.Contains(((Component)importEnemyList[i]).GetComponentInChildren<ScanNodeProperties>().headerText.ToUpper())))
				{
					if (debugUnspecified && blacklist.Contains(importEnemyList[i].enemyType.enemyName.ToUpper()))
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "Found blacklisted enemy in importEnemyList by EnemyType name! Removing..."));
					}
					if (debugUnspecified && blacklist.Contains(((Component)importEnemyList[i]).GetComponentInChildren<ScanNodeProperties>().headerText.ToUpper()))
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "Found blacklisted enemy in importEnemyList by scan node headertext! Removing..."));
					}
					list.Remove(importEnemyList[i]);
				}
				if (targetTypes != null && targetTypes.Count > 0 && ((!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));
					}
					continue;
				}
				if (targetTypes != null && targetTypes.Count > 0)
				{
					if (debugUnspecified)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "Caught and filtered out Enemy of type " + ((object)importEnemyList[i]).GetType()));
					}
					list.Remove(importEnemyList[i]);
				}
				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()));
					}
					list.Remove(importEnemyList[i]);
				}
				if (targetTypes == null || targetTypes.Count < 1)
				{
					if (debugUnspecified && targetTypes != null && targetTypes.Count < 1)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "TargetTypes is empty.  Skipping enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " by default"));
					}
					if (debugUnspecified && targetTypes == null)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "TargetTypes is NULL.  Skipping enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			List<EnemyAI> list = new List<EnemyAI>(importEnemyList);
			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);
			}
			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)
						{
							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.6.2";
	}
}