Decompiled source of Natural selection v0.2.2

DLLs/fandovec03.NaturalSelection.dll

Decompiled 4 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("0.2.2.0")]
[assembly: AssemblyInformationalVersion("0.2.2+2df52fa8376c348612aa72ef4ae0ed031928370f")]
[assembly: AssemblyProduct("NaturalSelection")]
[assembly: AssemblyTitle("fandovec03.NaturalSelection")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.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 NaturalSelection
{
	[BepInPlugin("fandovec03.NaturalSelection", "NaturalSelection", "0.2.2")]
	[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);
			isExperimental = false;
			Patch();
			Logger.LogInfo((object)"fandovec03.NaturalSelection v0.2.2 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)
			{
				for (int i = 0; i < 100; i++)
				{
					Logger.LogError((object)("LOADING EXPERIMENTAL " + "NaturalSelection".ToUpper() + ", DOWNLOAD NATURAL SELECTION INSTEAD!"));
				}
			}
			Harmony.PatchAll(typeof(AICollisionDetectPatch));
			Harmony.PatchAll(typeof(EnemyAIPatch));
			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.0");
			}
			catch
			{
				Logger.LogError((object)"Failed to setup library!");
			}
			Harmony.PatchAll(typeof(RoundManagerPatch));
			if (BoundingConfig.loadSandworms.Value)
			{
				Harmony.PatchAll(typeof(SandWormAIPatch));
			}
			if (BoundingConfig.loadBlob.Value)
			{
				Harmony.PatchAll(typeof(BlobAIPatch));
			}
			if (BoundingConfig.loadHoardingBugs.Value)
			{
				Harmony.PatchAll(typeof(HoarderBugPatch));
			}
			if (BoundingConfig.LoadBees.Value)
			{
				Harmony.PatchAll(typeof(BeeAIPatch));
			}
			if (BoundingConfig.loadGiants.Value)
			{
				Harmony.PatchAll(typeof(ForestGiantPatch));
			}
			if (!stableToggle)
			{
				if (BoundingConfig.loadNutcrackers.Value)
				{
					Harmony.PatchAll(typeof(NutcrackerAIPatch));
				}
				if (BoundingConfig.loadSporeLizard.Value)
				{
					Harmony.PatchAll(typeof(PufferAIPatch));
				}
				if (BoundingConfig.loadSpiders.Value)
				{
					Harmony.PatchAll(typeof(SandSpiderAIPatch));
				}
				Logger.LogInfo((object)"Stable mode off. Loaded all patches.");
			}
			else
			{
				Logger.LogInfo((object)"Stable mode on. Excluded unstable and WIP patches from loading.");
			}
			Logger.LogInfo((object)"Finished patching NaturalSelection !");
		}

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

		public const string PLUGIN_NAME = "NaturalSelection";

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

		public readonly ConfigEntry<float> delay;

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

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

		public readonly ConfigEntry<bool> loadSpiders;

		public readonly ConfigEntry<bool> loadSandworms;

		public readonly ConfigEntry<bool> loadGiants;

		public readonly ConfigEntry<bool> loadHoardingBugs;

		public readonly ConfigEntry<bool> loadBlob;

		public readonly ConfigEntry<bool> LoadBees;

		public readonly ConfigEntry<bool> loadSporeLizard;

		public readonly ConfigEntry<bool> debugBool;

		public readonly ConfigEntry<bool> spammyLogs;

		public readonly ConfigEntry<bool> debugTriggerFlags;

		public readonly ConfigEntry<bool> 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;
			delayScriptsOnSpawn = cfg.Bind<bool>("Experimental Fixes", "Delay enemy scripts on spawn", false, "Delay enemy scripts from taking effect on enemy spawns. Might fix invisible bees");
			delay = cfg.Bind<float>("Experimental Fixes", "Delay", 0.2f, "Set the length of the delay");
			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, "Mod applies changes Bunker Spider. DEV ONLY");
			enableSlime = cfg.Bind<bool>("Entity settings", "Enable slime", true, "Mod applies changes Hygrodere. Slime now damages every entity it passes by.");
			enableLeviathan = cfg.Bind<bool>("Entity settings", "Enable leviathan", true, "Mod applies changes Earth leviathan. Leviathan now targets other creatures aswell.");
			enableSporeLizard = cfg.Bind<bool>("WIP", "Enable SporeLizard", false, "Mod applies changes Spore lizard. It is now mortal!");
			enableRedBees = cfg.Bind<bool>("Entity settings", "Enable Red bees (Circuit bees)", true, "Mod applies changes red bees. They now defend nest from other mobs and kill everything in rampage!");
			enableNutcrackers = cfg.Bind<bool>("WIP", "Enable Nutcrackers", false, "Mod applies changes to nutcrackers. DEV ONLY");
			giantExtinguishChance = cfg.Bind<int>("Entity settings", "(Giant) Extinguish chance", 33, "[Accepts int values between 0 and 100] Chance of giants extinguishing themselves.");
			beesSetGiantsOnFireMinChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants min chace", 1.5f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit");
			beesSetGiantsOnFireMaxChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants max chace", 8f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit");
			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]");
			loadSpiders = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spider patches", true, "Load the spider patches. Do not touch.");
			loadBlob = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load slime patches", true, "Load the slime patches. Do not touch.");
			loadSandworms = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load leviathan patches", true, "Load the leviathan patches. Do not touch.");
			loadGiants = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load giant patches", true, "Load the giant patches. Do not touch.");
			LoadBees = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load circuit bees patches", true, "Load bees patches. Do not touch.");
			loadNutcrackers = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load nutcracker patches", true, "Load the nutcracker patches. Do not touch.");
			loadHoardingBugs = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load hoarding bugs patches", true, "Load the hoarding bug patches. Do not touch.");
			loadSporeLizard = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spore lizards patches", true, "Load the spore lizard patches. Do not touch.");
			debugBool = cfg.Bind<bool>("Debug", "Debug mode", false, "Enables debug mode for more debug logs.");
			spammyLogs = cfg.Bind<bool>("Debug", "Spammy logs", false, "Enables spammy logs for extra logs.");
			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 in dictionary.");
			Networking.ClearSubscribtionsInDictionary();
		}

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

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

		public static float updateListInterval = 1f;

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

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

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

		public static bool RequestUpdate(EnemyAI instance)
		{
			if (!checkedTypes.ContainsKey(((object)instance).GetType()) && ((NetworkBehaviour)instance).IsOwner)
			{
				checkedTypes.Add(((object)instance).GetType(), new List<EnemyAI>());
				if (logUnspecified && logSpam)
				{
					Script.Logger.LogMessage((object)("/RoundManager/ request was Accepted. Requested by " + EnemyAIPatch.DebugStringHead(instance) + " at " + Time.realtimeSinceStartup));
				}
				return true;
			}
			if (logUnspecified && logSpam && !((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(((object)instance).GetType()))
			{
				checkedTypes[((object)instance).GetType()] = list;
			}
			if (!NaturalSelectionLib.globalEnemyLists.ContainsKey(((object)instance).GetType()))
			{
				Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead(instance) + "global enemy list for this enemy does not exist! Creating a new one."));
				NaturalSelectionLib.UpdateListInsideDictionrary(((object)instance).GetType(), checkedTypes[((object)instance).GetType()]);
			}
		}
	}
}
namespace NaturalSelection.EnemyPatches
{
	internal class BeeValues
	{
		public bool start = Script.BoundingConfig.delayScriptsOnSpawn.Value;

		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public Vector3 lastKnownEnemyPosition = Vector3.zero;

