Decompiled source of TheShatterling v1.1.3

Shatterling.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using REPOLib.Objects.Sdk;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Discord.Sdk")]
[assembly: IgnoresAccessChecksTo("Domain_Reload")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")]
[assembly: IgnoresAccessChecksTo("Unity.Localization")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.MemoryProfiler")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.ResourceManager")]
[assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")]
[assembly: IgnoresAccessChecksTo("Unity.Splines")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: AssemblyCompany("Shatterling")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3")]
[assembly: AssemblyProduct("Shatterling")]
[assembly: AssemblyTitle("Shatterling")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Shatterling
{
	internal sealed class Brain : MonoBehaviour, IPunObservable
	{
		private enum Effect : byte
		{
			Carpet
		}

		private float nextAttack;

		private float nextBite;

		private float nextSwipe;

		private float nextVolley;

		private float nextSlam;

		private float nextSwarm;

		private float nextGrab;

		private float nextSpires;

		private Vector3 aim;

		private Vector3 aimPoint;

		private Vector3 leapFrom;

		private bool struck;

		private bool released;

		private readonly HashSet<Enemy> hitEnemies = new HashSet<Enemy>();

		private readonly HashSet<PlayerAvatar> swarmHit = new HashSet<PlayerAvatar>();

		private Vector3 swarmTo;

		private float swarmUntil;

		private float nextSwarmPath;

		private PlayerAvatar victim;

		private PlayerAvatar deadInFist;

		private float headWatchUntil;

		private const float LeapTime = 0.25f;

		private Enemy enemy;

		private EnemyParent parent;

		private PhotonView view;

		private Body body;

		private Sight sight;

		private Transform feet;

		private Mode mode;

		private int absorbed;

		private bool lockedOn;

		private byte healthShare = byte.MaxValue;

		private PlayerAvatar target;

		private Vector3 lastSeen;

		private float lastSeenAt = -99f;

		private float modeAt;

		private float chaseStarted;

		private float tipOffAt;

		private float lookAroundUntil;

		private float leaveUntil;

		private float recoverFor;

		private float nextThink;

		private float nextIdle;

		private float nextMess;

		private readonly Dictionary<PlayerAvatar, float> hitRecently = new Dictionary<PlayerAvatar, float>();

		private Vector3? noise;

		private Vector3? hunger;

		private bool wasStunned;

		private Mode afterGrow;

		private Stage growTo;

		private float growBurst;

		private float growReformAt;

		private float growReformFor;

		private float growReformed = -1f;

		private Vector3 goal;

		private bool hasGoal;

		private float speed;

		private Quaternion facing;

		private bool looking;

		private Vector3 lookAt;

		private int spawns;

		private Stage streamedTarget;

		private float streamedEase = 1f;

		private float fleeUntil;

		private float nextNip;

		internal static bool debugPending;

		private Attack nextForced;

		private List<Spires.Spike> spireField;

		private bool[] spireUp;

		private float spireAt;

		private float spireCrack;

		private float spireSpeed;

		private float spireEnd;

		private float nextHalo;

		private readonly HashSet<PlayerAvatar> spireHit = new HashSet<PlayerAvatar>();

		private readonly HashSet<Enemy> spireEnemies = new HashSet<Enemy>();

		private readonly HashSet<Enemy> haloEnemies = new HashSet<Enemy>();

		private bool squeezing;

		private bool crouching;

		private float squeezeAt;

		private float nextFit;

		private float noSqueezeUntil;

		private float pausedUntil;

		private float nextEscape;

		private Vector3? escape;

		private float S => Mathf.Max(0.2f, body.Scale);

		private float GrabReach => Plugin.GrabRange.Value * Mathf.Max(1f, Mathf.Sqrt(S));

		private float SwipeReach => Mathf.Max(0.5f, Plugin.SwipeReach[Mathf.Clamp((int)Stage, 1, 4)].Value) * body.Ease;

		internal int Absorbed => absorbed;

		internal Stage Stage => body.Stage;

		internal Stage Target
		{
			get
			{
				if (!Net.IsHost)
				{
					return streamedTarget;
				}
				return Growth.StageOf(absorbed);
			}
		}

		internal float Ease
		{
			get
			{
				if (!Net.IsHost)
				{
					return streamedEase;
				}
				return Growth.Ease(absorbed);
			}
		}

		internal bool LockedOn => lockedOn;

		internal bool InSwarm
		{
			get
			{
				Mode mode = this.mode;
				if ((mode - 10 > Mode.Hungry && mode != Mode.Grow) || 1 == 0)
				{
					return squeezing;
				}
				return true;
			}
		}

		internal bool Settled
		{
			get
			{
				bool flag = !squeezing;
				bool flag2 = flag;
				if (flag2)
				{
					Mode mode = this.mode;
					bool flag3 = ((mode <= Mode.Chase || mode - 16 <= Mode.Hungry) ? true : false);
					flag2 = flag3;
				}
				return flag2;
			}
		}

		internal float HealthShare => (float)(int)healthShare / 255f;

		internal bool Alive
		{
			get
			{
				if (Object.op_Implicit((Object)(object)enemy) && Object.op_Implicit((Object)(object)enemy.Health) && !enemy.Health.dead && Object.op_Implicit((Object)(object)parent))
				{
					return parent.Spawned;
				}
				return false;
			}
		}

		private float InMode => Time.time - modeAt;

		internal bool Squeezing => squeezing;

		internal bool Crouching => crouching;

		private bool Travelling
		{
			get
			{
				Mode mode = this.mode;
				if (mode <= Mode.Chase || mode - 17 <= Mode.Investigate)
				{
					return true;
				}
				return false;
			}
		}

		private float Reach => 0.6f + body.Form.BodyLength * body.Ease * 0.5f + speed * 0.25f;

		internal static List<Attack> Unlocked(Stage stage)
		{
			List<Attack> list = new List<Attack>();
			if ((int)stage <= 1)
			{
				list.Add(Attack.Bite);
			}
			if (stage == Stage.Crawler)
			{
				return list;
			}
			list.Add(Attack.Swipe);
			list.Add(Attack.Volley);
			if ((int)stage >= 2)
			{
				list.Add(Attack.Slam);
			}
			if ((int)stage >= 3)
			{
				list.Add(Attack.Swarm);
				list.Add(Attack.Grab);
			}
			if ((int)stage >= 4)
			{
				list.Add(Attack.Spires);
			}
			return list;
		}

		private bool TryAttack(float d)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < nextAttack || squeezing)
			{
				return false;
			}
			Stage stage = Stage;
			float num = Mathf.Abs(((Component)target).transform.position.y - ((Component)this).transform.position.y);
			List<(Attack, float)> list = new List<(Attack, float)>();
			if (stage == Stage.Stalker && d <= Plugin.BiteRange.Value + 0.4f && num < 1f && Time.time >= nextBite)
			{
				list.Add((Attack.Bite, 1f));
			}
			if (d <= SwipeReach * 0.85f + 0.2f && num < body.Height * 0.75f + 0.5f && Time.time >= nextSwipe && HeadRoom("swipe"))
			{
				list.Add((Attack.Swipe, 1f));
			}
			if ((int)stage >= 3 && d <= GrabReach * 0.85f && num < 1.8f && Time.time >= nextGrab && HeadRoom("grab", "hold", "hurl"))
			{
				list.Add((Attack.Grab, 0.8f));
			}
			if ((int)stage >= 2 && d <= Plugin.CarpetTrigger.Value * Mathf.Max(1f, S) && Time.time >= nextSlam && HeadRoom("slam"))
			{
				list.Add((Attack.Slam, 0.6f));
			}
			if (list.Count > 0)
			{
				return Use(Weighted(list), forced: false);
			}
			if ((int)stage >= 4 && d >= Plugin.SpiresMin.Value && d <= Plugin.SpiresMax.Value && Time.time >= nextSpires && Random.value < Plugin.SpiresChance.Value && HeadRoom("spires") && Reaches(body.Chest, target))
			{
				return Use(Attack.Spires, forced: false);
			}
			if ((int)stage >= 3 && d >= Plugin.SwarmMin.Value && d <= Plugin.SwarmMax.Value && Time.time >= nextSwarm && Random.value < Plugin.SwarmChance.Value && HeadRoom("shriek"))
			{
				return Use(Attack.Swarm, forced: false);
			}
			if (d >= Plugin.VolleyMin.Value && d <= Plugin.VolleyMax.Value && Time.time >= nextVolley && Random.value < Plugin.AttackChance.Value && HeadRoom((stage == Stage.Stalker) ? "shake" : "volley") && Reaches(body.Eyes, target))
			{
				return Use(Attack.Volley, forced: false);
			}
			return false;
		}

		private static Attack Weighted(List<(Attack attack, float weight)> options)
		{
			float num = Random.value * options.Sum(((Attack attack, float weight) o) => o.weight);
			foreach (var option in options)
			{
				Attack item = option.attack;
				float item2 = option.weight;
				num -= item2;
				if (num <= 0f)
				{
					return item;
				}
			}
			return options[options.Count - 1].attack;
		}

		private bool Use(Attack attack, bool forced)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: 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 (!Object.op_Implicit((Object)(object)target) || target.isDisabled || squeezing)
			{
				return false;
			}
			LetGo();
			Stop();
			leapFrom = ((Component)this).transform.position;
			Vector3 val = Flat(((Component)target).transform.position - ((Component)this).transform.position);
			aim = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref aim)).sqrMagnitude < 0.01f)
			{
				aim = ((Component)this).transform.forward;
			}
			aimPoint = Chest(target);
			facing = Quaternion.LookRotation(aim);
			struck = (released = false);
			hitEnemies.Clear();
			float num = Mathf.Max(0f, Plugin.AttackGap.Value);
			switch (attack)
			{
			case Attack.Bite:
				Enter(Mode.Bite);
				nextBite = Time.time + Plugin.BiteCooldown.Value;
				nextAttack = Time.time + Mathf.Min(num, Plugin.BiteCooldown.Value);
				Send(Cue.Bite, Plugin.BiteWarn.Value);
				break;
			case Attack.Swipe:
				Enter(Mode.Swipe);
				nextSwipe = Time.time + Plugin.SwipeCooldown.Value;
				nextAttack = Time.time + Mathf.Min(num, Plugin.SwipeCooldown.Value);
				Send(Cue.Swipe, Plugin.SwipeWarn.Value);
				break;
			case Attack.Volley:
				Enter(Mode.Volley);
				nextVolley = Time.time + Plugin.VolleyCooldown.Value;
				nextAttack = Time.time + num;
				Send(Cue.Volley, Plugin.VolleyWarn.Value);
				break;
			case Attack.Slam:
				Enter(Mode.Slam);
				nextSlam = Time.time + Plugin.CarpetCooldown.Value;
				nextAttack = Time.time + num;
				Send(Cue.Slam, Plugin.CarpetWarn.Value);
				break;
			case Attack.Swarm:
				Enter(Mode.Shriek);
				nextSwarm = Time.time + Plugin.SwarmCooldown.Value;
				nextAttack = Time.time + num;
				Send(Cue.Shriek, Plugin.SwarmWarn.Value);
				Say(Voice.Shriek);
				break;
			case Attack.Grab:
				Enter(Mode.Grab);
				nextGrab = Time.time + Plugin.GrabCooldown.Value;
				nextAttack = Time.time + num;
				Send(Cue.Reach, Plugin.GrabWarn.Value);
				break;
			case Attack.Spires:
				Enter(Mode.Spires);
				nextSpires = Time.time + Plugin.SpiresCooldown.Value;
				nextAttack = Time.time + num;
				Send(Cue.Spires, Plugin.SpiresWarn.Value);
				break;
			}
			object[] obj = new object[4] { attack, target.playerName, null, null };
			val = Flat(((Component)target).transform.position - ((Component)this).transform.position);
			obj[2] = ((Vector3)(ref val)).magnitude;
			obj[3] = (forced ? " (forced)" : "");
			Log(string.Format("{0} at {1}, {2:0.0} m{3}", obj));
			return true;
		}

		private void Track(float until)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && !(InMode >= until))
			{
				aimPoint = Vector3.MoveTowards(aimPoint, Chest(target), Mathf.Max(0.5f, Plugin.TrackSpeed.Value) * Time.deltaTime);
				Vector3 val = Flat(aimPoint - ((Component)this).transform.position);
				if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
				{
					aim = ((Vector3)(ref val)).normalized;
					facing = Quaternion.LookRotation(aim);
				}
			}
		}

		private void Bite()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0.1f, Plugin.BiteWarn.Value);
			if (InMode < num)
			{
				Stop();
				Track(num * 0.8f);
				return;
			}
			float num2 = Mathf.Max(0.2f, Plugin.BiteLeap.Value);
			if (InMode < num + 0.25f)
			{
				Nav.Straight(leapFrom, leapFrom + aim * num2, out var stop);
				enemy.NavMeshAgent.SetDestination(stop);
				enemy.NavMeshAgent.OverrideAgent(num2 / 0.25f, 80f, 0.2f);
				speed = num2 / 0.25f;
			}
			else
			{
				Stop();
			}
			if (!struck && Object.op_Implicit((Object)(object)target) && !target.isDisabled)
			{
				Vector3 mouth = body.Mouth;
				Vector3 val = ((Component)target).transform.position + Vector3.up * ((Stage == Stage.Crawler) ? 0.2f : 0.6f);
				Vector3 val2 = Flat(val - mouth);
				if (((Vector3)(ref val2)).magnitude <= 0.75f && Mathf.Abs(val.y - mouth.y) < 1.2f)
				{
					struck = true;
					Damage(target, Mathf.RoundToInt((Stage == Stage.Crawler) ? Plugin.BiteDamage.Value : Plugin.StalkerBiteDamage.Value));
					SendHit(target, val);
					Log("bit " + target.playerName);
				}
			}
			if (InMode >= num + 0.25f + 0.15f)
			{
				if (!struck)
				{
					Log("bite missed");
				}
				if (Stage == Stage.Crawler)
				{
					StartFlee(1.2f);
				}
				else
				{
					Recover(0.6f);
				}
			}
		}

		private void Swipe()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			float num = Mathf.Max(0.1f, Plugin.SwipeWarn.Value);
			Stop();
			Track(num * 0.8f);
			float value = Plugin.PounceLeap.Value;
			float num2 = body.Form.Hit("swipe", null, 0.75f);
			float num3 = Mathf.Clamp(num * (1f - body.Form.Event("swipe", "pounce", num2 - 0.25f) / num2), 0.1f, num);
			if (Stage == Stage.Stalker && value > 0f && InMode >= num - num3 && InMode < num)
			{
				Nav.Straight(leapFrom, leapFrom + aim * value, out var stop);
				enemy.NavMeshAgent.SetDestination(stop);
				enemy.NavMeshAgent.OverrideAgent(value / num3, 80f, 0.2f);
				speed = value / num3;
			}
			if (!struck && InMode >= num)
			{
				struck = true;
				Strike();
			}
			if (InMode >= num + 0.45f)
			{
				Recover(0.5f);
			}
		}

		private void Strike()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			float swipeReach = SwipeReach;
			Vector3 val = ((Component)this).transform.position + Vector3.up * Mathf.Clamp(body.Height * 0.45f, 0.3f, 1.6f);
			Stage stage = Stage;
			int num = Mathf.RoundToInt(Plugin.SwipeDamage[Mathf.Max(1, (int)stage)].Value);
			bool flag = stage == Stage.Sovereign;
			float num2 = (flag ? Plugin.SovereignTumble.Value : Plugin.SwipeTumble.Value);
			bool flag2 = (int)stage >= 2 && num2 > 0f;
			foreach (PlayerAvatar item in World.Targets())
			{
				Vector3 val2 = Chest(item) - ((Component)this).transform.position;
				Vector3 val3 = Flat(val2);
				if (((Vector3)(ref val3)).magnitude > swipeReach + 0.35f || val2.y < -0.8f || val2.y > body.Height + 0.3f)
				{
					continue;
				}
				val3 = Flat(val2);
				if (!(Vector3.Dot(((Vector3)(ref val3)).normalized, aim) < 0.3f) && Reaches(val, item))
				{
					bool flag3 = item.playerHealth.health <= num;
					Damage(item, num);
					SendHit(item, Chest(item));
					if (flag2 && !flag3)
					{
						Knock(item, flag ? (aim * 9f + Vector3.up * 3.5f) : (aim * 6f + Vector3.up * 2.5f), num2);
					}
					Log("swiped " + item.playerName + (flag3 ? ": killed" : ""));
				}
			}
			Vector3 at = val + aim * swipeReach * 0.6f;
			HitEnemies(at, 0.4f + swipeReach * 0.3f, Plugin.SwipeEnemyDamage.Value, hitEnemies);
			Shove(at, aim, Plugin.SwipeShove.Value, 0.3f + swipeReach * 0.25f);
		}

		private void VolleyMode()
		{
			//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)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0.1f, Plugin.VolleyWarn.Value);
			Stop();
			Track(num);
			if (!released && InMode >= num)
			{
				released = true;
				bool flag = Stage == Stage.Stalker;
				Vector3 origin = (flag ? (body.Chest + ((Component)this).transform.forward * 0.3f) : ((body.PalmL + body.PalmR) * 0.5f + ((Component)this).transform.forward * 0.2f * S));
				int num2 = Mathf.Max(1, Plugin.VolleyShardsMin.Value);
				int num3 = Mathf.Max(num2, Plugin.VolleyShardsMax.Value);
				int count = Mathf.Min(Random.Range(num2, num3 + 1) + (flag ? 2 : 0), 30);
				float spread = Mathf.Clamp(flag ? Plugin.ShakeSpread.Value : Plugin.VolleySpread.Value, 0f, 60f);
				SendVolley(origin, aimPoint, count, Random.Range(1, int.MaxValue), spread, Mathf.Max(2f, Plugin.VolleySpeed.Value));
			}
			if (InMode >= num + 0.6f)
			{
				Recover(0.5f);
			}
		}

		internal void ShardHit(PlayerAvatar p, Vector3 at)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Damage(p, Mathf.RoundToInt(Plugin.VolleyDamage.Value));
			SendHit(p, at);
		}

		internal void ShardStruck(Collider c, Vector3 dir)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)c))
			{
				return;
			}
			EnemyRigidbody componentInParent = ((Component)c).GetComponentInParent<EnemyRigidbody>();
			Enemy val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.enemy : ((Component)c).GetComponentInParent<Enemy>());
			if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)enemy)
			{
				if (val.HasHealth && Plugin.VolleyEnemyDamage.Value > 0f)
				{
					val.Health.Hurt(Mathf.RoundToInt(Plugin.VolleyEnemyDamage.Value), dir);
				}
				return;
			}
			PhysGrabObject componentInParent2 = ((Component)c).GetComponentInParent<PhysGrabObject>();
			if (Object.op_Implicit((Object)(object)componentInParent2) && Object.op_Implicit((Object)(object)componentInParent2.rb) && !componentInParent2.rb.isKinematic && !Object.op_Implicit((Object)(object)((Component)componentInParent2).GetComponent<PlayerTumble>()))
			{
				Feed.Touched(componentInParent2);
				componentInParent2.rb.AddForce(dir * 1.2f, (ForceMode)2);
			}
		}

		private void Slam()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00d1: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: 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_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0.1f, Plugin.CarpetWarn.Value);
			Stop();
			Track(num * 0.6f);
			if (!struck && InMode >= num)
			{
				struck = true;
				Vector3 val = (body.PalmL + body.PalmR) * 0.5f;
				float num2 = Vector3.Dot(val - ((Component)this).transform.position, ((Component)this).transform.forward);
				val = ((Component)this).transform.position + ((Component)this).transform.forward * ((num2 > 0.2f * S && num2 < 2.5f * S) ? num2 : (1f * S));
				RaycastHit val2 = default(RaycastHit);
				if (Physics.Raycast(val + Vector3.up * 1f, Vector3.down, ref val2, 3f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1))
				{
					val = ((RaycastHit)(ref val2)).point;
				}
				else
				{
					val.y = feet.position.y;
				}
				float num3 = Plugin.SlamReach.Value * S;
				foreach (PlayerAvatar item in World.Targets())
				{
					Vector3 val3 = Chest(item) - val;
					Vector3 val4 = Flat(val3);
					if (!(((Vector3)(ref val4)).magnitude > num3) && !(val3.y > 2f) && !(val3.y < -0.5f) && Reaches(val + Vector3.up * 0.5f, item))
					{
						Damage(item, Mathf.RoundToInt(Plugin.SlamDamage.Value));
						SendHit(item, Chest(item));
						val4 = Flat(val3);
						Knock(item, ((Vector3)(ref val4)).normalized * 4f + Vector3.up * 3f, 1.5f);
						Log("slammed " + item.playerName);
					}
				}
				HitEnemies(val + Vector3.up * 0.4f, num3, Plugin.SwipeEnemyDamage.Value, hitEnemies);
				Shove(val + Vector3.up * 0.3f, Vector3.up, Plugin.SwipeShove.Value * 0.8f, num3);
				SendFx(Effect.Carpet, val, ((Component)this).transform.forward);
			}
			if (InMode >= num + 0.7f)
			{
				Recover(0.6f);
			}
		}

		private void Shriek()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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)
			float num = Mathf.Max(0.1f, Plugin.SwarmWarn.Value);
			Stop();
			Track(num);
			if (!(InMode < num))
			{
				if (!Object.op_Implicit((Object)(object)target) || target.isDisabled)
				{
					Recover(0.5f);
					return;
				}
				enemy.Rigidbody.GrabRelease(true, 0.1f);
				Protect(0.3f);
				Send(Cue.Burst);
				Enter(Mode.Swarm);
				crouching = false;
				swarmHit.Clear();
				swarmTo = SwarmSpot(target);
				nextSwarmPath = Time.time + 0.25f;
				float num2 = Vector3.Distance(((Component)this).transform.position, swarmTo);
				swarmUntil = Time.time + num2 / Mathf.Max(1f, Plugin.SwarmSpeed.Value) + 2f;
				enemy.Rigidbody.notMovingTimer = 0f;
				Log($"swarming at {target.playerName}, {num2:0} m");
			}
		}

		private void Protect(float seconds)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			enemy.StateStunned.OverrideDisable(seconds);
			if ((int)enemy.CurrentState == 9)
			{
				enemy.CurrentState = (EnemyState)2;
			}
			enemy.Health.OverrideDamageResistance(1f, seconds);
			enemy.Health.ObjectHurtDisable(seconds);
		}

		private Vector3 SwarmSpot(PlayerAvatar p)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			//IL_002e: 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_0034: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			//IL_0063: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			//IL_007e: 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)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_009d: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)p).transform.position;
			float num = Mathf.Max(1f, Plugin.SwarmInFront.Value);
			Vector3 val = position + LookOf(p) * num;
			if (Nav.Straight(position, val, out var stop) && Nav.Sample(val, 1f, out var onMesh))
			{
				return onMesh;
			}
			Vector3 val2 = Flat(((Component)this).transform.position - position);
			Vector3 position2 = position + ((Vector3)(ref val2)).normalized * num;
			if (Nav.Sample(position2, 1.5f, out var onMesh2))
			{
				return onMesh2;
			}
			val2 = Flat(stop - position);
			if (!(((Vector3)(ref val2)).magnitude > 1f))
			{
				return position;
			}
			return stop;
		}

		private void SwarmMode()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0288: Unknown result type (might be due to invalid IL or missing references)
			Protect(0.3f);
			if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && sight.Visible(target, body.Eyes, Plugin.SwarmMax.Value * 1.5f))
			{
				Seen();
			}
			if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && Time.time >= nextSwarmPath)
			{
				nextSwarmPath = Time.time + 0.25f;
				swarmTo = SwarmSpot(target);
			}
			GoTo(swarmTo, Plugin.SwarmSpeed.Value, 60f);
			Vector3 val = ((Component)body).transform.position + Vector3.up * 0.8f * S;
			Vector3 val2;
			foreach (PlayerAvatar item in World.Targets())
			{
				if (!swarmHit.Contains(item))
				{
					val2 = Chest(item) - val;
					if (((Vector3)(ref val2)).magnitude <= 1.3f * S)
					{
						swarmHit.Add(item);
						Damage(item, Mathf.RoundToInt(Plugin.SwarmDamage.Value));
						SendHit(item, Chest(item));
						Log("the swarm cut " + item.playerName);
					}
				}
			}
			val2 = Flat(((Component)body).transform.position - swarmTo);
			bool flag = ((Vector3)(ref val2)).magnitude < 1f;
			if (!flag && !(Time.time > swarmUntil) && (!(InMode > 1f) || !(enemy.Rigidbody.notMovingTimer > 1.5f)))
			{
				return;
			}
			if (Plugin.FlowThrough.Value && !FitsHere(Stage == Stage.Sovereign))
			{
				Log("no room to reform there: flowing on");
				StartSqueeze(burst: false);
				nextAttack = Time.time + Mathf.Max(0f, Plugin.SwarmPause.Value);
				Enter(Mode.Chase);
				return;
			}
			Stop();
			if (Object.op_Implicit((Object)(object)target))
			{
				Face(((Component)target).transform.position);
				((Component)this).transform.rotation = facing;
			}
			crouching = Stage == Stage.Sovereign && !FitsHere(crouched: false);
			Enter(Mode.Reform);
			Send(Cue.Reform, Plugin.SwarmReform.Value);
			Log(flag ? "reforming" : "reforming short of the spot");
		}

		private void Reform()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0.2f, Plugin.SwarmReform.Value);
			Stop();
			if (Object.op_Implicit((Object)(object)target))
			{
				Face(((Component)target).transform.position);
			}
			if (InMode < num * 0.35f)
			{
				Protect(0.2f);
			}
			else if (!struck)
			{
				struck = true;
				enemy.StateStunned.OverrideDisable(0f);
			}
			if (InMode >= num)
			{
				nextAttack = Time.time + Mathf.Max(0f, Plugin.SwarmPause.Value);
				Recover(Mathf.Max(0.2f, Plugin.SwarmPause.Value));
			}
		}

		private void Grab()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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)
			//IL_008d: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0.1f, Plugin.GrabWarn.Value);
			Stop();
			Track(num * 0.8f);
			if (InMode < num)
			{
				return;
			}
			PlayerAvatar val = target;
			Vector3 val2 = ((Object.op_Implicit((Object)(object)val) && !val.isDisabled) ? (Chest(val) - ((Component)this).transform.position) : Vector3.zero);
			if (Object.op_Implicit((Object)(object)val) && !val.isDisabled && Object.op_Implicit((Object)(object)val.tumble))
			{
				Vector3 val3 = Flat(val2);
				if (((Vector3)(ref val3)).magnitude <= GrabReach + 0.3f && val2.y > -0.8f && val2.y < 2.6f)
				{
					val3 = Flat(val2);
					if (Vector3.Dot(((Vector3)(ref val3)).normalized, aim) > 0.2f && Reaches(((Component)this).transform.position + Vector3.up * 1f * S, val))
					{
						victim = val;
						victim.tumble.TumbleRequest(true, false);
						ReleaseGrabs(victim);
						float num2 = Mathf.Max(0.2f, Plugin.GrabHold.Value);
						SendHold(victim, on: true, num2 + 0.6f);
						Send(Cue.Hold, num2);
						Enter(Mode.Hold);
						Log("caught " + victim.playerName);
						return;
					}
				}
			}
			Send(Cue.Miss);
			Log("grab missed");
			Recover(0.8f);
		}

		private void Hold()
		{
			Stop();
			if (!Object.op_Implicit((Object)(object)victim))
			{
				Recover(0.5f);
			}
			else if (victim.isDisabled)
			{
				Log(victim.playerName + " died in its fist");
				DiedInFist(victim);
				Send(Cue.Miss);
				LetGo();
				Recover(0.8f);
			}
			else if (InMode >= Mathf.Max(0.2f, Plugin.GrabHold.Value))
			{
				Enter(Mode.Hurl);
				Send(Cue.Hurl);
			}
		}

		private void Hurl()
		{
			Stop();
			float num = body.Form.Hit("hurl", null, 0.55f);
			if (!released && InMode >= num)
			{
				released = true;
				Throw();
			}
			if (InMode >= num + 0.6f)
			{
				Recover(0.8f);
			}
		}

		private void Throw()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = victim;
			LetGo();
			if (!Object.op_Implicit((Object)(object)val) || val.isDisabled || !Object.op_Implicit((Object)(object)val.tumble))
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					DiedInFist(val);
				}
				return;
			}
			Vector3 val2 = OpenWay(((Component)val.tumble).transform.position);
			float num = Mathf.Max(2f, Plugin.GrabThrow.Value);
			Vector3 gravity = Physics.gravity;
			float num2 = Mathf.Sqrt(num * ((Vector3)(ref gravity)).magnitude / 0.87f) * 1.1f;
			PlayerTumble tumble = val.tumble;
			tumble.rb.velocity = Vector3.zero;
			tumble.rb.AddForce(val2 * num2 * 0.87f + Vector3.up * num2 * 0.5f, (ForceMode)2);
			tumble.TumbleTorque(-((Component)val).transform.right * 40f);
			tumble.TumbleOverrideTime(2f);
			val.FallDamageResetSet(0.3f);
			int num3 = Mathf.RoundToInt(Plugin.GrabLanding.Value);
			if (num3 > 0)
			{
				tumble.ImpactHurtSet(2f, num3);
			}
			Damage(val, Mathf.RoundToInt(Plugin.GrabDamage.Value));
			SendHit(val, ((Component)tumble).transform.position);
			if (val.isDisabled)
			{
				DiedInFist(val);
			}
			Log($"hurled {val.playerName} {num:0} m");
		}

		private Vector3 OpenWay(Vector3 from)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = ((Component)this).transform.forward;
			float num = -1f;
			int mask = LayerMask.GetMask(new string[2] { "Default", "PhysGrabObjectHinge" });
			float[] array = new float[7] { 0f, -35f, 35f, -70f, 70f, -100f, 100f };
			RaycastHit val4 = default(RaycastHit);
			foreach (float num2 in array)
			{
				Quaternion val = Quaternion.AngleAxis(num2, Vector3.up);
				Vector3 val2 = Flat(((Component)this).transform.forward);
				Vector3 val3 = val * ((Vector3)(ref val2)).normalized;
				float num3 = (Physics.SphereCast(from, 0.3f, val3, ref val4, 12f, mask, (QueryTriggerInteraction)1) ? ((RaycastHit)(ref val4)).distance : 12f);
				num3 -= Mathf.Abs(num2) * 0.01f;
				if (num3 > num)
				{
					num = num3;
					result = val3;
				}
			}
			return result;
		}

		private void FixedUpdate()
		{
			if (Net.IsHost)
			{
				Safe.Run("fist", Fist);
			}
		}

		private void Fist()
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			bool flag = !Object.op_Implicit((Object)(object)victim) || victim.isDisabled || !Object.op_Implicit((Object)(object)victim.tumble);
			bool flag2 = flag;
			if (!flag2)
			{
				Mode mode = this.mode;
				bool flag3 = mode - 14 <= Mode.Investigate;
				flag2 = !flag3;
			}
			if (!flag2)
			{
				PlayerTumble tumble = victim.tumble;
				if (!tumble.isTumbling)
				{
					tumble.TumbleRequest(true, false);
				}
				tumble.TumbleOverrideTime(0.5f);
				tumble.OverrideEnemyHurt(0.2f);
				victim.FallDamageResetSet(0.1f);
				tumble.physGrabObject.OverrideZeroGravity(0.1f);
				tumble.physGrabObject.OverrideMass(1f, 0.1f);
				tumble.physGrabObject.OverrideDrag(1.5f, 0.1f);
				tumble.physGrabObject.OverrideAngularDrag(2f, 0.1f);
				float num = ((tumble.physGrabObject.playerGrabbing.Count > 0) ? 0.5f : 1f);
				Vector3 val = body.PalmR + Vector3.down * 0.2f;
				Vector3 val2 = SemiFunc.PhysFollowPosition(((Component)tumble).transform.position, val, tumble.rb.velocity, 8f * num);
				tumble.rb.AddForce(val2 * (10f * Time.fixedDeltaTime * num), (ForceMode)1);
			}
		}

		internal void LetGo()
		{
			if (Object.op_Implicit((Object)(object)victim))
			{
				SendHold(victim, on: false, 0f);
				victim = null;
			}
		}

		private void DiedInFist(PlayerAvatar p)
		{
			deadInFist = p;
			headWatchUntil = Time.time + 5f;
		}

		private void HeadsOut()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)deadInFist))
			{
				return;
			}
			if (Time.time > headWatchUntil)
			{
				deadInFist = null;
				return;
			}
			PlayerDeathHead playerDeathHead = deadInFist.playerDeathHead;
			if (Object.op_Implicit((Object)(object)playerDeathHead) && playerDeathHead.triggered && ((Component)playerDeathHead).gameObject.activeInHierarchy && Object.op_Implicit((Object)(object)playerDeathHead.physGrabObject))
			{
				Vector3 centerPoint = playerDeathHead.physGrabObject.centerPoint;
				bool flag = centerPoint.y > feet.position.y + 0.9f;
				Vector3 val = Flat(centerPoint - ((Component)body).transform.position);
				bool flag2 = ((Vector3)(ref val)).magnitude < 0.8f * S;
				if (flag || flag2)
				{
					Vector3 onMesh = feet.position + ((Component)this).transform.forward * 1.8f * S;
					Nav.Sample(onMesh, 2f, out onMesh);
					playerDeathHead.physGrabObject.Teleport(onMesh + Vector3.up * 0.4f, Quaternion.identity);
					Log("moved " + deadInFist.playerName + "'s head out of its fist");
				}
				deadInFist = null;
			}
		}

		private void HitEnemies(Vector3 at, float radius, float damage, HashSet<Enemy> already)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (damage <= 0f)
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(at, radius, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) | LayerMask.GetMask(new string[1] { "Enemy" }), (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				EnemyRigidbody componentInParent = ((Component)val).GetComponentInParent<EnemyRigidbody>();
				Enemy val2 = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.enemy : ((Component)val).GetComponentInParent<Enemy>());
				if (Object.op_Implicit((Object)(object)val2) && !((Object)(object)val2 == (Object)(object)enemy) && val2.HasHealth && already.Add(val2))
				{
					val2.Health.Hurt(Mathf.RoundToInt(damage), aim);
					Log("hit a " + val2.EnemyParent?.enemyName);
				}
			}
		}

		private void Shove(Vector3 at, Vector3 dir, float force, float radius)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			HashSet<PhysGrabObject> hashSet = new HashSet<PhysGrabObject>();
			Collider[] array = Physics.OverlapSphere(at, radius, LayerMask.op_Implicit(SemiFunc.LayerMaskGetPhysGrabObject()), (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				PhysGrabObject componentInParent = ((Component)val).GetComponentInParent<PhysGrabObject>();
				if (Object.op_Implicit((Object)(object)componentInParent) && hashSet.Add(componentInParent) && Object.op_Implicit((Object)(object)componentInParent.rb) && !componentInParent.rb.isKinematic && !Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponent<EnemyRigidbody>()) && !Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponent<PlayerTumble>()) && !Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponent<PhysGrabHinge>()))
				{
					Feed.Touched(componentInParent);
					if (force > 0f)
					{
						Rigidbody rb = componentInParent.rb;
						Vector3 val2 = dir + Vector3.up * 0.3f;
						rb.AddForce(((Vector3)(ref val2)).normalized * force, (ForceMode)2);
					}
				}
			}
		}

		private void Awake()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			enemy = ((Component)this).GetComponent<Enemy>();
			view = ((Component)this).GetComponent<PhotonView>();
			parent = ((Component)this).GetComponentInParent<EnemyParent>(true);
			Transform val = ((Component)this).transform.parent.Find("Rigidbody");
			feet = val.Find("Feet Transform");
			Clips.Load();
			body = Body.Create(((Component)this).transform, val);
			body.Enemy = enemy;
			body.Brain = this;
			sight = new Sight(Object.op_Implicit((Object)(object)parent) ? ((Component)parent).transform : ((Component)this).transform.parent);
			facing = ((Component)this).transform.rotation;
			((Component)this).GetComponent<EnemyStateSpawn>().OnSpawn.AddListener(new UnityAction(OnSpawn));
			EnemyHealth component = ((Component)this).GetComponent<EnemyHealth>();
			component.onHurt.AddListener(new UnityAction(OnHurt));
			component.onDeath.AddListener(new UnityAction(OnDeath));
			EnemyStateInvestigate ears = ((Component)this).GetComponent<EnemyStateInvestigate>();
			if (ears != null)
			{
				ears.onInvestigateTriggered.AddListener((UnityAction)delegate
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					Heard(ears.onInvestigateTriggeredPosition);
				});
			}
		}

		private void OnSpawn()
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			absorbed = 0;
			streamedTarget = Stage.Crawler;
			streamedEase = 1f;
			healthShare = byte.MaxValue;
			looking = false;
			lockedOn = false;
			squeezing = (crouching = false);
			escape = null;
			pausedUntil = 0f;
			spireField = null;
			mode = Mode.Roam;
			body.Reset();
			if (Net.IsHost)
			{
				SemiFunc.EnemySpawn(enemy);
				enemy.Health.health = Growth.Health(Stage.Crawler);
				enemy.Health.healthCurrent = enemy.Health.health;
				target = null;
				noise = (hunger = null);
				wasStunned = false;
				hasGoal = false;
				LetGo();
				facing = ((Component)this).transform.rotation;
				tipOffAt = Time.time + 10f;
				nextIdle = Time.time + Random.Range(8f, 20f);
				nextAttack = Time.time + 2f;
				Enter(Mode.Roam);
				spawns++;
				string text = (debugPending ? "by the debug key" : "naturally");
				debugPending = false;
				Log((spawns == 1) ? ("spawned " + text) : $"spawned {text} (back again, #{spawns} this level)");
			}
		}

		private void OnHurt()
		{
			body.Hurt();
			if (!body.Swarming)
			{
				body.Say(Voice.Hurt, Body.Pick(Voice.Hurt));
			}
		}

		private void OnDeath()
		{
			Safe.Run("death", body.Died);
			if (!Net.IsHost)
			{
				return;
			}
			Log($"killed as a {Stage} (${absorbed} eaten)");
			LetGo();
			squeezing = false;
			spireField = null;
			Safe.Run("orb", delegate
			{
				float scale;
				GameObject val = Orb.Spawn(enemy, parent, Target, absorbed, out scale);
				if (Object.op_Implicit((Object)(object)val) && scale != 1f && SemiFunc.IsMultiplayer())
				{
					PhotonView component = val.GetComponent<PhotonView>();
					if (component != null)
					{
						view.RPC("OrbRPC", (RpcTarget)1, new object[2] { component.ViewID, scale });
					}
				}
			});
			absorbed = 0;
			target = null;
			parent.Despawn();
		}

		private void Heard(Vector3 position)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			bool flag = !Net.IsHost;
			bool flag2 = flag;
			if (!flag2)
			{
				Mode mode = this.mode;
				bool flag3 = ((mode <= Mode.Hungry || mode == Mode.Search) ? true : false);
				flag2 = !flag3;
			}
			if (!flag2)
			{
				noise = position;
			}
		}

		internal void Eat(Vector3 point, int dollars, int key, bool destroyed, string what)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			Stage stage = Target;
			absorbed = Mathf.Min(absorbed + dollars, 10000000);
			SendFed(point, dollars, key, destroyed);
			float num = Vector3.Distance(point, ((Component)this).transform.position);
			Log(string.Format("ate ${0} from {1}{2}, {3:0} m away: ${4} now", dollars, what, destroyed ? " (smashed)" : "", num, absorbed));
			Stage stage2 = Target;
			if (stage2 != stage)
			{
				Restage(stage, stage2);
				Log($"has eaten enough to be a {stage2}");
			}
			bool flag = num <= Plugin.HearFeed.Value;
			bool flag2 = flag;
			if (flag2)
			{
				Mode mode = this.mode;
				bool flag3 = ((mode <= Mode.Hungry || mode == Mode.Search) ? true : false);
				flag2 = flag3;
			}
			if (flag2)
			{
				hunger = point;
			}
		}

		internal void Starve()
		{
			Stage before = Target;
			absorbed = 0;
			Restage(before, Stage.Crawler);
			Send(Cue.Starve);
			Log("starved back to a Crawler");
		}

		private void Restage(Stage before, Stage after)
		{
			EnemyHealth health = enemy.Health;
			int num = Growth.Health(before);
			int num2 = (health.health = Growth.Health(after));
			health.healthCurrent = Mathf.Clamp(health.healthCurrent + (num2 - num), 1, num2);
		}

		private void Update()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (Net.IsHost)
			{
				if (Object.op_Implicit((Object)(object)LevelGenerator.Instance) && LevelGenerator.Instance.Generated)
				{
					Safe.Run("brain", Think);
				}
			}
			else
			{
				body.LookAt = (looking ? new Vector3?(lookAt) : ((Vector3?)null));
			}
		}

		private void Enter(Mode m)
		{
			if (mode != m)
			{
				hasGoal = false;
			}
			mode = m;
			modeAt = Time.time;
		}

		private void Think()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: 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_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			EnemyHealth health = enemy.Health;
			healthShare = (byte)Mathf.Clamp(Mathf.RoundToInt(255f * (float)health.healthCurrent / Mathf.Max(1f, (float)health.health)), 0, 255);
			if ((int)enemy.CurrentState == 11)
			{
				LetGo();
				target = null;
				parent.Despawn();
				return;
			}
			HeadsOut();
			SpiresTick();
			if (Time.time >= nextMess)
			{
				nextMess = Time.time + 0.2f;
				Mess();
			}
			if (enemy.IsStunned())
			{
				if (!wasStunned)
				{
					wasStunned = true;
					squeezing = (crouching = false);
					escape = null;
					Log("stunned");
					if (Object.op_Implicit((Object)(object)victim))
					{
						Send(Cue.Miss);
					}
					LetGo();
				}
				enemy.NavMeshAgent.Disable(0.1f);
				((Component)this).transform.position = feet.position;
				looking = false;
				lockedOn = false;
				body.LookAt = null;
				return;
			}
			if (wasStunned)
			{
				wasStunned = false;
				enemy.NavMeshAgent.Warp(feet.position, false);
				enemy.NavMeshAgent.ResetPath();
				hasGoal = false;
				Recover(1f);
			}
			if (Stage == Stage.Crawler && mode != Mode.Held && Grabbers().Count > 0)
			{
				StartHeld();
			}
			if (Target != Stage && Settled && Time.time >= pausedUntil)
			{
				StartGrow();
			}
			if (Time.time < pausedUntil)
			{
				Stop();
			}
			else if (!Escaping())
			{
				switch (mode)
				{
				case Mode.Stalk:
					Stalk();
					break;
				case Mode.Flee:
					Flee();
					break;
				case Mode.Chase:
					Chase();
					break;
				case Mode.Bite:
					Bite();
					break;
				case Mode.Swipe:
					Swipe();
					break;
				case Mode.Volley:
					VolleyMode();
					break;
				case Mode.Slam:
					Slam();
					break;
				case Mode.Shriek:
					Shriek();
					break;
				case Mode.Swarm:
					SwarmMode();
					break;
				case Mode.Reform:
					Reform();
					break;
				case Mode.Grab:
					Grab();
					break;
				case Mode.Hold:
					Hold();
					break;
				case Mode.Hurl:
					Hurl();
					break;
				case Mode.Held:
					Held();
					break;
				case Mode.Grow:
					Growing();
					break;
				case Mode.Recover:
					Recovering();
					break;
				case Mode.Search:
					Search();
					break;
				case Mode.Spires:
					SpiresMode();
					break;
				default:
					Hunt();
					break;
				}
			}
			Fit();
			bool flag;
			switch (mode)
			{
			case Mode.Stalk:
			case Mode.Chase:
			case Mode.Bite:
			case Mode.Swipe:
			case Mode.Volley:
			case Mode.Slam:
			case Mode.Shriek:
			case Mode.Swarm:
			case Mode.Reform:
			case Mode.Grab:
			case Mode.Hold:
			case Mode.Hurl:
			case Mode.Recover:
			case Mode.Spires:
				flag = true;
				break;
			default:
				flag = false;
				break;
			}
			bool flag2 = flag;
			lockedOn = flag2 && Object.op_Implicit((Object)(object)target) && !target.isDisabled;
			looking = lockedOn && mode != Mode.Swarm && !squeezing;
			lookAt = ((!looking) ? Vector3.zero : ((Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.tumble)) ? ((Component)victim.tumble).transform.position : PlayerEyes(target)));
			body.LookAt = (looking ? new Vector3?(lookAt) : ((Vector3?)null));
			HaloTick();
			Turn();
			Idle();
		}

		private void Idle()
		{
			if (!(Time.time < nextIdle))
			{
				nextIdle = Time.time + Mathf.Max(5f, Plugin.IdleSeconds.Value) * Random.Range(0.7f, 1.3f);
				Mode mode = this.mode;
				if ((mode <= Mode.Stalk || mode - 17 <= Mode.Investigate) ? true : false)
				{
					Say(Voice.Idle);
				}
			}
		}

		private void Hunt()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && target.isDisabled)
			{
				target = null;
			}
			if (mode != Mode.Leave)
			{
				List<PlayerAvatar> list = sight.Look(body.Eyes, ((Component)body).transform.forward);
				if (list.Count > 0)
				{
					target = list[0];
					Seen();
					string playerName = target.playerName;
					Vector3 val = Flat(((Component)target).transform.position - ((Component)this).transform.position);
					Log($"spotted {playerName}, {((Vector3)(ref val)).magnitude:0} m");
					StartHunt(spotted: true);
					return;
				}
			}
			if (mode == Mode.Leave || SemiFunc.EnemyForceLeave(enemy))
			{
				Leave();
			}
			else if (hunger.HasValue)
			{
				if (mode != Mode.Hungry)
				{
					Enter(Mode.Hungry);
				}
				GoTo(hunger.Value, Growth.Roam(Stage) * 1.3f);
				if (Arrived(1.2f) || Stuck() || InMode > 25f)
				{
					hunger = null;
					StartSearch();
				}
			}
			else if (noise.HasValue)
			{
				if (mode != Mode.Investigate)
				{
					Enter(Mode.Investigate);
				}
				GoTo(noise.Value, Growth.Roam(Stage) * 1.15f);
				if (Arrived(1.5f) || Stuck() || InMode > 25f)
				{
					noise = null;
				}
			}
			else
			{
				Roam();
			}
		}

		private void StartHunt(bool spotted)
		{
			if (!Object.op_Implicit((Object)(object)target) || target.isDisabled)
			{
				StartSearch();
				return;
			}
			chaseStarted = Time.time;
			if (Stage == Stage.Crawler)
			{
				Enter(Mode.Stalk);
				return;
			}
			if (spotted)
			{
				Say(Voice.Combat);
			}
			Enter(Mode.Chase);
			Log("after " + target.playerName);
		}

		private void StartSearch()
		{
			Enter(Mode.Search);
			lookAroundUntil = 0f;
		}

		private bool Chasing(out bool seeing, out float d)
		{
			//IL_0046: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			seeing = false;
			d = 0f;
			if (!Object.op_Implicit((Object)(object)target) || target.isDisabled)
			{
				target = null;
				StartSearch();
				return false;
			}
			seeing = sight.Visible(target, body.Eyes, Plugin.VisionRange.Value * 1.5f);
			if (seeing)
			{
				Seen();
			}
			Vector3 val = Flat(((Component)target).transform.position - ((Component)this).transform.position);
			d = ((Vector3)(ref val)).magnitude;
			if (Time.time - lastSeenAt > Plugin.LoseSeconds.Value || Stuck())
			{
				Log("lost " + target.playerName);
				StartSearch();
				return false;
			}
			if (Time.time - chaseStarted > Plugin.ChaseSeconds.Value)
			{
				Log("gave up on " + target.playerName);
				target = null;
				StartSearch();
				return false;
			}
			return true;
		}

		private void Chase()
		{
			//IL_0096: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (Stage == Stage.Crawler)
			{
				Enter(Mode.Stalk);
			}
			else
			{
				if (!Chasing(out var seeing, out var d))
				{
					return;
				}
				if (seeing && Time.time >= nextThink)
				{
					nextThink = Time.time + 0.5f;
					if (TryAttack(d))
					{
						return;
					}
				}
				if (d < Mathf.Max(body.Form.BodyLength * body.Ease * 0.5f + 0.5f, SwipeReach * 0.6f))
				{
					Stop();
					Face(((Component)target).transform.position);
				}
				else
				{
					GoTo((Time.time - lastSeenAt < 0.5f) ? ((Component)target).transform.position : lastSeen, Growth.Chase(Stage));
				}
			}
		}

		private void Stalk()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (Stage != Stage.Crawler)
			{
				Enter(Mode.Chase);
			}
			else
			{
				if (!Chasing(out var seeing, out var d))
				{
					return;
				}
				if (Watched(target))
				{
					StartFlee(2f);
					return;
				}
				if (seeing && !squeezing && d <= Plugin.BiteRange.Value && Time.time >= nextBite && Time.time >= nextAttack && Mathf.Abs(((Component)target).transform.position.y - ((Component)this).transform.position.y) < 1f)
				{
					Use(Attack.Bite, forced: false);
					return;
				}
				Vector3 val = LookOf(target);
				Vector3 onMesh = ((Component)target).transform.position - val * 1.2f;
				if (d > 4f || !Nav.Sample(onMesh, 1f, out onMesh))
				{
					onMesh = ((Time.time - lastSeenAt < 0.5f) ? ((Component)target).transform.position : lastSeen);
				}
				GoTo(onMesh, Growth.Chase(Stage));
			}
		}

		private void StartFlee(float seconds)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)target))
			{
				StartSearch();
				return;
			}
			Enter(Mode.Flee);
			fleeUntil = Time.time + seconds;
			Vector3 val = Flat(((Component)this).transform.position - ((Component)target).transform.position);
			Vector3 away = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref away)).sqrMagnitude < 0.01f)
			{
				away = -((Component)this).transform.forward;
			}
			LevelPoint val2 = (SemiFunc.LevelPointsGetAll() ?? new List<LevelPoint>()).Where((LevelPoint p) => Object.op_Implicit((Object)(object)p) && !p.Truck).Where(delegate(LevelPoint p)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: 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_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: 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_004b: 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_0054: Unknown result type (might be due to invalid IL or missing references)
				Vector3 v = ((Component)p).transform.position - ((Component)target).transform.position;
				Vector3 val3 = Flat(v);
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (magnitude > 6f && magnitude < 16f)
				{
					val3 = Flat(v);
					return Vector3.Dot(((Vector3)(ref val3)).normalized, away) > 0.2f;
				}
				return false;
			}).OrderBy(delegate(LevelPoint p)
			{
				//IL_0006: 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)
				//IL_001b: 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)
				Vector3 val3 = ((Component)p).transform.position - ((Component)this).transform.position;
				return ((Vector3)(ref val3)).sqrMagnitude;
			})
				.FirstOrDefault();
			Vector3 onMesh = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).transform.position : (((Component)this).transform.position + away * 6f));
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Nav.Sample(onMesh, 3f, out onMesh);
			}
			GoTo(onMesh, Growth.Chase(Stage) * 1.1f);
			Log("scared off by " + target.playerName);
		}

		private void Flee()
		{
			//IL_0002: 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)
			GoTo(goal, Growth.Chase(Stage) * 1.1f);
			if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && sight.Visible(target, body.Eyes, Plugin.VisionRange.Value * 1.5f))
			{
				Seen();
			}
			if ((Time.time >= fleeUntil && (!Object.op_Implicit((Object)(object)target) || !Watched(target) || Arrived(1f))) || InMode > 7f || Stuck())
			{
				if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && Time.time - lastSeenAt < Plugin.LoseSeconds.Value)
				{
					Enter((Stage == Stage.Crawler) ? Mode.Stalk : Mode.Chase);
				}
				else
				{
					StartSearch();
				}
			}
		}

		private bool Watched(PlayerAvatar p)
		{
			//IL_001b: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)p) || p.isDisabled || p.isTumbling)
			{
				return false;
			}
			Vector3 val = PlayerEyes(p);
			Vector3 val2 = body.Chest - val;
			if (((Vector3)(ref val2)).magnitude > Plugin.FleeRange.Value)
			{
				return false;
			}
			Vector3 val3 = (Object.op_Implicit((Object)(object)p.localCamera) ? ((Component)p.localCamera).transform.forward : ((Component)p).transform.forward);
			if (Vector3.Angle(val3, val2) <= Plugin.FleeAngle.Value)
			{
				return sight.Visible(p, body.Eyes, Plugin.FleeRange.Value + 1f);
			}
			return false;
		}

		private static Vector3 LookOf(PlayerAvatar p)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Flat(Object.op_Implicit((Object)(object)p.localCamera) ? ((Component)p.localCamera).transform.forward : ((Component)p).transform.forward);
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private void StartGrow()
		{
			Mode mode = this.mode;
			bool flag = ((mode <= Mode.Hungry || mode - 17 <= Mode.Investigate) ? true : false);
			afterGrow = ((!flag) ? Mode.Chase : Mode.Roam);
			growTo = Target;
			Body.GrowTimes(Stage, growTo, out growBurst, out growReformAt, out growReformFor);
			growReformed = -1f;
			crouching = false;
			LetGo();
			Stop();
			Enter(Mode.Grow);
			Send(Cue.Grow, (int)growTo);
			Log(string.Format("{0} from a {1} into a {2}", ((int)growTo > (int)Stage) ? "growing" : "shrinking", Stage, growTo));
		}

		private void Growing()
		{
			Stop();
			enemy.StateStunned.OverrideDisable(0.3f);
			float inMode = InMode;
			if (inMode >= growBurst - 0.05f && (growReformed < 0f || inMode < growReformed + growReformFor * 0.35f))
			{
				Protect(0.3f);
				enemy.Rigidbody.GrabRelease(true, 0.1f);
			}
			if (inMode < growReformAt)
			{
				return;
			}
			if (growReformed < 0f)
			{
				if (Plugin.FlowThrough.Value && !FitsHere(Stage == Stage.Sovereign))
				{
					Log($"no room for a {Stage} here: flowing on as the swarm");
					StartSqueeze(burst: false);
					Resume();
				}
				else
				{
					growReformed = inMode;
					crouching = Stage == Stage.Sovereign && !FitsHere(crouched: false);
					Send(Cue.Reform, growReformFor);
				}
			}
			else if (inMode >= growReformed + growReformFor + 0.1f)
			{
				Resume();
			}
		}

		private void Resume()
		{
			if (afterGrow == Mode.Chase && Object.op_Implicit((Object)(object)target) && !target.isDisabled)
			{
				StartHunt(spotted: false);
			}
			else
			{
				Enter(Mode.Roam);
			}
		}

		private bool HeadRoom(params string[] clips)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Form form = body.Form;
			float num = 0f;
			foreach (string clip in clips)
			{
				num = Mathf.Max(num, form.Top(clip));
			}
			if (!(num <= form.Height * 1.02f))
			{
				return Room.At(feet.position, ((Component)this).transform.forward, 0.6f).x >= num * body.Ease + Plugin.AttackHeadRoom.Value;
			}
			return true;
		}

		private List<PlayerAvatar> Grabbers()
		{
			PhysGrabObject val = (Object.op_Implicit((Object)(object)enemy.Rigidbody) ? enemy.Rigidbody.physGrabObject : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return new List<PlayerAvatar>();
			}
			return (from g in val.playerGrabbing
				where Object.op_Implicit((Object)(object)g) && Object.op_Implicit((Object)(object)g.playerAvatar)
				select g.playerAvatar).Distinct().ToList();
		}

		private void StartHeld()
		{
			LetGo();
			Stop();
			Enter(Mode.Held);
			nextNip = Time.time + 0.6f;
			Send(Cue.Wriggle, 30f);
			Log("picked up: wriggling");
		}

		private void Held()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			Stop();
			List<PlayerAvatar> list = Grabbers();
			if (list.Count == 0 || Stage != Stage.Crawler)
			{
				Send(Cue.Settle);
				target = (PlayerAvatar)(Object.op_Implicit((Object)(object)target) ? ((object)target) : ((object)list.FirstOrDefault()));
				StartFlee(2f);
				return;
			}
			target = list[0];
			Seen();
			chaseStarted = Time.time;
			if (!(Time.time >= nextNip))
			{
				return;
			}
			nextNip = Time.time + 1f;
			foreach (PlayerAvatar item in list)
			{
				Damage(item, Mathf.Max(1, Mathf.RoundToInt(Plugin.HeldBite.Value)));
				SendHit(item, Chest(item));
			}
		}

		private void Recover(float seconds)
		{
			Enter(Mode.Recover);
			recoverFor = seconds;
		}

		private void Recovering()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Stop();
			if (Object.op_Implicit((Object)(object)target))
			{
				Face(((Component)target).transform.position);
			}
			if (!(InMode < recoverFor))
			{
				if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && Time.time - lastSeenAt < Plugin.LoseSeconds.Value)
				{
					StartHunt(spotted: false);
				}
				else
				{
					StartSearch();
				}
			}
		}

		private void Search()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)target) && !target.isDisabled && sight.Visible(target, body.Eyes, Plugin.VisionRange.Value))
			{
				Seen();
				StartHunt(spotted: false);
				return;
			}
			List<PlayerAvatar> list = sight.Look(body.Eyes, ((Component)body).transform.forward);
			if (list.Count > 0)
			{
				target = list[0];
				Seen();
				StartHunt(spotted: true);
				return;
			}
			if (hunger.HasValue || noise.HasValue)
			{
				target = null;
				Enter(Mode.Roam);
				return;
			}
			if (Object.op_Implicit((Object)(object)target) && !Arrived(1f) && !Stuck() && InMode < 10f)
			{
				GoTo(lastSeen, Growth.Chase(Stage) * 0.9f);
				return;
			}
			Stop();
			if (lookAroundUntil == 0f)
			{
				lookAroundUntil = Time.time + Plugin.SearchSeconds.Value;
			}
			facing *= Quaternion.Euler(0f, 50f * Time.deltaTime, 0f);
			if (Time.time > lookAroundUntil)
			{
				target = null;
				Enter(Mode.Roam);
				Log("gave up looking");
			}
		}

		private void Roam()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if (mode != Mode.Roam)
			{
				Enter(Mode.Roam);
			}
			if (SemiFunc.EnemySpawnIdlePause())
			{
				Stop();
				return;
			}
			if (hasGoal && !Arrived(1.5f) && !Stuck())
			{
				GoTo(goal, Growth.Roam(Stage));
				return;
			}
			List<LevelPoint> list = (SemiFunc.LevelPointsGetAll() ?? new List<LevelPoint>()).Where((LevelPoint p) => Object.op_Implicit((Object)(object)p) && !p.Truck).ToList();
			if (list.Count == 0)
			{
				return;
			}
			Vector3 position;
			if (Time.time >= tipOffAt)
			{
				PlayerAvatar near = Nearest();
				if (near != null)
				{
					tipOffAt = Time.time + Plugin.TipOffSeconds.Value;
					position = ((Component)(from _ in list.OrderBy(delegate(LevelPoint p)
						{
							//IL_0006: 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)
							//IL_001b: 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)
							Vector3 val = ((Component)p).transform.position - ((Component)near).transform.position;
							return ((Vector3)(ref val)).sqrMagnitude;
						}).Take(4)
						orderby Random.value
						select _).First()).transform.position;
					Log("drifting toward " + near.playerName + "'s area");
					goto IL_0166;
				}
			}
			position = ((Component)list[Random.Range(0, list.Count)]).transform.position;
			goto IL_0166;
			IL_0166:
			hasGoal = false;
			GoTo(position, Growth.Roam(Stage));
		}

		private void Leave()
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (mode != Mode.Leave)
			{
				LevelPoint val = SemiFunc.LevelPointGetPlayerDistance(((Component)this).transform.position, 30f, 50f, false) ?? SemiFunc.LevelPointGetFurthestFromPlayer(((Component)this).transform.position, 5f);
				if (!Object.op_Implicit((Object)(object)val))
				{
					Roam();
					return;
				}
				Enter(Mode.Leave);
				noise = (hunger = null);
				leaveUntil = Time.time + 25f;
				SemiFunc.EnemyLeaveStart(enemy);
				GoTo(((Component)val).transform.position, Growth.Roam(Stage) * 1.3f);
				Log("leaving");
			}
			else
			{
				GoTo(goal, Growth.Roam(Stage) * 1.3f);
				if (Arrived(1.5f) || Stuck() || Time.time > leaveUntil)
				{
					Enter(Mode.Roam);
				}
			}
		}

		private void Seen()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			lastSeen = ((Component)target).transform.position;
			lastSeenAt = Time.time;
		}

		internal void Damage(PlayerAvatar p, int damage)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)p) && !p.isDisabled && damage > 0)
			{
				if (Object.op_Implicit((Object)(object)p.physGrabber) && Object.op_Implicit((Object)(object)p.physGrabber.grabbedPhysGrabObject))
				{
					Feed.Touched(p.physGrabber.grabbedPhysGrabObject);
				}
				hitRecently[p] = Time.time + 3f;
				int num = SemiFunc.EnemyGetIndex(enemy);
				if (p.isLocal)
				{
					p.playerHealth.Hurt(damage, false, num, false);
				}
				else
				{
					p.playerHealth.HurtOther(damage, Vector3.zero, false, num, false);
				}
			}
		}

		private void Mess()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)enemy.CenterTransform))
			{
				Feed.TouchAround(enemy.CenterTransform.position, 1.1f * Mathf.Max(0.2f, body.Scale), loose: true);
			}
			foreach (PlayerAvatar item in hitRecently.Keys.ToList())
			{
				if (!Object.op_Implicit((Object)(object)item) || item.isDisabled || Time.time > hitRecently[item])
				{
					hitRecently.Remove(item);
				}
				else
				{
					Feed.TouchAround(((Component)item).transform.position + Vector3.up * 0.5f, 1.2f, loose: false);
				}
			}
		}

		private static void Knock(PlayerAvatar p, Vector3 force, float seconds)
		{
			//IL_0029: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)p.tumble) && !p.isDisabled)
			{
				p.tumble.TumbleRequest(true, false);
				p.tumble.TumbleForce(force);
				p.tumble.TumbleTorque(-((Component)p).transform.right * 20f);
				p.tumble.TumbleOverrideTime(seconds);
			}
		}

		private static void Release(PhysGrabber g, PhysGrabObject o, float seconds)
		{
			if (Object.op_Implicit((Object)(object)g) && Object.op_Implicit((Object)(object)o) && Object.op_Implicit((Object)(object)o.photonView))
			{
				if (SemiFunc.IsMultiplayer())
				{
					g.photonView.RPC("ReleaseObjectRPC", (RpcTarget)0, new object[3]
					{
						false,
						seconds,
						o.photonView.ViewID
					});
				}
				else
				{
					g.ReleaseObject(o.photonView.ViewID, seconds);
				}
			}
		}

		private static void ReleaseGrabs(PlayerAvatar p)
		{
			PhysGrabber physGrabber = p.physGrabber;
			if (Object.op_Implicit((Object)(object)physGrabber) && physGrabber.grabbed && Object.op_Implicit((Object)(object)physGrabber.grabbedPhysGrabObject))
			{
				Release(physGrabber, physGrabber.grabbedPhysGrabObject, 0.5f);
			}
		}

		private bool Reaches(Vector3 from, PlayerAvatar p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or m