Rats/Snowlance.Rats.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Snowlance.Rats.NetcodePatcher;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("Snowlance.Rats")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+8450997c6aa80c2a41ba302e61301e2827332616")]
[assembly: AssemblyProduct("Rats")]
[assembly: AssemblyTitle("Snowlance.Rats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 Rats
{
	internal class TESTING : MonoBehaviour
	{
		private static ManualLogSource logger = Plugin.LoggerInstance;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(HUDManager), "PingScan_performed")]
		public static void PingScan_performedPostFix()
		{
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
		public static void SubmitChat_performedPrefix(HUDManager __instance)
		{
			string text = __instance.chatTextField.text;
			string[] array = text.Split(" ");
			switch (array[0])
			{
			case "/testing":
				RatAI.testing = bool.Parse(array[1]);
				break;
			case "/enemies":
			{
				foreach (SpawnableEnemyWithRarity enemy in GetEnemies())
				{
					logger.LogDebug((object)((Object)enemy.enemyType).name);
				}
				break;
			}
			case "/refresh":
				RoundManager.Instance.RefreshEnemiesList();
				HoarderBugAI.RefreshGrabbableObjectsInMapList();
				break;
			case "/levels":
			{
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val2 in levels)
				{
					logger.LogDebug((object)((Object)val2).name);
				}
				break;
			}
			case "/dungeon":
				logger.LogDebug((object)((Object)RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow).name);
				break;
			case "/dungeons":
			{
				IndoorMapType[] dungeonFlowTypes = RoundManager.Instance.dungeonFlowTypes;
				foreach (IndoorMapType val in dungeonFlowTypes)
				{
					logger.LogDebug((object)((Object)val.dungeonFlow).name);
				}
				break;
			}
			}
		}

		public static List<SpawnableEnemyWithRarity> GetEnemies()
		{
			logger.LogDebug((object)"Getting enemies");
			List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>();
			list = (from x in GameObject.Find("Terminal").GetComponentInChildren<Terminal>().moonsCatalogueList.SelectMany((SelectableLevel x) => x.Enemies.Concat(x.DaytimeEnemies).Concat(x.OutsideEnemies))
				where x != null && (Object)(object)x.enemyType != (Object)null && ((Object)x.enemyType).name != null
				select x).GroupBy((SpawnableEnemyWithRarity x) => ((Object)x.enemyType).name, (string k, IEnumerable<SpawnableEnemyWithRarity> v) => v.First()).ToList();
			logger.LogDebug((object)$"Enemy types: {list.Count}");
			return list;
		}

		public static void LogChat(string msg)
		{
			HUDManager.Instance.AddChatMessage(msg, "Server");
		}

		public static Vector3 GetSpeed()
		{
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: 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_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			float num = Plugin.localPlayer.movementSpeed / Plugin.localPlayer.carryWeight;
			if (Plugin.localPlayer.sinkingValue > 0.73f)
			{
				num = 0f;
			}
			else
			{
				if (Plugin.localPlayer.isCrouching)
				{
					num /= 1.5f;
				}
				else if (Plugin.localPlayer.criticallyInjured && !Plugin.localPlayer.isCrouching)
				{
					num *= Plugin.localPlayer.limpMultiplier;
				}
				if (Plugin.localPlayer.isSpeedCheating)
				{
					num *= 15f;
				}
				if (Plugin.localPlayer.movementHinderedPrev > 0)
				{
					num /= 2f * Plugin.localPlayer.hinderedMultiplier;
				}
				if (Plugin.localPlayer.drunkness > 0f)
				{
					num *= StartOfRound.Instance.drunknessSpeedEffect.Evaluate(Plugin.localPlayer.drunkness) / 5f + 1f;
				}
				if (!Plugin.localPlayer.isCrouching && Plugin.localPlayer.crouchMeter > 1.2f)
				{
					num *= 0.5f;
				}
				if (!Plugin.localPlayer.isCrouching)
				{
					float num2 = Vector3.Dot(Plugin.localPlayer.playerGroundNormal, Plugin.localPlayer.walkForce);
					if (num2 > 0.05f)
					{
						Plugin.localPlayer.slopeModifier = Mathf.MoveTowards(Plugin.localPlayer.slopeModifier, num2, (Plugin.localPlayer.slopeModifierSpeed + 0.45f) * Time.deltaTime);
					}
					else
					{
						Plugin.localPlayer.slopeModifier = Mathf.MoveTowards(Plugin.localPlayer.slopeModifier, num2, Plugin.localPlayer.slopeModifierSpeed / 2f * Time.deltaTime);
					}
					num = Mathf.Max(num * 0.8f, num + Plugin.localPlayer.slopeIntensity * Plugin.localPlayer.slopeModifier);
				}
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, 0f, 0f);
			int num3 = Physics.OverlapSphereNonAlloc(((Component)Plugin.localPlayer).transform.position, 0.65f, Plugin.localPlayer.nearByPlayers, StartOfRound.Instance.playersMask);
			for (int i = 0; i < num3; i++)
			{
				val += Vector3.Normalize((((Component)Plugin.localPlayer).transform.position - ((Component)Plugin.localPlayer.nearByPlayers[i]).transform.position) * 100f) * 1.2f;
			}
			int num4 = Physics.OverlapSphereNonAlloc(((Component)Plugin.localPlayer).transform.position, 1.25f, Plugin.localPlayer.nearByPlayers, 524288);
			for (int j = 0; j < num4; j++)
			{
				EnemyAICollisionDetect component = ((Component)Plugin.localPlayer.nearByPlayers[j]).gameObject.GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.mainScript != (Object)null && !component.mainScript.isEnemyDead && Vector3.Distance(((Component)Plugin.localPlayer).transform.position, ((Component)Plugin.localPlayer.nearByPlayers[j]).transform.position) < component.mainScript.enemyType.pushPlayerDistance)
				{
					val += Vector3.Normalize((((Component)Plugin.localPlayer).transform.position - ((Component)Plugin.localPlayer.nearByPlayers[j]).transform.position) * 100f) * component.mainScript.enemyType.pushPlayerForce;
				}
			}
			Vector3 val2 = Plugin.localPlayer.walkForce * num * Plugin.localPlayer.sprintMultiplier + new Vector3(0f, Plugin.localPlayer.fallValue, 0f) + val;
			return val2 + Plugin.localPlayer.externalForces;
		}
	}
	[BepInPlugin("Snowlance.Rats", "Rats", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin? PluginInstance;

		public static ManualLogSource? LoggerInstance;

		private readonly Harmony harmony = new Harmony("Snowlance.Rats");

		public static AssetBundle? ModAssets;

		public static ConfigEntry<bool>? configHideCodeOnTerminal;

		public static ConfigEntry<int>? configMinRatSpawnTime;

		public static ConfigEntry<int>? configMaxRatSpawnTime;

		public static ConfigEntry<int>? configFoodToSpawnRat;

		public static ConfigEntry<int>? configEnemyFoodPerHPPoint;

		public static ConfigEntry<int>? configMaxRats;

		public static ConfigEntry<float>? configDefenseRadius;

		public static ConfigEntry<float>? configTimeToIncreaseThreat;

		public static ConfigEntry<int>? configThreatToAttackPlayer;

		public static ConfigEntry<int>? configThreatToAttackEnemy;

		public static ConfigEntry<float>? configSwarmRadius;

		public static ConfigEntry<bool>? configCanVent;

		public static ConfigEntry<int>? configMaxDefenseRats;

		public static ConfigEntry<int>? configRatsNeededToAttack;

		public static ConfigEntry<float>? configDistanceNeededToLoseRats;

		public static ConfigEntry<int>? configEnemyHitsToDoDamage;

		public static ConfigEntry<int>? configPlayerFoodAmount;

		public static ConfigEntry<int>? configRatDamage;

		public static PlayerControllerB localPlayer => GameNetworkManager.Instance.localPlayerController;

		public static bool IsServerOrHost => NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost;

		public static PlayerControllerB PlayerFromId(ulong id)
		{
			return StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[id]];
		}

		private void Awake()
		{
			if ((Object)(object)PluginInstance == (Object)null)
			{
				PluginInstance = this;
			}
			LoggerInstance = ((BaseUnityPlugin)PluginInstance).Logger;
			harmony.PatchAll();
			InitializeNetworkBehaviours();
			configHideCodeOnTerminal = ((BaseUnityPlugin)this).Config.Bind<bool>("Nest", "Hide Code On Terminal", true, "If set to true, will make the code on the ship monitor for the nest be ??, requiring the player to find the nest physically to turn off its spawning.");
			configMinRatSpawnTime = ((BaseUnityPlugin)this).Config.Bind<int>("Nest", "Minimum Rat Spawn Time", 5, "The minimum time in seconds before a rat can spawn from the nest.");
			configMaxRatSpawnTime = ((BaseUnityPlugin)this).Config.Bind<int>("Nest", "Maximum Rat Spawn Time", 30, "The maximum time in seconds before a rat can spawn from the nest.");
			configFoodToSpawnRat = ((BaseUnityPlugin)this).Config.Bind<int>("Nest", "Food Required to Spawn Rat", 5, "The amount of food needed in the nest to spawn a new rat.");
			configEnemyFoodPerHPPoint = ((BaseUnityPlugin)this).Config.Bind<int>("Nest", "Food Per HP Point", 10, "How much food points one HP will equal for enemies. ex: if 10 thumper will give 40 food points.");
			configMaxRats = ((BaseUnityPlugin)this).Config.Bind<int>("Nest", "Maximum Rats", 40, "The maximum number of rats that can be on the map. Lowering this can improve performance.");
			configDefenseRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Rats", "Defense Radius", 5f, "The radius in which defense rats protect the nest.");
			configTimeToIncreaseThreat = ((BaseUnityPlugin)this).Config.Bind<float>("Rats", "Time to Increase Threat", 3f, "The time needed to add a threat point for a player when they are in line of sight of the rat.");
			configThreatToAttackPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Threat to Attack Player", 100, "The threat level at which rats begin attacking the player.");
			configThreatToAttackEnemy = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Threat to Attack Enemy", 50, "The threat level at which rats begin attacking enemy entities.");
			configSwarmRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Rats", "Swarm Radius", 10f, "The radius in which rats swarm around their target.");
			configCanVent = ((BaseUnityPlugin)this).Config.Bind<bool>("Rats", "Can Vent", true, "If set to true, allows rats to travel through vents. This can also increase performance if set to false.");
			configMaxDefenseRats = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Maximum Defense Rats", 10, "The maximum number of defense rats assigned to protect the nest.");
			configRatsNeededToAttack = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Rats Needed to Attack", 5, "The minimum number of rats required to start an attack.");
			configDistanceNeededToLoseRats = ((BaseUnityPlugin)this).Config.Bind<float>("Rats", "Distance Needed to Lose Rats", 25f, "The distance the player must be from rats to lose them.");
			configEnemyHitsToDoDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Enemy Hits to Do Damage", 10, "The amount of attacks needed to do 1 shovel hit of damage to an enemy. If 10, thumper will need to be attacked 40 times by a rat.");
			configPlayerFoodAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Player Food Amount", 30, "How much food points a player corpse gives when brought to the nest.");
			configRatDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Rats", "Rat Damage", 2, "The damage dealt by a rat when attacking.");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "rats_assets"));
			if ((Object)(object)ModAssets == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			LoggerInstance.LogDebug((object)("Got AssetBundle at: " + Path.Combine(directoryName, "rats_assets")));
			EnemyType val = ModAssets.LoadAsset<EnemyType>("Assets/ModAssets/RatEnemy.asset");
			if ((Object)(object)val == (Object)null)
			{
				LoggerInstance.LogError((object)"Error: Couldnt get Rat from assets");
				return;
			}
			LoggerInstance.LogDebug((object)"Got Rat prefab");
			TerminalNode val2 = ModAssets.LoadAsset<TerminalNode>("Assets/ModAssets/Bestiary/RatTN.asset");
			TerminalKeyword val3 = ModAssets.LoadAsset<TerminalKeyword>("Assets/ModAssets/Bestiary/RatTK.asset");
			LoggerInstance.LogDebug((object)"Registering enemy network prefab...");
			NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
			LoggerInstance.LogDebug((object)"Registering enemy...");
			Enemies.RegisterEnemy(val, (Dictionary<LevelTypes, int>)null, (Dictionary<string, int>)null, val2, val3);
			SpawnableMapObjectDef RatSpawn = ModAssets.LoadAsset<SpawnableMapObjectDef>("Assets/ModAssets/RatSpawn.asset");
			if ((Object)(object)RatSpawn == (Object)null)
			{
				LoggerInstance.LogError((object)"Error: Couldnt get RatSpawn from assets");
				return;
			}
			LoggerInstance.LogDebug((object)"Registering rat spawn network prefab...");
			NetworkPrefabs.RegisterNetworkPrefab(RatSpawn.spawnableMapObject.prefabToSpawn);
			LoggerInstance.LogDebug((object)"Registering RatSpawn");
			MapObjects.RegisterMapObject(RatSpawn, (LevelTypes)(-1), (Func<SelectableLevel, AnimationCurve>)((SelectableLevel level) => RatSpawn.spawnableMapObject.numberToSpawn));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Snowlance.Rats v1.0.1 has loaded!");
		}

		private static void InitializeNetworkBehaviours()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			LoggerInstance.LogDebug((object)"Finished initializing network behaviours");
		}
	}
	internal class RatAI : EnemyAI
	{
		public enum RatType
		{
			Unassigned,
			ScoutRat,
			DefenseRat
		}

		public enum State
		{
			Roaming,
			Tasking,
			Swarming,
			Attacking,
			Rallying
		}

		public static bool testing = false;

		public static List<RatAI> Rats = new List<RatAI>();

		public GameObject NestPrefab = null;

		public ScanNodeProperties ScanNode = null;

		public AudioClip[] SqueakSFX = null;

		public AudioClip[] AttackSFX = null;

		public AudioClip[] HitSFX = null;

		public AudioClip[] NibbleSFX = null;

		public Transform TurnCompass = null;

		public Transform RatMouth = null;

		private SewerGrate Nest;

		private DeadBodyInfo? heldBody;

		private float timeSinceAttackCheck;

		private EnemyAI? targetEnemy;

		private bool holdingFood;

		private Vector3 finalDestination;

		private float timeSinceCollision;

		private float timeSinceAddThreat;

		private float timeSincePounce;

		private float timeSinceSyncedAIInterval;

		private float timeSinceChangeDestination;

		private Coroutine? ratCoroutine = null;

		private bool sickRat;

		private bool rallyRat;

		private bool grabbingBody;

		private bool returningBodyToNest;

		private const float timeAgentStopped = 1f;

		private float defenseRadius = 5f;

		private float timeToIncreaseThreat = 3f;

		private int threatToAttackPlayer = 100;

		private int threatToAttackEnemy = 50;

		private float swarmRadius = 10f;

		private bool canVent = true;

		private int maxDefenseRats = 10;

		private int ratsNeededToAttack = 5;

		private float distanceToLoseRats = 25f;

		private int enemyHitsToDoDamage = 10;

		private int playerFoodAmount = 30;

		private int ratDamage = 2;

		private RatType RatTypeState = RatType.Unassigned;

		private EnemyVent? FromVent => GetClosestVentToPosition(((Component)this).transform.position);

		private EnemyVent? ToVent => GetClosestVentToPosition(finalDestination);

		private bool AtNest => ((Behaviour)base.agent).enabled && (Object)(object)Nest != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)Nest).transform.position) < 3f;

		public void SwitchToBehaviourStateCustom(State state)
		{
			if (base.currentBehaviourStateIndex == (int)state)
			{
				return;
			}
			StopRoutines();
			switch (state)
			{
			case State.Roaming:
				rallyRat = false;
				AssignRatType();
				break;
			case State.Tasking:
				rallyRat = false;
				AssignRatType();
				break;
			case State.Swarming:
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					ratCoroutine = ((MonoBehaviour)this).StartCoroutine(SwarmCoroutine(base.targetPlayer, swarmRadius));
				}
				else if ((Object)(object)targetEnemy != (Object)null)
				{
					ratCoroutine = ((MonoBehaviour)this).StartCoroutine(SwarmCoroutine(targetEnemy, swarmRadius));
				}
				else
				{
					Plugin.LoggerInstance.LogError((object)"No target to swarm");
				}
				break;
			case State.Attacking:
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					ratCoroutine = ((MonoBehaviour)this).StartCoroutine(SwarmCoroutine(base.targetPlayer, 2f));
				}
				else if ((Object)(object)targetEnemy != (Object)null)
				{
					ratCoroutine = ((MonoBehaviour)this).StartCoroutine(SwarmCoroutine(targetEnemy, 2f));
				}
				else
				{
					Plugin.LoggerInstance.LogError((object)"No target to attack");
				}
				break;
			case State.Rallying:
				base.agent.speed = 7f;
				rallyRat = true;
				break;
			}
			SwitchToBehaviourClientRpc((int)state);
		}

		public override void Start()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0068: 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)
			try
			{
				base.thisNetworkObject = ((Component)this).gameObject.GetComponentInChildren<NetworkObject>();
				base.thisEnemyIndex = RoundManager.Instance.numberOfEnemiesInScene;
				RoundManager instance = RoundManager.Instance;
				instance.numberOfEnemiesInScene++;
				base.allAINodes = GameObject.FindGameObjectsWithTag("AINode");
				RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)this);
				base.path1 = new NavMeshPath();
				base.serverPosition = ((Component)this).transform.position;
				base.ventAnimationFinished = true;
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"Error when initializing enemy variables for {((Object)((Component)this).gameObject).name} : {arg}");
			}
			defenseRadius = Plugin.configDefenseRadius.Value;
			timeToIncreaseThreat = Plugin.configTimeToIncreaseThreat.Value;
			threatToAttackPlayer = Plugin.configThreatToAttackPlayer.Value;
			threatToAttackEnemy = Plugin.configThreatToAttackEnemy.Value;
			swarmRadius = Plugin.configSwarmRadius.Value;
			canVent = Plugin.configCanVent.Value;
			maxDefenseRats = Plugin.configMaxDefenseRats.Value;
			ratsNeededToAttack = Plugin.configRatsNeededToAttack.Value;
			distanceToLoseRats = Plugin.configDistanceNeededToLoseRats.Value;
			enemyHitsToDoDamage = Plugin.configEnemyHitsToDoDamage.Value;
			playerFoodAmount = Plugin.configPlayerFoodAmount.Value;
			ratDamage = Plugin.configRatDamage.Value;
			logIfDebug("Rat spawned");
			HottestRat();
			if (Plugin.IsServerOrHost)
			{
				Rats.Add(this);
				SpawnNestIfNonExist();
				SwitchToBehaviourStateCustom(GetStartNest() ? State.Tasking : State.Roaming);
			}
		}

		public override void Update()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			if (base.stunNormalizedTimer >= 0f)
			{
				base.stunNormalizedTimer -= Time.deltaTime / base.enemyType.stunTimeMultiplier;
			}
			else
			{
				base.stunnedByPlayer = null;
			}
			if (!((NetworkBehaviour)this).IsOwner)
			{
				if (RoundManager.Instance.currentDungeonType == 4 && Vector3.Distance(((Component)this).transform.position, RoundManager.Instance.currentMineshaftElevator.elevatorInsidePoint.position) < 1f)
				{
					base.serverPosition += RoundManager.Instance.currentMineshaftElevator.elevatorInsidePoint.position - RoundManager.Instance.currentMineshaftElevator.previousElevatorPosition;
				}
				((Component)this).transform.position = Vector3.SmoothDamp(((Component)this).transform.position, base.serverPosition, ref base.tempVelocity, base.syncMovementSpeed);
				((Component)this).transform.eulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, Mathf.LerpAngle(((Component)this).transform.eulerAngles.y, base.targetYRotation, 15f * Time.deltaTime), ((Component)this).transform.eulerAngles.z);
			}
			else
			{
				if (!base.inSpecialAnimation)
				{
					((EnemyAI)this).SetClientCalculatingAI(true);
				}
				if (base.updateDestinationInterval >= 0f)
				{
					base.updateDestinationInterval -= Time.deltaTime;
				}
				else
				{
					((EnemyAI)this).DoAIInterval();
					base.updateDestinationInterval = base.AIIntervalTime + Random.Range(-0.015f, 0.015f);
				}
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
			}
			if (timeSinceSyncedAIInterval > base.AIIntervalTime)
			{
				timeSinceSyncedAIInterval = 0f;
				DoSyncedAIInterval();
			}
			timeSinceSyncedAIInterval += Time.deltaTime;
			timeSinceCollision += Time.deltaTime;
			timeSinceAddThreat += Time.deltaTime;
			timeSinceChangeDestination += Time.deltaTime;
			base.creatureAnimator.SetBool("stunned", base.stunNormalizedTimer > 0f);
			base.creatureAnimator.SetBool("runBackwards", returningBodyToNest && base.stunNormalizedTimer <= 0f);
			if (returningBodyToNest && (Object)(object)heldBody != (Object)null)
			{
				TurnCompass.LookAt(((Component)heldBody).transform.position);
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(new Vector3(0f, TurnCompass.eulerAngles.y, 0f)), 10f * Time.deltaTime);
			}
		}

		public void DoSyncedAIInterval()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.localPlayer.HasLineOfSightToPosition(((Component)this).transform.position, 45f, 60, -1f))
			{
				if (base.currentBehaviourStateIndex == 3)
				{
					Plugin.localPlayer.IncreaseFearLevelOverTime(0.05f, 1f);
				}
				else if (base.currentBehaviourStateIndex == 2)
				{
					Plugin.localPlayer.IncreaseFearLevelOverTime(0.2f, 1f);
				}
				else
				{
					Plugin.localPlayer.IncreaseFearLevelOverTime(0.02f, 1f);
				}
			}
		}

		public override void DoAIInterval()
		{
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead || base.stunNormalizedTimer > 0f)
			{
				return;
			}
			((EnemyAI)this).DoAIInterval();
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 5f;
				if (AtNest)
				{
					if (returningBodyToNest)
					{
						DropBody(deactivate: true);
						Nest.AddFood(playerFoodAmount);
					}
					SwitchToBehaviourStateCustom(State.Tasking);
					break;
				}
				if ((Object)(object)Nest == (Object)null)
				{
					TryGetAnyNest();
				}
				if ((Object)(object)Nest != (Object)null && SetDestinationToPosition(((Component)Nest).transform.position))
				{
					StopRoutines();
					SetStatus("Returning to nest");
					break;
				}
				if (returningBodyToNest)
				{
					DropBody();
				}
				Roam();
				break;
			case 1:
				base.agent.speed = 5f;
				if (grabbingBody)
				{
					GrabbableObject grabBodyObject = base.targetPlayer.deadBody.grabBodyObject;
					if (SetDestinationToPosition(((Component)grabBodyObject).transform.position, checkForPath: true))
					{
						if (Vector3.Distance(((Component)this).transform.position, ((Component)grabBodyObject).transform.position) < 1f)
						{
							GrabBody();
							returningBodyToNest = true;
							SwitchToBehaviourStateCustom(State.Roaming);
						}
						break;
					}
				}
				CheckForThreatsInLOS();
				break;
			case 2:
				base.agent.speed = 10f;
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					if (Vector3.Distance(((Component)base.targetPlayer).transform.position, ((Component)this).transform.position) > distanceToLoseRats)
					{
						base.targetPlayer = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
					else if (NearbyRatCount(swarmRadius) >= ratsNeededToAttack)
					{
						SwitchToBehaviourStateCustom(State.Attacking);
					}
				}
				else if ((Object)(object)targetEnemy != (Object)null)
				{
					if (Vector3.Distance(((Component)targetEnemy).transform.position, ((Component)this).transform.position) > distanceToLoseRats)
					{
						targetEnemy = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
					else if (NearbyRatCount(swarmRadius) >= ratsNeededToAttack)
					{
						SwitchToBehaviourStateCustom(State.Attacking);
					}
				}
				else
				{
					SwitchToBehaviourStateCustom(State.Roaming);
				}
				break;
			case 3:
				base.agent.speed = 10f;
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					if (Vector3.Distance(((Component)base.targetPlayer).transform.position, ((Component)this).transform.position) > distanceToLoseRats && !rallyRat)
					{
						base.targetPlayer = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
					else if (NearbyRatCount(swarmRadius) <= ratsNeededToAttack / 3 && !IsPlayerNearANest(base.targetPlayer))
					{
						base.targetPlayer = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
				}
				else if ((Object)(object)targetEnemy != (Object)null)
				{
					if (Vector3.Distance(((Component)targetEnemy).transform.position, ((Component)this).transform.position) > distanceToLoseRats * 2f)
					{
						targetEnemy = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
					else if (NearbyRatCount(swarmRadius) <= ratsNeededToAttack / 3)
					{
						targetEnemy = null;
						SwitchToBehaviourStateCustom(State.Roaming);
					}
				}
				else
				{
					SwitchToBehaviourStateCustom(State.Roaming);
				}
				break;
			case 4:
				base.agent.speed = 7f;
				break;
			default:
				Plugin.LoggerInstance.LogWarning((object)("Invalid state: " + base.currentBehaviourStateIndex));
				break;
			}
		}

		private void GrabBody()
		{
			if ((Object)(object)base.targetPlayer != (Object)null && (Object)(object)base.targetPlayer.deadBody != (Object)null)
			{
				int attachedLimbIndex = Random.Range(0, base.targetPlayer.deadBody.bodyParts.Length);
				GrabBodyClientRpc(base.targetPlayer.actualClientId, attachedLimbIndex);
			}
		}

		private void DropBody(bool deactivate = false)
		{
			if ((Object)(object)heldBody != (Object)null)
			{
				DropBodyClientRpc(deactivate);
			}
		}

		private bool SetDestinationToPosition(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			position = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 1.75f, -1);
			finalDestination = position;
			base.path1 = new NavMeshPath();
			if (!((Behaviour)base.agent).enabled)
			{
				return false;
			}
			if (!base.agent.CalculatePath(position, base.path1) || Vector3.Distance(base.path1.corners[base.path1.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 2.7f, -1)) > 1.55f)
			{
				if (canVent && (Object)(object)FromVent != (Object)null && (Object)(object)ToVent != (Object)null)
				{
					Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(((Component)FromVent.floorNode).transform.position, RoundManager.Instance.navHit, 1.75f, -1);
					if (Vector3.Distance(((Component)this).transform.position, navMeshPosition) < 1f)
					{
						WarpToVent(FromVent, ToVent);
						base.moveTowardsDestination = true;
						base.movingTowardsTargetPlayer = false;
						base.destination = RoundManager.Instance.GetNavMeshPosition(finalDestination, RoundManager.Instance.navHit, -1f, -1);
						return true;
					}
					base.moveTowardsDestination = true;
					base.movingTowardsTargetPlayer = false;
					base.destination = RoundManager.Instance.GetNavMeshPosition(navMeshPosition, RoundManager.Instance.navHit, -1f, -1);
					return true;
				}
				return false;
			}
			base.moveTowardsDestination = true;
			base.movingTowardsTargetPlayer = false;
			base.destination = RoundManager.Instance.GetNavMeshPosition(finalDestination, RoundManager.Instance.navHit, -1f, -1);
			return true;
		}

		private void SpawnNestIfNonExist()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SewerGrate.Nests.FirstOrDefault() == (Object)null)
			{
				Object.Instantiate<GameObject>(NestPrefab, ((Component)this).transform.position, Quaternion.identity).GetComponentInChildren<NetworkObject>().Spawn(true);
			}
		}

		private bool TryGetAnyNest()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Nest = SewerGrate.Nests.FirstOrDefault();
			if ((Object)(object)Nest != (Object)null)
			{
				SetNestClientRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)Nest).NetworkObject));
			}
			return (Object)(object)Nest != (Object)null;
		}

		private bool GetStartNest()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			foreach (SewerGrate nest in SewerGrate.Nests)
			{
				if (Vector3.Distance(((Component)this).transform.position, ((Component)nest).transform.position) < 2f)
				{
					Nest = nest;
					return true;
				}
			}
			return false;
		}

		private void HottestRat()
		{
			if (Random.Range(0f, 1f) < 0.01f)
			{
				ScanNode.headerText = "HottestRat";
			}
		}

		private bool CheckLineOfSightForDeadBody()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0055: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				DeadBodyInfo deadBody = val.deadBody;
				if (!((Object)(object)deadBody == (Object)null) && !deadBody.deactivated)
				{
					base.path1 = new NavMeshPath();
					if (((EnemyAI)this).CheckLineOfSightForPosition(((Component)deadBody.grabBodyObject).transform.position, 60f, 60, 5f, (Transform)null) && base.agent.CalculatePath(RoundManager.Instance.GetNavMeshPosition(((Component)deadBody.grabBodyObject).transform.position, RoundManager.Instance.navHit, 1.75f, -1), base.path1))
					{
						base.targetPlayer = deadBody.playerScript;
						return true;
					}
				}
			}
			return false;
		}

		private void CheckForThreatsInLOS()
		{
			if (!(timeSinceAddThreat > timeToIncreaseThreat))
			{
				return;
			}
			if (CheckLineOfSightForDeadBody())
			{
				StopRoutines();
				grabbingBody = true;
				return;
			}
			PlayerControllerB val = ((EnemyAI)this).CheckLineOfSightForPlayer(60f, 60, 5);
			if (PlayerIsTargetable(val))
			{
				AddThreat(val);
				return;
			}
			EnemyAI val2 = CheckLineOfSightForEnemy(30);
			if ((Object)(object)val2 != (Object)null && val2.enemyType.canDie)
			{
				AddThreat(val2);
			}
		}

		private int NearbyRatCount(float radius)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (RatAI rat in Rats)
			{
				if (Vector3.Distance(((Component)this).transform.position, ((Component)rat).transform.position) <= radius)
				{
					num++;
				}
			}
			return num;
		}

		public void AssignRatType()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Nest == (Object)null)
			{
				RatTypeState = RatType.Unassigned;
				SwitchToBehaviourStateCustom(State.Roaming);
				return;
			}
			if (!AtNest)
			{
				RatTypeState = RatType.Unassigned;
				return;
			}
			if (holdingFood)
			{
				holdingFood = false;
				Nest.AddFood();
			}
			if (Nest.DefenseRatCount < maxDefenseRats)
			{
				logIfDebug("Rat defense assigned");
				RatTypeState = RatType.DefenseRat;
				Nest.DefenseRatCount++;
				ratCoroutine = ((MonoBehaviour)this).StartCoroutine(SwarmCoroutine(((Component)Nest).transform.position, defenseRadius));
				SetStatus("Defending");
			}
			else
			{
				logIfDebug("Rat scout assigned");
				RatTypeState = RatType.ScoutRat;
				ratCoroutine = ((MonoBehaviour)this).StartCoroutine(ScoutCoroutine());
				SetStatus("Scouting");
			}
		}

		private EnemyVent? GetClosestVentToPosition(Vector3 pos)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			float num = 2000f;
			EnemyVent result = null;
			EnemyVent[] allEnemyVents = RoundManager.Instance.allEnemyVents;
			foreach (EnemyVent val in allEnemyVents)
			{
				float num2 = Vector3.Distance(pos, ((Component)val.floorNode).transform.position);
				if (((Behaviour)base.agent).enabled && CalculatePath(pos, ((Component)val.floorNode).transform.position) && num2 < num)
				{
					num = num2;
					result = val;
				}
			}
			return result;
		}

		private bool CalculatePath(Vector3 fromPos, Vector3 toPos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0044: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(fromPos, RoundManager.Instance.navHit, 1.75f, -1);
			Vector3 navMeshPosition2 = RoundManager.Instance.GetNavMeshPosition(toPos, RoundManager.Instance.navHit, 1.75f, -1);
			base.path1 = new NavMeshPath();
			if (!((Behaviour)base.agent).enabled)
			{
				return false;
			}
			return NavMesh.CalculatePath(navMeshPosition, navMeshPosition2, base.agent.areaMask, base.path1) && Vector3.Distance(base.path1.corners[base.path1.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(navMeshPosition2, RoundManager.Instance.navHit, 2.7f, -1)) <= 1.55f;
		}

		public EnemyAI? CheckLineOfSightForEnemy(int range)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				if ((Object)(object)spawnedEnemy.enemyType == (Object)(object)base.enemyType || !spawnedEnemy.enemyType.canDie || !((EnemyAI)this).CheckLineOfSightForPosition(((Component)spawnedEnemy).transform.position, 60f, range, 5f, (Transform)null))
				{
					continue;
				}
				return spawnedEnemy;
			}
			return null;
		}

		public EnemyAI? GetClosestEnemy(float range)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			EnemyAI result = null;
			float num = range;
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				if (!((Object)(object)spawnedEnemy.enemyType == (Object)(object)base.enemyType) && spawnedEnemy.enemyType.canDie)
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)spawnedEnemy).transform.position);
					if (num2 < num)
					{
						result = spawnedEnemy;
						num = num2;
					}
				}
			}
			return result;
		}

		private bool TargetPlayerNearNest()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Nest == (Object)null)
			{
				return false;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (PlayerIsTargetable(val) && Vector3.Distance(((Component)val).transform.position, ((Component)Nest).transform.position) < defenseRadius)
				{
					base.targetPlayer = val;
				}
			}
			return (Object)(object)base.targetPlayer != (Object)null;
		}

		private void WarpToVent(EnemyVent fromVent, EnemyVent toVent)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			OpenVent(fromVent);
			OpenVent(toVent);
			Vector3 val = (base.serverPosition = RoundManager.Instance.GetNavMeshPosition(((Component)ToVent.floorNode).transform.position, RoundManager.Instance.navHit, 1.75f, -1));
			((Component)this).transform.position = val;
			base.agent.Warp(val);
			((EnemyAI)this).SyncPositionToClients();
		}

		private int GetVentIndex(EnemyVent? vent)
		{
			for (int i = 0; i < RoundManager.Instance.allEnemyVents.Length; i++)
			{
				if ((Object)(object)RoundManager.Instance.allEnemyVents[i] == (Object)(object)vent)
				{
					return i;
				}
			}
			return -1;
		}

		private void OpenVent(EnemyVent? vent)
		{
			if (!((Object)(object)vent == (Object)null))
			{
				int ventIndex = GetVentIndex(vent);
				if (ventIndex != -1)
				{
					OpenVentClientRpc(ventIndex);
				}
			}
		}

		private void SetStatus(string status)
		{
			if (testing)
			{
				ScanNode.subText = status;
			}
		}

		private void Roam()
		{
			if (ratCoroutine == null)
			{
				SetStatus("Lost");
				ratCoroutine = ((MonoBehaviour)this).StartCoroutine(RoamCoroutine());
			}
		}

		private IEnumerator RoamCoroutine()
		{
			yield return null;
			while (ratCoroutine != null)
			{
				float timeStuck = 0f;
				TargetRandomNode();
				Vector3 position = RoundManager.Instance.GetNavMeshPosition(base.targetNode.position, RoundManager.Instance.navHit, 1.75f, base.agent.areaMask);
				if (!SetDestinationToPosition(position))
				{
					continue;
				}
				while (((Behaviour)base.agent).enabled)
				{
					yield return (object)new WaitForSeconds(base.AIIntervalTime);
					if (!base.agent.hasPath || timeStuck > 1f)
					{
						PlaySqueakSFXClientRpc();
						break;
					}
					if (base.agent.velocity == Vector3.zero)
					{
						timeStuck += base.AIIntervalTime;
					}
				}
			}
			SwitchToBehaviourStateCustom(State.Roaming);
		}

		private IEnumerator SwarmCoroutine(PlayerControllerB player, float radius)
		{
			yield return null;
			logIfDebug("Starting swarm on player");
			while (ratCoroutine != null && (Object)(object)player != (Object)null && !((Object)(object)player == (Object)null) && !player.isPlayerDead)
			{
				float timeStuck = 0f;
				Vector3 position = RoundManager.Instance.GetRandomNavMeshPositionInRadius(((Component)player).transform.position, radius, RoundManager.Instance.navHit);
				SetDestinationToPosition(position, checkForPath: false);
				while (((Behaviour)base.agent).enabled)
				{
					yield return (object)new WaitForSeconds(base.AIIntervalTime);
					if (!base.agent.hasPath || timeStuck > 1f)
					{
						break;
					}
					if (base.agent.velocity == Vector3.zero)
					{
						timeStuck += base.AIIntervalTime;
					}
				}
				if (base.currentBehaviourStateIndex != 3)
				{
					PlaySqueakSFXClientRpc(shortsfx: true);
				}
			}
			SwitchToBehaviourStateCustom(State.Roaming);
		}

		private IEnumerator SwarmCoroutine(EnemyAI enemy, float radius)
		{
			yield return null;
			while (ratCoroutine != null && (Object)(object)enemy != (Object)null)
			{
				float timeStuck = 0f;
				Vector3 position = RoundManager.Instance.GetRandomNavMeshPositionInRadius(((Component)enemy).transform.position, radius, RoundManager.Instance.navHit);
				SetDestinationToPosition(position, checkForPath: false);
				while (((Behaviour)base.agent).enabled)
				{
					yield return (object)new WaitForSeconds(base.AIIntervalTime);
					if (!base.agent.hasPath || timeStuck > 1f)
					{
						break;
					}
					if (base.agent.velocity == Vector3.zero)
					{
						timeStuck += base.AIIntervalTime;
					}
				}
				if (base.currentBehaviourStateIndex != 3)
				{
					PlaySqueakSFXClientRpc(shortsfx: true);
				}
			}
			SwitchToBehaviourStateCustom(State.Roaming);
		}

		private IEnumerator SwarmCoroutine(Vector3 position, float radius)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			yield return null;
			while (ratCoroutine != null)
			{
				float timeStuck = 0f;
				Vector3 pos2 = position;
				pos2 = RoundManager.Instance.GetRandomNavMeshPositionInRadius(pos2, radius, RoundManager.Instance.navHit);
				SetDestinationToPosition(pos2, checkForPath: false);
				while (((Behaviour)base.agent).enabled)
				{
					yield return (object)new WaitForSeconds(base.AIIntervalTime);
					if (!base.agent.hasPath || timeStuck > 1f)
					{
						break;
					}
					if (base.agent.velocity == Vector3.zero)
					{
						timeStuck += base.AIIntervalTime;
					}
				}
				if (base.currentBehaviourStateIndex != 3)
				{
					PlaySqueakSFXClientRpc(shortsfx: true);
				}
			}
			SwitchToBehaviourStateCustom(State.Roaming);
		}

		private IEnumerator ScoutCoroutine()
		{
			yield return null;
			while (ratCoroutine != null && ((Behaviour)base.agent).enabled)
			{
				float timeStuck = 0f;
				TargetRandomNode();
				Vector3 position = ((Component)base.targetNode).transform.position;
				if (!SetDestinationToPosition(position))
				{
					continue;
				}
				while (((Behaviour)base.agent).enabled)
				{
					yield return (object)new WaitForSeconds(base.AIIntervalTime);
					if (!base.agent.hasPath || timeStuck > 1f)
					{
						PlaySqueakSFXClientRpc();
						SwitchToBehaviourStateCustom(State.Roaming);
						ratCoroutine = null;
						yield break;
					}
					if (base.agent.velocity == Vector3.zero)
					{
						timeStuck += base.AIIntervalTime;
					}
				}
			}
			SwitchToBehaviourStateCustom(State.Roaming);
		}

		private void TargetRandomNode()
		{
			GameObject[] allAINodes = base.allAINodes;
			int num = Random.Range(0, allAINodes.Length);
			base.targetNode = allAINodes[num].transform;
		}

		public override void HitEnemy(int force = 0, PlayerControllerB playerWhoHit = null, bool playHitSFX = true, int hitID = -1)
		{
			if (!base.isEnemyDead)
			{
				base.enemyHP -= force;
				if (base.enemyHP <= 0)
				{
					DropBody();
					RoundManager.PlayRandomClip(base.creatureSFX, HitSFX, true, 1f, -1, 1000);
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
		}

		public void StopRoutines()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			ratCoroutine = null;
		}

		public override void CancelSpecialAnimationWithPlayer()
		{
			StopRoutines();
		}

		public override void HitFromExplosion(float distance)
		{
			RoundManager.PlayRandomClip(base.creatureSFX, HitSFX, true, 1f, -1, 1000);
			((EnemyAI)this).KillEnemyOnOwnerClient(false);
		}

		public bool PlayerIsTargetable(PlayerControllerB playerScript)
		{
			if ((Object)(object)playerScript == (Object)null)
			{
				return false;
			}
			if (playerScript.isPlayerDead)
			{
				return false;
			}
			if (base.currentBehaviourStateIndex == 0)
			{
				return false;
			}
			if (!playerScript.isPlayerControlled)
			{
				return false;
			}
			if ((Object)(object)playerScript.inAnimationWithEnemy != (Object)null)
			{
				return false;
			}
			if (playerScript.sinkingValue >= 0.73f)
			{
				return false;
			}
			return true;
		}

		public bool IsPlayerNearANest(PlayerControllerB player)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			foreach (SewerGrate nest in SewerGrate.Nests)
			{
				if (Vector3.Distance(((Component)player).transform.position, ((Component)nest).transform.position) < defenseRadius)
				{
					return true;
				}
			}
			return false;
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (!base.isEnemyDead && timeSinceCollision > 1f)
			{
				timeSinceCollision = 0f;
				PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
				if (!((Object)(object)val == (Object)null) && (base.currentBehaviourStateIndex == 3 || IsPlayerNearANest(val)))
				{
					int num = ((Random.Range(0, 2) == 1) ? 7 : 0);
					val.DamagePlayer(ratDamage, true, true, (CauseOfDeath)6, num, false, default(Vector3));
					PlayAttackSFXServerRpc();
				}
			}
		}

		public override void OnCollideWithEnemy(Collider other, EnemyAI collidedEnemy = null)
		{
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).OnCollideWithEnemy(other, collidedEnemy);
			if (Plugin.IsServerOrHost)
			{
				if (base.isEnemyDead || base.currentBehaviourStateIndex == 0 || (Object)(object)Nest == (Object)null)
				{
					return;
				}
				if (timeSinceCollision > 1f && (Object)(object)collidedEnemy != (Object)null && (Object)(object)collidedEnemy.enemyType != (Object)(object)base.enemyType && collidedEnemy.enemyType.canDie && !(base.stunNormalizedTimer > 0f))
				{
					logIfDebug("Collided with: " + collidedEnemy.enemyType.enemyName);
					timeSinceCollision = 0f;
					if (collidedEnemy.isEnemyDead)
					{
						if (SewerGrate.EnemyFoodAmount.ContainsKey(collidedEnemy))
						{
							if (SewerGrate.EnemyFoodAmount[collidedEnemy] <= 1)
							{
								holdingFood = SewerGrate.EnemyFoodAmount[collidedEnemy] == 1;
								((NetworkBehaviour)collidedEnemy).NetworkObject.Despawn(true);
								return;
							}
							SewerGrate.EnemyFoodAmount[collidedEnemy]--;
							holdingFood = true;
						}
						else
						{
							SewerGrate.EnemyHitCount.Remove(collidedEnemy);
							Nest.AddEnemyFoodAmount(collidedEnemy);
							SewerGrate.EnemyFoodAmount[collidedEnemy]--;
							holdingFood = true;
						}
						SwitchToBehaviourStateCustom(State.Roaming);
					}
					else
					{
						if (!SewerGrate.EnemyHitCount.ContainsKey(collidedEnemy))
						{
							SewerGrate.EnemyHitCount.Add(collidedEnemy, enemyHitsToDoDamage);
						}
						SewerGrate.EnemyHitCount[collidedEnemy]--;
						if (SewerGrate.EnemyHitCount[collidedEnemy] <= 0)
						{
							collidedEnemy.HitEnemy(1, (PlayerControllerB)null, true, -1);
							SewerGrate.EnemyHitCount[collidedEnemy] = enemyHitsToDoDamage;
						}
					}
				}
			}
			if (holdingFood)
			{
				RoundManager.PlayRandomClip(base.creatureSFX, NibbleSFX, true, 1f, -1, 1000);
				if ((Object)(object)collidedEnemy != (Object)null && Plugin.localPlayer.HasLineOfSightToPosition(((Component)collidedEnemy).transform.position, 45f, 60, -1f))
				{
					Plugin.localPlayer.IncreaseFearLevelOverTime(0.8f, 1f);
				}
			}
		}

		private void AddThreat(EnemyAI enemy, int amount = 1)
		{
			if (!((Object)(object)enemy == (Object)null) && (Object)(object)Nest != (Object)null && !Nest.IsRallying)
			{
				timeSinceAddThreat = 0f;
				if (Nest.EnemyThreatCounter.ContainsKey(enemy))
				{
					Nest.EnemyThreatCounter[enemy] += amount;
				}
				else
				{
					Nest.EnemyThreatCounter.Add(enemy, amount);
				}
				PlaySqueakSFXClientRpc(shortsfx: true);
				int num = Nest.EnemyThreatCounter[enemy];
				logIfDebug($"{enemy.enemyType.enemyName}: {num} threat");
				if (RatTypeState != RatType.DefenseRat && (Nest.EnemyThreatCounter[enemy] > threatToAttackEnemy || enemy.isEnemyDead))
				{
					SetTarget(enemy);
					SwitchToBehaviourStateCustom(State.Swarming);
				}
			}
		}

		private void AddThreat(PlayerControllerB player, int amount = 1)
		{
			if (!((Object)(object)player == (Object)null) && (Object)(object)Nest != (Object)null && !Nest.IsRallying)
			{
				timeSinceAddThreat = 0f;
				if (Nest.PlayerThreatCounter.ContainsKey(player))
				{
					Nest.PlayerThreatCounter[player] += amount;
				}
				else
				{
					Nest.PlayerThreatCounter.Add(player, amount);
				}
				PlaySqueakSFXClientRpc(shortsfx: true);
				int num = Nest.PlayerThreatCounter[player];
				logIfDebug($"{player.playerUsername}: {num} threat");
				if (RatTypeState != RatType.DefenseRat && (Nest.PlayerThreatCounter[player] > threatToAttackPlayer || player.isPlayerDead))
				{
					SetTarget(player);
					SwitchToBehaviourStateCustom(State.Swarming);
				}
			}
		}

		public void SetTarget(PlayerControllerB player)
		{
			timeSinceAttackCheck = 0f;
			targetEnemy = null;
			base.targetPlayer = player;
		}

		public void SetTarget(EnemyAI enemy)
		{
			timeSinceAttackCheck = 0f;
			base.targetPlayer = null;
			targetEnemy = enemy;
		}

		private void logIfDebug(string message)
		{
			if (testing)
			{
				Plugin.LoggerInstance.LogDebug((object)message);
			}
		}

		public override void SetEnemyStunned(bool setToStunned, float setToStunTime = 1f, PlayerControllerB setStunnedByPlayer = null)
		{
			if (base.isEnemyDead)
			{
				return;
			}
			if (setToStunned)
			{
				if (!(base.postStunInvincibilityTimer >= 0f))
				{
					base.stunnedByPlayer = setStunnedByPlayer;
					base.postStunInvincibilityTimer = 0.5f;
					base.stunNormalizedTimer = 5f;
				}
			}
			else
			{
				base.stunnedByPlayer = null;
				if (base.stunNormalizedTimer > 0f)
				{
					base.stunNormalizedTimer = 0f;
				}
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			if (destroy && base.enemyType.canBeDestroyed)
			{
				Debug.Log((object)"Destroy enemy called");
				if (((NetworkBehaviour)this).IsServer)
				{
					Debug.Log((object)"Despawn network object in kill enemy called!");
					if (base.thisNetworkObject.IsSpawned)
					{
						base.thisNetworkObject.Despawn(true);
					}
				}
				return;
			}
			if ((Object)(object)ScanNode != (Object)null && Object.op_Implicit((Object)(object)((Component)ScanNode).gameObject.GetComponent<Collider>()))
			{
				((Component)ScanNode).gameObject.GetComponent<Collider>().enabled = false;
			}
			base.isEnemyDead = true;
			try
			{
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetBool("stunned", false);
					base.creatureAnimator.SetTrigger("KillEnemy");
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"enemy did not have bool in animator in KillEnemy, error returned; {arg}");
			}
			((MonoBehaviour)this).StopAllCoroutines();
			((Behaviour)base.agent).enabled = false;
			Rats.Remove(this);
			if (RatTypeState == RatType.DefenseRat)
			{
				Nest.DefenseRatCount--;
			}
		}

		public override void OnDestroy()
		{
			((Behaviour)base.agent).enabled = false;
			((MonoBehaviour)this).StopAllCoroutines();
			if ((Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned && ((NetworkBehaviour)this).IsSpawned)
			{
				((NetworkBehaviour)this).NetworkObject.OnNetworkBehaviourDestroyed((NetworkBehaviour)(object)this);
			}
			if (!((NetworkBehaviour)this).m_VarInit)
			{
				((NetworkBehaviour)this).InitializeVariables();
			}
			for (int i = 0; i < ((NetworkBehaviour)this).NetworkVariableFields.Count; i++)
			{
				((NetworkBehaviour)this).NetworkVariableFields[i].Dispose();
			}
			if (RoundManager.Instance.SpawnedEnemies.Contains((EnemyAI)(object)this))
			{
				RoundManager.Instance.SpawnedEnemies.Remove((EnemyAI)(object)this);
			}
			Rats.Remove(this);
		}

		public bool SetDestinationToPosition(Vector3 position, bool checkForPath = false)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0038: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (checkForPath)
			{
				position = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 1.75f, -1);
				base.path1 = new NavMeshPath();
				if (!base.agent.CalculatePath(position, base.path1))
				{
					return false;
				}
				if (Vector3.Distance(base.path1.corners[base.path1.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 2.7f, -1)) > 1.55f)
				{
					return false;
				}
			}
			base.moveTowardsDestination = true;
			base.movingTowardsTargetPlayer = false;
			base.destination = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, -1f, -1);
			return true;
		}

		[ServerRpc(RequireOwnership = false)]
		public void PlayAttackSFXServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4136324962u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4136324962u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && Plugin.IsServerOrHost)
				{
					PlayAttackSFXClientRpc();
				}
			}
		}

		[ClientRpc]
		public void PlayAttackSFXClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2132714291u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2132714291u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					RoundManager.PlayRandomClip(base.creatureSFX, AttackSFX, true, 1f, -1, 1000);
				}
			}
		}

		[ClientRpc]
		public void SwitchToBehaviourClientRpc(int stateIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2453761421u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, stateIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2453761421u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && base.currentBehaviourStateIndex != stateIndex)
				{
					base.currentBehaviourStateIndex = stateIndex;
					base.currentBehaviourState = base.enemyBehaviourStates[stateIndex];
				}
			}
		}

		[ClientRpc]
		public void DamagePlayerClientRpc(ulong clientId, int damage = 1)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(771720103u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				BytePacker.WriteValueBitPacked(val2, damage);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 771720103u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (Plugin.localPlayer.actualClientId == clientId)
				{
					int num = ((Random.Range(0, 2) == 1) ? 7 : 0);
					Plugin.localPlayer.DamagePlayer(damage, true, true, (CauseOfDeath)6, num, false, default(Vector3));
				}
				RoundManager.PlayRandomClip(base.creatureSFX, AttackSFX, true, 1f, -1, 1000);
			}
		}

		[ClientRpc]
		public void PlaySqueakSFXClientRpc(bool shortsfx = false)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2878241198u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref shortsfx, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2878241198u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (shortsfx)
				{
					RoundManager.PlayRandomClip(base.creatureSFX, HitSFX, true, 1f, -1, 1000);
				}
				else
				{
					RoundManager.PlayRandomClip(base.creatureSFX, SqueakSFX, true, 1f, -1, 1000);
				}
			}
		}

		[ClientRpc]
		public void OpenVentClientRpc(int ventIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2429225862u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, ventIndex);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2429225862u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			EnemyVent val3 = RoundManager.Instance.allEnemyVents[ventIndex];
			if ((Object)(object)val3 == (Object)null)
			{
				RoundManager.Instance.RefreshEnemyVents();
				val3 = RoundManager.Instance.allEnemyVents[ventIndex];
				if ((Object)(object)val3 == (Object)null)
				{
					Plugin.LoggerInstance.LogError((object)"Cant get vent to open on client");
					return;
				}
			}
			val3.ventIsOpen = true;
			val3.ventAnimator.SetTrigger("openVent");
			val3.lowPassFilter.lowpassResonanceQ = 0f;
		}

		[ServerRpc(RequireOwnership = false)]
		public void AddThreatServerRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(166353355u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, clientId);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 166353355u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && Plugin.IsServerOrHost && timeSinceAddThreat > timeToIncreaseThreat)
				{
					PlayerControllerB player = Plugin.PlayerFromId(clientId);
					AddThreat(player);
				}
			}
		}

		[ClientRpc]
		public void SetNestClientRpc(NetworkObjectReference nestRef)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(797388341u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref nestRef, default(ForNetworkSerializable));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 797388341u, val, (RpcDelivery)0);
				}
				NetworkObject val3 = default(NetworkObject);
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && ((NetworkObjectReference)(ref nestRef)).TryGet(ref val3, (NetworkManager)null))
				{
					Nest = ((Component)val3).GetComponent<SewerGrate>();
				}
			}
		}

		[ClientRpc]
		public void GrabBodyClientRpc(ulong clientId, int attachedLimbIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3500738837u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				BytePacker.WriteValueBitPacked(val2, attachedLimbIndex);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3500738837u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.targetPlayer = Plugin.PlayerFromId(clientId);
				if ((Object)(object)base.targetPlayer != (Object)null && (Object)(object)base.targetPlayer.deadBody != (Object)null)
				{
					heldBody = base.targetPlayer.deadBody;
					heldBody.attachedTo = RatMouth;
					heldBody.attachedLimb = base.targetPlayer.deadBody.bodyParts[attachedLimbIndex];
					heldBody.matchPositionExactly = true;
				}
				grabbingBody = false;
				returningBodyToNest = true;
				RoundManager.PlayRandomClip(base.creatureSFX, NibbleSFX, true, 1f, -1, 1000);
			}
		}

		[ClientRpc]
		public void DropBodyClientRpc(bool deactivate)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1118647984u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref deactivate, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1118647984u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			returningBodyToNest = false;
			grabbingBody = false;
			base.targetPlayer = null;
			if ((Object)(object)heldBody != (Object)null)
			{
				heldBody.attachedTo = null;
				heldBody.attachedLimb = null;
				heldBody.matchPositionExactly = false;
				if (deactivate)
				{
					heldBody.DeactivateBody(false);
				}
				heldBody = null;
			}
		}

		protected override void __initializeVariables()
		{
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_RatAI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(4136324962u, new RpcReceiveHandler(__rpc_handler_4136324962));
			NetworkManager.__rpc_func_table.Add(2132714291u, new RpcReceiveHandler(__rpc_handler_2132714291));
			NetworkManager.__rpc_func_table.Add(2453761421u, new RpcReceiveHandler(__rpc_handler_2453761421));
			NetworkManager.__rpc_func_table.Add(771720103u, new RpcReceiveHandler(__rpc_handler_771720103));
			NetworkManager.__rpc_func_table.Add(2878241198u, new RpcReceiveHandler(__rpc_handler_2878241198));
			NetworkManager.__rpc_func_table.Add(2429225862u, new RpcReceiveHandler(__rpc_handler_2429225862));
			NetworkManager.__rpc_func_table.Add(166353355u, new RpcReceiveHandler(__rpc_handler_166353355));
			NetworkManager.__rpc_func_table.Add(797388341u, new RpcReceiveHandler(__rpc_handler_797388341));
			NetworkManager.__rpc_func_table.Add(3500738837u, new RpcReceiveHandler(__rpc_handler_3500738837));
			NetworkManager.__rpc_func_table.Add(1118647984u, new RpcReceiveHandler(__rpc_handler_1118647984));
		}

		private static void __rpc_handler_4136324962(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((RatAI)(object)target).PlayAttackSFXServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2132714291(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).PlayAttackSFXClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2453761421(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int stateIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref stateIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).SwitchToBehaviourClientRpc(stateIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_771720103(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				int damage = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref damage);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).DamagePlayerClientRpc(clientId, damage);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2878241198(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool shortsfx = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref shortsfx, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).PlaySqueakSFXClientRpc(shortsfx);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2429225862(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int ventIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref ventIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).OpenVentClientRpc(ventIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_166353355(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((RatAI)(object)target).AddThreatServerRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_797388341(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkObjectReference nestClientRpc = default(NetworkObjectReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref nestClientRpc, default(ForNetworkSerializable));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).SetNestClientRpc(nestClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3500738837(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				int attachedLimbIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref attachedLimbIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).GrabBodyClientRpc(clientId, attachedLimbIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1118647984(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool deactivate = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref deactivate, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((RatAI)(object)target).DropBodyClientRpc(deactivate);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "RatAI";
		}
	}
	internal class SewerGrate : NetworkBehaviour
	{
		private static ManualLogSource logger = Plugin.LoggerInstance;

		public static List<SewerGrate> Nests = new List<SewerGrate>();

		public static Dictionary<EnemyAI, int> EnemyHitCount = new Dictionary<EnemyAI, int>();

		public static Dictionary<EnemyAI, int> EnemyFoodAmount = new Dictionary<EnemyAI, int>();

		public GameObject RatPrefab = null;

		public TextMeshPro[] TerminalCodes = null;

		public TerminalAccessibleObject TerminalAccessibleObj = null;

		private EnemyVent? ClosestVentToNest = null;

		public int DefenseRatCount;

		public Dictionary<PlayerControllerB, int> PlayerThreatCounter = new Dictionary<PlayerControllerB, int>();

		public Dictionary<EnemyAI, int> EnemyThreatCounter = new Dictionary<EnemyAI, int>();

		public List<RatAI> RallyRats = new List<RatAI>();

		public RatAI? LeadRallyRat;

		private float rallyCooldown;

		private float rallyTimer;

		private float timeSinceSpawnRat;

		private float nextRatSpawnTime;

		public bool open = true;

		private bool codeOnGrateSet = false;

		private int food;

		private bool hideCodeOnTerminal = true;

		private float minRatSpawnTime = 10f;

		private float maxRatSpawnTime = 30f;

		private float rallyTimeLength = 10f;

		private float rallyCooldownLength = 60f;

		private int foodToSpawnRat = 5;

		private int enemyFoodPerHPPoint = 10;

		private int maxRats = 40;

		public static int RatCount => Object.FindObjectsOfType<RatAI>().Length;

		public bool IsRallying => rallyTimer > 0f;

		public bool CanRally => rallyCooldown <= 0f;

		public void Start()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource obj = logger;
			Vector3 position = ((Component)this).transform.position;
			obj.LogDebug((object)("Sewer grate spawned at: " + ((object)(Vector3)(ref position)).ToString()));
			Nests.Add(this);
			hideCodeOnTerminal = Plugin.configHideCodeOnTerminal.Value;
			minRatSpawnTime = Plugin.configMinRatSpawnTime.Value;
			maxRatSpawnTime = Plugin.configMaxRatSpawnTime.Value;
			foodToSpawnRat = Plugin.configFoodToSpawnRat.Value;
			enemyFoodPerHPPoint = Plugin.configEnemyFoodPerHPPoint.Value;
			maxRats = Plugin.configMaxRats.Value;
			if (Plugin.IsServerOrHost)
			{
				nextRatSpawnTime = Random.Range(minRatSpawnTime, maxRatSpawnTime);
			}
		}

		public void Update()
		{
			if (!codeOnGrateSet && TerminalAccessibleObj.objectCode