		public int customBehaviorStateIndex = 0;

		public float timeSinceHittingEnemy = 0f;

		public float LostLOSOfEnemy = 0f;

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

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

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

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

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

		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 (beeValues.delayTimer > 0f)
			{
				beeValues.delayTimer -= Time.deltaTime;
				return;
			}
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), beeList[__instance].enemyTypes, blacklist, (EnemyAI)(object)__instance, inverseToggle: true, Script.BoundingConfig.IgnoreImmortalEnemies.Value));
			}
			if (((NetworkBehaviour)__instance).IsOwner && NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Contains((EnemyAI)(object)__instance))
			{
				if (logBees && debugSpam)
				{
					Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList! Removing..."));
				}
				NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance);
			}
		}

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

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

		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];
			blobData.timeSinceHittingLocalMonster += Time.deltaTime;
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance, FilterThemselves: true, 1), (EnemyAI)(object)__instance), null, blacklist, (EnemyAI)(object)__instance));
			}
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				blobData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 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 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_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: 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)
			{
				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> GetOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetOutsideEnemyList!");
			}
			return NaturalSelectionLib.GetOutsideEnemyList(importEnemyList, instance);
		}

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

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

		public static List<EnemyAI> FilterEnemyList(List<EnemyAI> importEnemyList, List<Type>? targetTypes, 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>();
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal class HoarderBugPatch
	{
		private static Dictionary<HoarderBugAI, HoarderBugValues> hoarderBugList = new Dictionary<HoarderBugAI, HoarderBugValues>();

		public static void CustomOnHit(int force, EnemyAI enemyWhoHit, bool playHitSFX, HoarderBugAI __instance)
		{
			((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - force;
			Script.Logger.LogDebug((object)"Hoarderbug CustomHit Triggered");
			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);
			}
		}
	}
	internal class NutcrackerData
	{
		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public bool SeeMovingEnemy = false;

		public Vector3 lastSeenEnemyPosition = Vector3.zero;

		public float TimeSinceSeeingMonster = 0f;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public EnemyAI? targetEnemy = null;

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

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

		public float LookAtEnemyTimer = 0f;

		public Dictionary<EnemyAI, float> enemiesInLOSDictionary = new Dictionary<EnemyAI, float>();
	}
	[HarmonyPatch(typeof(SandSpiderAI))]
	internal class SandSpiderAIPatch
	{
		private static float refreshCDtimeSpider = 1f;

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

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

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

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

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

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

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefixPatch(SandSpiderAI __instance)
		{
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0506: Unknown result type (might be due to invalid IL or missing references)
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_076a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f4: Unknown result type (might be due to invalid IL or missing references)
			if (!enableSpider)
			{
				return true;
			}
			SpiderData spiderData = spiderList[__instance];
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance));
			}
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				spiderData.enemiesInLOSDictionary = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 80f, 15, 2f);
			}
			if (spiderData.enemiesInLOSDictionary.Count > 0)
			{
				foreach (KeyValuePair<EnemyAI, float> item in spiderData.enemiesInLOSDictionary)
				{
					if (item.Key.isEnemyDead)
					{
						if (debugSpider)
						{
							Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is Dead! Checking deadEnemyBodies list and skipping..."));
						}
						if (!spiderData.deadEnemyBodies.Contains(item.Key))
						{
							spiderData.deadEnemyBodies.Add(item.Key);
							if (debugSpider)
							{
								Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " added to deadEnemyBodies list"));
							}
						}
					}
					else if (spiderData.knownEnemy.Contains(item.Key))
					{
						if (debugSpider && debugSpam)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is already in knownEnemyList"));
						}
					}
					else
					{
						if (debugSpider)
						{
							Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Adding " + ((object)item.Key)?.ToString() + " to knownEnemyList"));
						}
						spiderData.knownEnemy.Add(item.Key);
					}
				}
				for (int i = 0; i < spiderData.knownEnemy.Count; i++)
				{
					if (spiderData.knownEnemy[i].isEnemyDead)
					{
						if (debugSpider)
						{
							Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Removed " + ((object)spiderData.knownEnemy[i])?.ToString() + " from knownEnemyList"));
						}
						spiderData.knownEnemy.Remove(spiderData.knownEnemy[i]);
					}
				}
			}
			__instance.SyncMeshContainerPositionToClients();
			__instance.CalculateMeshMovement();
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			case 0:
				spiderData.closestEnemy = EnemyAIPatch.FindClosestEnemy(spiderData.knownEnemy, spiderData.closestEnemy, (EnemyAI)(object)__instance);
				if ((Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye) && !spiderData.closestEnemy.isEnemyDead)
				{
					spiderData.targetEnemy = spiderData.closestEnemy;
					if (debugSpider)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set " + ((object)spiderData.closestEnemy)?.ToString() + " as TargetEnemy"));
					}
					((EnemyAI)__instance).SwitchToBehaviourState(2);
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set state to " + ((EnemyAI)__instance).currentBehaviourStateIndex));
					}
					__instance.chaseTimer = 12.5f;
					__instance.watchFromDistance = Vector3.Distance(((Component)__instance.meshContainer).transform.position, ((Component)spiderData.closestEnemy).transform.position) > 8f;
				}
				break;
			case 2:
				if ((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null)
				{
					break;
				}
				if ((Object)(object)spiderData.targetEnemy != (Object)(object)spiderData.closestEnemy && (Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye))
				{
					if (spiderData.targetEnemy is HoarderBugAI && !(spiderData.closestEnemy is HoarderBugAI) && Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position) * 1.2f < Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.closestEnemy).transform.position))
					{
						spiderData.targetEnemy = spiderData.closestEnemy;
					}
					else
					{
						spiderData.targetEnemy = spiderData.closestEnemy;
					}
				}
				if ((Object)(object)spiderData.targetEnemy == (Object)null)
				{
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-0/ Stopping chasing: " + (object)spiderData.targetEnemy));
					}
					spiderData.targetEnemy = null;
					__instance.StopChasing(false);
					break;
				}
				if (__instance.onWall)
				{
					((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false);
					((EnemyAI)__instance).agent.speed = 4.25f;
					__instance.spiderSpeed = 4.25f;
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2/ onWall"));
					}
					break;
				}
				if (__instance.watchFromDistance && (Object)(object)((EnemyAI)__instance).GetClosestPlayer(true, false, false) != (Object)null && Vector3.Distance(__instance.meshContainerPosition, ((Component)((EnemyAI)__instance).GetClosestPlayer(true, false, false)).transform.position) > Vector3.Distance(__instance.meshContainerPosition, ((Component)spiderData.targetEnemy).transform.position))
				{
					if (spiderData.LookAtEnemyTimer <= 0f)
					{
						spiderData.LookAtEnemyTimer = 3f;
						((EnemyAI)__instance).movingTowardsTargetPlayer = false;
						__instance.overrideSpiderLookRotation = true;
						Vector3 position = ((Component)spiderData.targetEnemy).transform.position;
						__instance.SetSpiderLookAtPosition(position);
					}
					else
					{
						spiderData.LookAtEnemyTimer -= Time.deltaTime;
					}
					__instance.spiderSpeed = 0f;
					((EnemyAI)__instance).agent.speed = 0f;
					if (Physics.Linecast(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
					{
						if (debugSpider)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-1/ Stopping chasing: " + (object)spiderData.targetEnemy));
						}
						spiderData.targetEnemy = null;
						__instance.StopChasing(false);
					}
					else if (Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) < 5f || ((EnemyAI)__instance).stunNormalizedTimer > 0f)
					{
						__instance.watchFromDistance = false;
					}
					break;
				}
				((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false);
				if ((Object)(object)spiderData.targetEnemy == (Object)null || spiderData.targetEnemy.isEnemyDead)
				{
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Stopping chasing: " + (object)spiderData.targetEnemy));
					}
					if ((Object)(object)spiderData.targetEnemy != (Object)null)
					{
						try
						{
							spiderData.deadEnemyBodies.Add(spiderData.targetEnemy);
							spiderData.knownEnemy.Remove(spiderData.targetEnemy);
							if (debugSpider)
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Moved dead enemy to separate list"));
							}
						}
						catch
						{
							Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Enemy does not exist!"));
						}
					}
					spiderData.targetEnemy = null;
					__instance.StopChasing(false);
				}
				else
				{
					if (!(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.homeNode.position) > 12f) || !(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) > 5f))
					{
						break;
					}
					__instance.chaseTimer -= Time.deltaTime;
					if (__instance.chaseTimer <= 0f)
					{
						if (debugSpider)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-3/ Stopping chasing: " + (object)spiderData.targetEnemy));
						}
						spiderData.targetEnemy = null;
						__instance.StopChasing(false);
					}
				}
				break;
			}
			if (refreshCDtimeSpider <= 0f)
			{
				if (debugSpider && debugSpam)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "watchFromDistance: " + __instance.watchFromDistance));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "overrideSpiderLookRotation: " + __instance.overrideSpiderLookRotation));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "moveTowardsDestination: " + ((EnemyAI)__instance).moveTowardsDestination));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "movingTowardsTargetPlayer: " + ((EnemyAI)__instance).movingTowardsTargetPlayer));
				}
				refreshCDtimeSpider = 0.5f;
			}
			else
			{
				refreshCDtimeSpider -= Time.deltaTime;
			}
			if ((Object)(object)spiderData.targetEnemy != (Object)null && !Object.op_Implicit((Object)(object)((EnemyAI)__instance).targetPlayer) && ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				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)
		{
			/