Decompiled source of trepobmodsfix v0.2.2

plugins/trepobmodsfix.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice;
using Photon.Voice.Unity;
using REPOLib.Modules;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Rendering;
using UnityEngine.UI;
using trepobmodsfix.Fixes;
using trepobmodsfix.Graffiti;
using trepobmodsfix.Graffiti.Logic;
using trepobmodsfix.Mimic;
using trepobmodsfix.Mimic.Logic;
using trepobmodsfix.Taxman;
using trepobmodsfix.Taxman.Logic;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 trepobmodsfix
{
	[BepInPlugin("FabioAraujo.trepobmodsfix", "trepobmodsfix", "0.2.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private readonly Harmony _harmony = new Harmony("FabioAraujo.trepobmodsfix");

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			MimicConfig.Bind(((BaseUnityPlugin)this).Config);
			RepoLibPatchFix.Apply(_harmony);
			_harmony.PatchAll();
			((Component)this).gameObject.AddComponent<GraffitiDirector>();
			if (MimicSettings.Current.Enabled)
			{
				((Component)this).gameObject.AddComponent<TaxmanGreeting>();
			}
			VoiceCapture.Install(_harmony);
			MimicDirector.Create(((Component)this).gameObject, _harmony);
			Logger.LogInfo((object)"trepobmodsfix 0.2.2 loaded");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "FabioAraujo.trepobmodsfix";

		public const string PLUGIN_NAME = "trepobmodsfix";

		public const string PLUGIN_VERSION = "0.2.2";
	}
}
namespace trepobmodsfix.Valuables
{
	internal sealed class MeshAsset
	{
		public Mesh Mesh { get; }

		public Bounds[] Boxes { get; }

		private MeshAsset(Mesh mesh, Bounds[] boxes)
		{
			Mesh = mesh;
			Boxes = boxes;
		}

		public static MeshAsset Load(string resourceName)
		{
			//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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00e2: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			using Stream input = typeof(MeshAsset).Assembly.GetManifestResourceStream(resourceName) ?? throw new FileNotFoundException("Embedded resource '" + resourceName + "' not found");
			using BinaryReader binaryReader = new BinaryReader(input);
			int num = binaryReader.ReadInt32();
			int num2 = binaryReader.ReadInt32();
			int num3 = binaryReader.ReadInt32();
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = ReadVector3(binaryReader);
				array2[i] = ReadVector3(binaryReader);
			}
			int[] array3 = new int[num2];
			for (int j = 0; j < num2; j++)
			{
				array3[j] = binaryReader.ReadInt32();
			}
			Bounds[] array4 = (Bounds[])(object)new Bounds[num3];
			for (int k = 0; k < num3; k++)
			{
				array4[k] = new Bounds(ReadVector3(binaryReader), ReadVector3(binaryReader));
			}
			Mesh val = new Mesh
			{
				name = Path.GetFileNameWithoutExtension(resourceName),
				indexFormat = (IndexFormat)(num > 65535),
				vertices = array,
				normals = array2,
				triangles = array3,
				hideFlags = (HideFlags)32
			};
			val.RecalculateBounds();
			return new MeshAsset(val, array4);
		}

		private static Vector3 ReadVector3(BinaryReader reader)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}
	}
	internal static class RootSpace
	{
		public static Bounds Bounds(Transform root, IEnumerable<MeshFilter> filters)
		{
			//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_0009: 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_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_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_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)
			//IL_00c0: 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)
			Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix;
			Bounds result = default(Bounds);
			bool flag = true;
			foreach (MeshFilter filter in filters)
			{
				if ((Object)(object)filter == (Object)null || (Object)(object)filter.sharedMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = filter.sharedMesh.bounds;
				Matrix4x4 val = worldToLocalMatrix * ((Component)filter).transform.localToWorldMatrix;
				for (int i = 0; i < 8; i++)
				{
					Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1))));
					Vector3 val3 = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val2);
					if (flag)
					{
						result = new Bounds(val3, Vector3.zero);
						flag = false;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val3);
					}
				}
			}
			return result;
		}

		public static void Place(Transform t, Transform root, Vector3 localPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_002b: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			t.position = root.TransformPoint(localPosition);
			t.rotation = root.rotation;
			Vector3 lossyScale = t.parent.lossyScale;
			Vector3 lossyScale2 = root.lossyScale;
			t.localScale = new Vector3(lossyScale2.x / lossyScale.x, lossyScale2.y / lossyScale.y, lossyScale2.z / lossyScale.z);
		}
	}
	[HarmonyPatch(typeof(RunManager), "Awake")]
	internal static class TrophyValuable
	{
		private const string TemplatePath = "Valuables/07 Very Tall/Valuable Manor Golden Statue";

		private const string PrefabName = "Valuable TBParty Trophy";

		private const string MeshResource = "tbp.mesh";

		private const float Mass = 6f;

		private const float ValueMin = 30000f;

		private const float ValueMax = 54000f;

		private static readonly Color Gold = new Color(1f, 0.72f, 0.25f);

		private const float GoldMetallic = 0.85f;

		private const float GoldSmoothness = 0.65f;

		internal static PrefabRef? Prefab { get; private set; }

		private static void Postfix()
		{
			if (Prefab == null)
			{
				GameObject val = Resources.Load<GameObject>("Valuables/07 Very Tall/Valuable Manor Golden Statue");
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Logger.LogError((object)"Template 'Valuables/07 Very Tall/Valuable Manor Golden Statue' not found. The game may have renamed it; the trophy will not spawn.");
					return;
				}
				Prefab = Valuables.RegisterValuable(Build(val, MeshAsset.Load("tbp.mesh")), new List<string> { "Valuables - Generic" });
				Plugin.Logger.LogInfo((object)((Prefab != null) ? "Registered 'Valuable TBParty Trophy'" : "REPOLib refused 'Valuable TBParty Trophy'"));
			}
		}

		private static GameObject Build(GameObject template, MeshAsset asset)
		{
			//IL_0005: 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_0013: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0121: 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_0198: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("trepobmodsfix Prefabs")
			{
				hideFlags = (HideFlags)61
			};
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			GameObject val2 = Object.Instantiate<GameObject>(template, val.transform);
			((Object)val2).name = "Valuable TBParty Trophy";
			Transform transform = val2.transform;
			MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true);
			Bounds val3 = RootSpace.Bounds(transform, componentsInChildren.Select((MeshRenderer r) => ((Component)r).GetComponent<MeshFilter>()));
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).center.z);
			MeshRenderer val5 = componentsInChildren[0];
			foreach (MeshRenderer item in componentsInChildren.Skip(1))
			{
				Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
			}
			RootSpace.Place(((Component)val5).transform, transform, val4);
			((Component)val5).GetComponent<MeshFilter>().sharedMesh = asset.Mesh;
			((Renderer)val5).sharedMaterials = (Material[])(object)new Material[1] { GoldMaterial(((Renderer)val5).sharedMaterial) };
			ReplaceColliders(val2, transform, asset.Boxes, val4);
			ValuableObject component = val2.GetComponent<ValuableObject>();
			component.volumeType = (Type)3;
			component.physAttributePreset = Preset<PhysAttribute>("TBParty Trophy Phys", (Action<PhysAttribute>)delegate(PhysAttribute p)
			{
				p.mass = 6f;
			});
			component.valuePreset = Preset<Value>("TBParty Trophy Value", (Action<Value>)delegate(Value v)
			{
				v.valueMin = 30000f;
				v.valueMax = 54000f;
			});
			Bounds bounds = asset.Mesh.bounds;
			RoomVolumeCheck component2 = val2.GetComponent<RoomVolumeCheck>();
			Plugin.Logger.LogDebug((object)$"Template RoomVolumeCheck: CheckPosition {component2.CheckPosition}, currentSize {component2.currentSize}");
			component2.CheckPosition = val4 + ((Bounds)(ref bounds)).center;
			component2.currentSize = ((Bounds)(ref bounds)).size;
			return val2;
		}

		private static void ReplaceColliders(GameObject prefab, Transform root, Bounds[] boxes, Vector3 offset)
		{
			//IL_0088: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<GameObject> list = (from c in prefab.GetComponentsInChildren<Collider>(true)
				where !c.isTrigger
				select ((Component)c).gameObject).Distinct().ToList();
			GameObject val = list.First((GameObject go) => (Object)(object)go.GetComponent<PhysGrabObjectBoxCollider>() != (Object)null);
			for (int num = 0; num < boxes.Length; num++)
			{
				Bounds val2 = boxes[num];
				GameObject obj = Object.Instantiate<GameObject>(val, val.transform.parent);
				((Object)obj).name = "Valuable Collider";
				RootSpace.Place(obj.transform, root, offset + ((Bounds)(ref val2)).center);
				BoxCollider component = obj.GetComponent<BoxCollider>();
				component.center = Vector3.zero;
				component.size = ((Bounds)(ref val2)).size;
			}
			foreach (GameObject item in list)
			{
				Object.DestroyImmediate((Object)(object)item);
			}
			prefab.GetComponent<PhysGrabObject>().colliders.Clear();
		}

		private static Material GoldMaterial(Material source)
		{
			//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_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			Material val = new Material(source)
			{
				name = "TBParty Gold",
				color = Gold,
				mainTexture = null
			};
			val.SetFloat("_Metallic", 0.85f);
			val.SetFloat("_Glossiness", 0.65f);
			(string, string)[] array = new(string, string)[3]
			{
				("_MetallicGlossMap", "_METALLICGLOSSMAP"),
				("_BumpMap", "_NORMALMAP"),
				("_EmissionMap", "_EMISSION")
			};
			for (int i = 0; i < array.Length; i++)
			{
				var (text, text2) = array[i];
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
				val.DisableKeyword(text2);
			}
			if (val.HasProperty("_OcclusionMap"))
			{
				val.SetTexture("_OcclusionMap", (Texture)null);
			}
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}

		private static T Preset<T>(string name, Action<T> set) where T : ScriptableObject
		{
			T val = ScriptableObject.CreateInstance<T>();
			((Object)(object)val).name = name;
			((Object)(object)val).hideFlags = (HideFlags)32;
			set(val);
			return val;
		}
	}
}
namespace trepobmodsfix.Taxman
{
	internal sealed class TaxmanGreeting : MonoBehaviour
	{
		private TruckScreenText? _screen;

		private TaxmanClock _clock = new TaxmanClock();

		private bool _over;

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception)
			{
				_over = true;
			}
		}

		private void Tick()
		{
			TruckScreenText instance = TruckScreenText.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (instance != _screen)
			{
				_screen = instance;
				_clock = new TaxmanClock();
				_over = false;
			}
			if (!_over && SemiFunc.IsMasterClientOrSingleplayer() && IsTruckOfALevel(instance))
			{
				switch (_clock.Tick(instance.started, instance.isTyping, instance.currentPageIndex, instance.currentLineIndex, LinesOnCurrentPage(instance), Time.deltaTime))
				{
				case TaxmanStep.Send:
					_over = true;
					Send(instance);
					break;
				case TaxmanStep.GiveUp:
					_over = true;
					break;
				}
			}
		}

		private static bool IsTruckOfALevel(TruckScreenText screen)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			if ((Object)(object)RunManager.instance != (Object)null && SemiFunc.RunIsLevel())
			{
				return (int)screen.screenType == 0;
			}
			return false;
		}

		private static int LinesOnCurrentPage(TruckScreenText screen)
		{
			int currentPageIndex = screen.currentPageIndex;
			if (currentPageIndex < 0 || currentPageIndex >= screen.pages.Count)
			{
				return 0;
			}
			return screen.pages[currentPageIndex].textLines.Count;
		}

		private static void Send(TruckScreenText screen)
		{
			TMP_FontAsset val = (((Object)(object)screen.textMesh != (Object)null) ? ((TMP_Text)screen.textMesh).font : null);
			string text = TaxmanRule.LineFor((Object)(object)val != (Object)null && val.HasCharacter('ã', true, true));
			screen.MessageSendCustom("", text, 0);
		}

		private static string Describe(TruckScreenText screen)
		{
			return "";
		}
	}
}
namespace trepobmodsfix.Taxman.Logic
{
	public enum TaxmanStep
	{
		Wait,
		Send,
		GiveUp
	}
	public static class TaxmanRule
	{
		public const int StartPage = 0;

		public const int NotEnoughPage = 1;

		public const float SecondsAfterFinish = 1.5f;

		public const char Accented = 'ã';

		private const string Line = "Se divirtam muito, pouco não pode";

		private const string LineWithoutAccent = "Se divirtam muito, pouco nao pode";

		public static string LineFor(bool fontHasAccent)
		{
			if (!fontHasAccent)
			{
				return "Se divirtam muito, pouco nao pode";
			}
			return "Se divirtam muito, pouco não pode";
		}

		public static bool CanTalkOn(int page)
		{
			if (page != 0)
			{
				return page == 1;
			}
			return true;
		}
	}
	public sealed class TaxmanClock
	{
		private int _page;

		private float _waited;

		private bool _over;

		public TaxmanStep Tick(bool started, bool typing, int page, int line, int linesOnPage, float deltaSeconds)
		{
			if (_over || !started)
			{
				return TaxmanStep.Wait;
			}
			if (!TaxmanRule.CanTalkOn(page))
			{
				_over = true;
				return TaxmanStep.GiveUp;
			}
			if (page != _page)
			{
				_page = page;
				_waited = 0f;
			}
			if (typing || line < linesOnPage)
			{
				_waited = 0f;
				return TaxmanStep.Wait;
			}
			_waited += deltaSeconds;
			if (_waited < 1.5f)
			{
				return TaxmanStep.Wait;
			}
			_over = true;
			return TaxmanStep.Send;
		}
	}
}
namespace trepobmodsfix.Mimic
{
	internal static class ClownLaugh
	{
		private sealed class Found
		{
			public readonly AudioClip Clip;

			public readonly Sound? From;

			public readonly string Where;

			public Found(AudioClip clip, Sound? from, string where)
			{
				Clip = clip;
				From = from;
				Where = where;
			}
		}

		private const string ChosenName = "enemy bomb thrower - head laughing loop";

		private static readonly string[] Names = new string[6] { "enemy bomb thrower - head laughing loop", "clown warning vo1", "clown warning vo2", "item revive item vo laugh01", "item revive item vo laugh02", "item revive item vo laugh03" };

		private static readonly string? Chosen = "enemy bomb thrower - head laughing loop";

		private static readonly List<Found> FoundList = new List<Found>();

		private static readonly List<AudioClip> CandidateClips = new List<AudioClip>();

		private static bool _resolved;

		private const BindingFlags FieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static AudioClip? Clip => Pick()?.Clip;

		public static IReadOnlyList<AudioClip> Candidates
		{
			get
			{
				Resolve();
				return CandidateClips;
			}
		}

		public static void Resolve()
		{
			if (_resolved)
			{
				bool flag = false;
				foreach (Found found in FoundList)
				{
					if ((Object)(object)found.Clip == (Object)null)
					{
						flag = true;
					}
				}
				if (!flag)
				{
					return;
				}
			}
			FoundList.Clear();
			CandidateClips.Clear();
			Dictionary<string, Found> dictionary = new Dictionary<string, Found>();
			int num = 0;
			AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
			foreach (AudioClip val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					if (Array.IndexOf(Names, ((Object)val).name) >= 0 && !dictionary.ContainsKey(((Object)val).name))
					{
						string text = "";
						dictionary[((Object)val).name] = new Found(val, null, text);
					}
				}
			}
			bool flag2 = true;
			if (dictionary.Count < Names.Length && (Chosen == null || !dictionary.ContainsKey(Chosen)))
			{
				flag2 = SearchEnemyPrefabs(dictionary) >= 0;
			}
			_resolved = dictionary.Count == Names.Length || flag2;
			string[] names = Names;
			foreach (string key in names)
			{
				if (dictionary.TryGetValue(key, out var value))
				{
					FoundList.Add(value);
					CandidateClips.Add(value.Clip);
				}
			}
			List<string> list = new List<string>();
			names = Names;
			foreach (string text2 in names)
			{
				if (!dictionary.ContainsKey(text2))
				{
					list.Add(text2);
				}
			}
			if (Chosen != null && dictionary.ContainsKey(Chosen))
			{
				_ = Chosen;
			}
			else if (FoundList.Count > 0)
			{
				_ = ((Object)FoundList[0].Clip).name;
			}
			foreach (Found found2 in FoundList)
			{
				_ = found2;
			}
		}

		public static void PlayAt(Vector3 position)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Found found = Pick();
			if (found != null)
			{
				Play(found, position);
			}
		}

		private static Found? Pick()
		{
			Resolve();
			if (Chosen != null)
			{
				foreach (Found found in FoundList)
				{
					if ((Object)(object)found.Clip != (Object)null && ((Object)found.Clip).name == Chosen)
					{
						return found;
					}
				}
			}
			foreach (Found found2 in FoundList)
			{
				if ((Object)(object)found2.Clip != (Object)null)
				{
					return found2;
				}
			}
			return null;
		}

		private static void Play(Found found, Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//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)
			if (!((Object)(object)AudioManager.instance == (Object)null))
			{
				Sound val = new Sound();
				Sound val2 = found.From;
				if (val2 != null)
				{
					Sound val3 = val;
					AudioType type = val2.Type;
					bool flag = (((int)type == 1 || (int)type == 6 || type - 8 <= 1) ? true : false);
					val3.Type = (AudioType)(flag ? ((int)val2.Type) : 0);
					val.Volume = val2.Volume;
					val.Pitch = val2.Pitch;
					val.ReverbMix = val2.ReverbMix;
					val.Doppler = val2.Doppler;
					val.FalloffMultiplier = val2.FalloffMultiplier;
					val.OffscreenVolume = val2.OffscreenVolume;
					val.OffscreenFalloff = val2.OffscreenFalloff;
				}
				val.Sounds = (AudioClip[])(object)new AudioClip[1] { found.Clip };
				val.PitchRandom = 0f;
				val.VolumeRandom = 0f;
				val.SpatialBlend = 1f;
				AudioSource val4 = val.Play(position, 1f, 1f, 1f, 1f);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.loop = false;
				}
			}
		}

		private static int SearchEnemyPrefabs(Dictionary<string, Found> byName)
		{
			EnemyDirector instance = EnemyDirector.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return -1;
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			int num = 0;
			List<EnemySetup>[] array = new List<EnemySetup>[3] { instance.enemiesDifficulty1, instance.enemiesDifficulty2, instance.enemiesDifficulty3 };
			foreach (List<EnemySetup> list in array)
			{
				if (list == null)
				{
					continue;
				}
				foreach (EnemySetup item in list)
				{
					if ((Object)(object)item == (Object)null || item.spawnObjects == null)
					{
						continue;
					}
					foreach (PrefabRef spawnObject in item.spawnObjects)
					{
						if (spawnObject == null || (Object)(object)((PrefabRef<GameObject>)(object)spawnObject).Bundle != (Object)null || string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)spawnObject).ResourcePath))
						{
							continue;
						}
						GameObject val = Resources.Load<GameObject>(((PrefabRef<GameObject>)(object)spawnObject).ResourcePath);
						if (!((Object)(object)val == (Object)null) && hashSet.Add(val))
						{
							num++;
							SearchObject(val, byName);
							if (byName.Count == Names.Length || (Chosen != null && byName.ContainsKey(Chosen)))
							{
								return num;
							}
						}
					}
				}
			}
			return num;
		}

		private static void SearchObject(GameObject prefab, Dictionary<string, Found> byName)
		{
			Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				AudioSource val2 = (AudioSource)(object)((val is AudioSource) ? val : null);
				if (val2 != null)
				{
					Take(val2.clip, null, ((Object)prefab).name, byName);
				}
				else
				{
					if (!(val is MonoBehaviour))
					{
						continue;
					}
					Type type = ((object)val).GetType();
					while (type != null && type != typeof(MonoBehaviour))
					{
						FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (FieldInfo fieldInfo in fields)
						{
							Type fieldType = fieldInfo.FieldType;
							if (fieldType != typeof(Sound) && fieldType != typeof(AudioClip) && fieldType != typeof(AudioClip[]))
							{
								continue;
							}
							string text = "";
							if (fieldType == typeof(Sound))
							{
								object? value = fieldInfo.GetValue(val);
								Sound val3 = (Sound)((value is Sound) ? value : null);
								if (val3 != null && val3.Sounds != null)
								{
									AudioClip[] sounds = val3.Sounds;
									for (int k = 0; k < sounds.Length; k++)
									{
										Take(sounds[k], val3, text, byName);
									}
								}
							}
							else if (fieldType == typeof(AudioClip))
							{
								object? value2 = fieldInfo.GetValue(val);
								Take((AudioClip?)((value2 is AudioClip) ? value2 : null), null, text, byName);
							}
							else if (fieldInfo.GetValue(val) is AudioClip[] array)
							{
								AudioClip[] sounds = array;
								for (int k = 0; k < sounds.Length; k++)
								{
									Take(sounds[k], null, text, byName);
								}
							}
						}
						type = type.BaseType;
					}
				}
			}
		}

		private static void Take(AudioClip? clip, Sound? from, string where, Dictionary<string, Found> byName)
		{
			if (!((Object)(object)clip == (Object)null) && Array.IndexOf(Names, ((Object)clip).name) >= 0 && !byName.ContainsKey(((Object)clip).name))
			{
				string text = "";
				byName[((Object)clip).name] = new Found(clip, from, text);
			}
		}
	}
	internal sealed class MimicAnimationEvents : MonoBehaviour
	{
		public MimicFootsteps? Footsteps { get; set; }

		public void FootstepLight()
		{
			Step((SoundType)0);
		}

		public void FootstepMedium()
		{
			Step((SoundType)1);
		}

		public void FootstepHeavy()
		{
			Step((SoundType)2);
		}

		private void Step(SoundType type)
		{
			//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)
			MimicFootsteps footsteps = Footsteps;
			if (!((Object)(object)footsteps == (Object)null))
			{
				MimicGuard.Run("step", delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					footsteps.FromAnimation(type);
				});
			}
		}

		public void RightFootUp()
		{
		}

		public void RightFootUpSlow()
		{
		}

		public void RightFootDown()
		{
		}

		public void RightFootDownSlow()
		{
		}

		public void LeftFootUp()
		{
		}

		public void LeftFootUpSlow()
		{
		}

		public void LeftFootDown()
		{
		}

		public void LeftFootDownSlow()
		{
		}

		public void StandToCrouch()
		{
		}

		public void CrouchToStand()
		{
		}

		public void CrouchToCrawl()
		{
		}

		public void CrawlToCrouch()
		{
		}

		public void JumpImpulse()
		{
		}
	}
	internal sealed class MimicBody : MonoBehaviour
	{
		private static readonly int OverlayAmount = Shader.PropertyToID("_ColorOverlayAmount");

		private static readonly int HealthOffset = Shader.PropertyToID("_OffsetX");

		private static readonly int AlbedoColor = Shader.PropertyToID("_AlbedoColor");

		private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor");

		private const float HealthFullOffset = -0.5f;

		private readonly List<Material> _ownMaterials = new List<Material>();

		public PlayerAvatar Source { get; private set; }

		public Transform Head { get; private set; }

		public Animator Animator { get; private set; }

		public Transform? HeadSide { get; private set; }

		public Transform? HeadUp { get; private set; }

		public Transform? BodyTopSide { get; private set; }

		public Transform? BodyTopUp { get; private set; }

		public Transform? Jaw { get; private set; }

		public float JawMaxAngle { get; private set; }

		public MimicFace? Face { get; private set; }

		public Transform? LeftArm { get; private set; }

		public Vector3 LeftArmFlashlightPose { get; private set; }

		public Vector3 LeftArmBasePose { get; private set; }

		public int MaterialsCopied { get; private set; }

		public static MimicBody Create(PlayerAvatar source, Vector3 position, Quaternion rotation)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Expected O, but got Unknown
			GameObject val = new GameObject("Holder");
			val.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(((Component)source.playerAvatarVisuals).gameObject, val.transform);
			((Object)val2).name = "Player Visuals Proxy";
			PlayerAvatarVisuals component = val2.GetComponent<PlayerAvatarVisuals>();
			Transform val3 = (((Object)(object)component != (Object)null) ? Own(component.headLookAtTransform, val2.transform) : null);
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = val2.transform;
			}
			Transform headSide = (((Object)(object)component != (Object)null) ? Own(component.headSideTransform, val2.transform) : null);
			Transform headUp = (((Object)(object)component != (Object)null) ? Own(component.headUpTransform, val2.transform) : null);
			Transform bodyTopSide = (((Object)(object)component != (Object)null) ? Own(component.bodyTopSideTransform, val2.transform) : null);
			Transform bodyTopUp = (((Object)(object)component != (Object)null) ? Own(component.bodyTopUpTransform, val2.transform) : null);
			List<GameObject> list = new List<GameObject>();
			Light light = null;
			PlayerAvatarRightArm component2 = val2.GetComponent<PlayerAvatarRightArm>();
			if ((Object)(object)component2 != (Object)null)
			{
				if ((Object)(object)component2.grabberTransform != (Object)null)
				{
					list.Add(((Component)component2.grabberTransform).gameObject);
				}
				if ((Object)(object)component2.grabberClawParent != (Object)null)
				{
					list.Add(((Component)component2.grabberClawParent).gameObject);
				}
				if ((Object)(object)component2.grabberOrb != (Object)null)
				{
					list.Add(((Component)component2.grabberOrb).gameObject);
				}
				if (component2.grabberOrbSpheres != null)
				{
					GameObject[] grabberOrbSpheres = component2.grabberOrbSpheres;
					foreach (GameObject val4 in grabberOrbSpheres)
					{
						if ((Object)(object)val4 != (Object)null)
						{
							list.Add(val4);
						}
					}
				}
				light = component2.grabberLight;
			}
			PlayerAvatarLeftArm component3 = val2.GetComponent<PlayerAvatarLeftArm>();
			Transform leftArm = (((Object)(object)component3 != (Object)null) ? Own(component3.leftArmTransform, val2.transform) : null);
			Vector3 leftArmFlashlightPose = (((Object)(object)component3 != (Object)null) ? component3.flashlightPose : Vector3.zero);
			Vector3 leftArmBasePose = (((Object)(object)component3 != (Object)null) ? component3.basePose : Vector3.zero);
			PlayerAvatarTalkAnimation component4 = val2.GetComponent<PlayerAvatarTalkAnimation>();
			Transform val5 = (((Object)(object)component4 != (Object)null && (Object)(object)component4.objectToRotate != (Object)null) ? component4.objectToRotate.transform : null);
			if ((Object)(object)val5 != (Object)null && ((Object)(object)val5 == (Object)(object)val2.transform || !val5.IsChildOf(val2.transform)))
			{
				val5 = null;
			}
			float jawMaxAngle = (((Object)(object)component4 != (Object)null) ? component4.rotationMaxAngle : 0f);
			PlayerExpression val6 = val2.GetComponent<PlayerExpression>();
			if ((Object)(object)val6 == (Object)null)
			{
				val6 = val2.GetComponentInChildren<PlayerExpression>(true);
			}
			PlayerEyes val7 = val2.GetComponent<PlayerEyes>();
			if ((Object)(object)val7 == (Object)null)
			{
				val7 = val2.GetComponentInChildren<PlayerEyes>(true);
			}
			MimicFace face = MimicFace.Read(val2.transform, val6, val7, component);
			List<Transform> list2 = new List<Transform>();
			Cosmetic[] componentsInChildren = val2.GetComponentsInChildren<Cosmetic>(true);
			foreach (Cosmetic val8 in componentsInChildren)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					list2.Add(((Component)val8).transform);
				}
			}
			MonoBehaviour[] componentsInChildren2 = val2.GetComponentsInChildren<MonoBehaviour>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			Collider[] componentsInChildren3 = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			Transform[] componentsInChildren4 = val2.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Component)componentsInChildren4[i]).gameObject.layer = 0;
			}
			ResetToPrefabPose(val2.transform);
			HideGrabber(val2.transform, val3, list, light);
			QuietEffects(val2.transform, list2);
			PlayerHealth playerHealth = source.playerHealth;
			Material val9 = (((source.deadSet || source.isDisabled) && (Object)(object)playerHealth != (Object)null) ? playerHealth.healthMaterial : null);
			int num = 0;
			int num2 = 0;
			List<Material> list3 = new List<Material>();
			Renderer[] componentsInChildren5 = val2.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val10 in componentsInChildren5)
			{
				Material[] sharedMaterials = val10.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!((Object)(object)sharedMaterials[j] == (Object)null))
					{
						bool num3 = (Object)(object)val9 != (Object)null && (Object)(object)sharedMaterials[j] == (Object)(object)val9;
						sharedMaterials[j] = new Material(sharedMaterials[j]);
						list3.Add(sharedMaterials[j]);
						if (ClearHurtOverlay(sharedMaterials[j]))
						{
							num++;
						}
						if (num3 && FillHealthBar(sharedMaterials[j], playerHealth))
						{
							num2++;
						}
					}
				}
				val10.sharedMaterials = sharedMaterials;
				val10.shadowCastingMode = (ShadowCastingMode)1;
			}
			Animator val11 = val2.GetComponent<Animator>();
			if ((Object)(object)val11 == (Object)null)
			{
				val11 = val2.GetComponentInChildren<Animator>(true);
			}
			_ = (Object)(object)val11 == (Object)null;
			(((Object)(object)val11 != (Object)null) ? ((Component)val11).gameObject : val2).AddComponent<MimicAnimationEvents>();
			MimicBody mimicBody = val2.AddComponent<MimicBody>();
			mimicBody.Source = source;
			mimicBody.Head = val3;
			mimicBody.Animator = val11;
			mimicBody.HeadSide = headSide;
			mimicBody.HeadUp = headUp;
			mimicBody.BodyTopSide = bodyTopSide;
			mimicBody.BodyTopUp = bodyTopUp;
			mimicBody.Jaw = val5;
			mimicBody.JawMaxAngle = jawMaxAngle;
			mimicBody.Face = face;
			mimicBody.LeftArm = leftArm;
			mimicBody.LeftArmFlashlightPose = leftArmFlashlightPose;
			mimicBody.LeftArmBasePose = leftArmBasePose;
			mimicBody.MaterialsCopied = list3.Count;
			mimicBody._ownMaterials.AddRange(list3);
			val2.transform.SetParent((Transform)null, false);
			val2.transform.SetPositionAndRotation(position, rotation);
			Object.Destroy((Object)(object)val);
			val2.SetActive(true);
			if ((Object)(object)val11 != (Object)null)
			{
				val11.Rebind();
				val11.Update(0f);
			}
			return mimicBody;
		}

		private static Transform? Own(Transform? node, Transform cloneRoot)
		{
			if ((Object)(object)node == (Object)null)
			{
				return null;
			}
			if (node.IsChildOf(cloneRoot))
			{
				return node;
			}
			return null;
		}

		private static bool ClearHurtOverlay(Material copy)
		{
			if (!copy.HasProperty(OverlayAmount))
			{
				return false;
			}
			bool result = copy.GetFloat(OverlayAmount) > 0f;
			copy.SetFloat(OverlayAmount, 0f);
			return result;
		}

		private static bool FillHealthBar(Material copy, PlayerHealth health)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!copy.HasProperty(HealthOffset))
			{
				return false;
			}
			copy.SetFloat(HealthOffset, -0.5f);
			Gradient healthMaterialColor = health.healthMaterialColor;
			if (healthMaterialColor == null)
			{
				return true;
			}
			Color val = healthMaterialColor.Evaluate(1f);
			if (copy.HasProperty(AlbedoColor))
			{
				copy.SetColor(AlbedoColor, val);
			}
			if (copy.HasProperty(EmissionColor))
			{
				val.a = copy.GetColor(EmissionColor).a;
				copy.SetColor(EmissionColor, val);
			}
			return true;
		}

		private static void HideGrabber(Transform cloneRoot, Transform head, List<GameObject> parts, Light? light)
		{
			new List<string>();
			foreach (GameObject part in parts)
			{
				if (!((Object)(object)part == (Object)null))
				{
					Transform transform = part.transform;
					if (transform.IsChildOf(cloneRoot) && !((Object)(object)transform == (Object)(object)cloneRoot) && !head.IsChildOf(transform) && part.activeSelf)
					{
						part.SetActive(false);
					}
				}
			}
			if ((!((Object)(object)light != (Object)null) || ((Component)light).transform.IsChildOf(cloneRoot)) && (Object)(object)light != (Object)null && ((Behaviour)light).enabled)
			{
				((Behaviour)light).enabled = false;
			}
		}

		private static void QuietEffects(Transform cloneRoot, List<Transform> cosmetics)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			int num = 0;
			ParticleSystem[] componentsInChildren = ((Component)cloneRoot).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj in componentsInChildren)
			{
				MainModule main = obj.main;
				((MainModule)(ref main)).playOnAwake = false;
				EmissionModule emission = obj.emission;
				((EmissionModule)(ref emission)).enabled = false;
				obj.Stop(false, (ParticleSystemStopBehavior)0);
				obj.Clear(false);
				num++;
			}
			int num2 = 0;
			AudioSource[] componentsInChildren2 = ((Component)cloneRoot).GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource obj2 in componentsInChildren2)
			{
				obj2.playOnAwake = false;
				((Behaviour)obj2).enabled = false;
				num2++;
			}
			int num3 = 0;
			Rigidbody[] componentsInChildren3 = ((Component)cloneRoot).GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody obj3 in componentsInChildren3)
			{
				obj3.isKinematic = true;
				obj3.useGravity = false;
				num3++;
			}
			new List<string>();
			new List<string>();
			Light[] componentsInChildren4 = ((Component)cloneRoot).GetComponentsInChildren<Light>(true);
			foreach (Light val in componentsInChildren4)
			{
				if (((Behaviour)val).enabled && !ShownCosmetic(((Component)val).transform, cloneRoot, cosmetics))
				{
					((Behaviour)val).enabled = false;
				}
			}
		}

		private static bool ShownCosmetic(Transform node, Transform cloneRoot, List<Transform> cosmetics)
		{
			bool flag = false;
			foreach (Transform cosmetic in cosmetics)
			{
				if ((Object)(object)cosmetic != (Object)null && node.IsChildOf(cosmetic))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			Transform val = node;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)cloneRoot)
			{
				if (!((Component)val).gameObject.activeSelf)
				{
					return false;
				}
				val = val.parent;
			}
			return true;
		}

		private static void ResetToPrefabPose(Transform cloneRoot)
		{
			GameObject val = Resources.Load<GameObject>("PlayerAvatar");
			Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("Player Visuals") : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				int reset = 0;
				int active = 0;
				int renderers = 0;
				int extra = 0;
				ResetNode(cloneRoot, val2, ref reset, ref active, ref renderers, ref extra);
			}
		}

		private static void ResetNode(Transform node, Transform reference, ref int reset, ref int active, ref int renderers, ref int extra)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0133: Expected O, but got Unknown
			node.localPosition = reference.localPosition;
			node.localRotation = reference.localRotation;
			node.localScale = reference.localScale;
			reset++;
			if (((Component)node).gameObject.activeSelf != ((Component)reference).gameObject.activeSelf)
			{
				((Component)node).gameObject.SetActive(((Component)reference).gameObject.activeSelf);
				active++;
			}
			Renderer[] components = ((Component)reference).GetComponents<Renderer>();
			if (components.Length != 0)
			{
				Dictionary<Type, int> dictionary = new Dictionary<Type, int>();
				Renderer[] components2 = ((Component)node).GetComponents<Renderer>();
				foreach (Renderer val in components2)
				{
					Type type = ((object)val).GetType();
					dictionary.TryGetValue(type, out var value);
					dictionary[type] = value + 1;
					Renderer[] array = components;
					foreach (Renderer val2 in array)
					{
						if (!(((object)val2).GetType() != type) && value-- == 0)
						{
							if (val.enabled != val2.enabled)
							{
								val.enabled = val2.enabled;
								renderers++;
							}
							break;
						}
					}
				}
			}
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			foreach (Transform item in node)
			{
				Transform val3 = item;
				dictionary2.TryGetValue(((Object)val3).name, out var value2);
				dictionary2[((Object)val3).name] = value2 + 1;
				Transform val4 = NthChildNamed(reference, ((Object)val3).name, value2);
				if ((Object)(object)val4 == (Object)null)
				{
					extra += ((Component)val3).GetComponentsInChildren<Transform>(true).Length;
				}
				else
				{
					ResetNode(val3, val4, ref reset, ref active, ref renderers, ref extra);
				}
			}
		}

		private static Transform? NthChildNamed(Transform parent, string name, int index)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (!(((Object)val).name != name) && index-- == 0)
				{
					return val;
				}
			}
			return null;
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			foreach (Material ownMaterial in _ownMaterials)
			{
				if ((Object)(object)ownMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)ownMaterial);
				}
			}
			_ownMaterials.Clear();
		}
	}
	internal enum VanishReason
	{
		Attacked,
		Touched,
		Crowd,
		VictimGone,
		ImitatedGone,
		Lifetime,
		LevelEnd
	}
	internal sealed class MimicBrain : MonoBehaviour
	{
		private enum Mode
		{
			Pause,
			Walk,
			StepBack,
			BusyWalk,
			BusyPause,
			Warning,
			Lunge
		}

		private enum SpeakResult
		{
			Spoke,
			NoPhrase,
			Failed
		}

		private const float SpawnSampleRadius = 2f;

		private const float FallbackRadius = 0.7f;

		private const float FallbackHeight = 2f;

		private const float FallbackWalkSpeed = 2.5f;

		private const float Acceleration = 6f;

		private const float BodyTurnSpeed = 150f;

		private const float HeadYawSpeed = 160f;

		private const float HeadPitchSpeed = 60f;

		private const float HeadYawLimit = 80f;

		private const float MovingSpeed = 0.1f;

		private const float TurningRate = 30f;

		private const float TurningHold = 0.2f;

		private const float StareLimit = 1.2f;

		private const float VictimGlanceCooldown = 5f;

		private const float WalkTimeout = 8f;

		private const float SeenCheckInterval = 0.25f;

		private const float FloorSnapLimit = 0.3f;

		private const float FloorSnapSpeed = 1.5f;

		private const float FirstPhraseRetry = 0.5f;

		private const float SeenFirstPhraseMin = 1f;

		private const float SeenFirstPhraseMax = 3f;

		private const float MouthThreshold = 0.005f;

		private const float MouthLoudnessScale = 4f;

		private const float MouthSpeed = 100f;

		private const float SnapHeadSpeed = 900f;

		private const float LungeSpeed = 9f;

		private const float LungeAcceleration = 60f;

		private const float LungeMaxTime = 0.7f;

		private const float LungeHitDistance = 1.2f;

		private const float LungeTurnSpeed = 720f;

		private const float StrikeReach = 2f;

		private const float TumbleForce = 45f;

		private const float TumbleUpBlend = 0.6f;

		private const float TouchSpeed = 2f;

		private const float ContactMargin = 0.25f;

		private const float BulletMargin = 0.05f;

		private const float FallbackGrabRange = 4f;

		private const float VoiceTailSeconds = 0.2f;

		private const float DoorCheckHeight = 1f;

		private const float DoorCheckInterval = 0.25f;

		private const float DoorLogInterval = 5f;

		private static readonly List<MimicBrain> Live = new List<MimicBrain>();

		private static int _visionMask = -1;

		private static int _seeMask = -1;

		private static int _doorMask = -1;

		private static float _standingHeight = -1f;

		private MimicSettings _settings;

		private MimicBody? _body;

		private NavMeshAgent? _agent;

		private CapsuleCollider? _capsule;

		private MimicFootsteps? _footsteps;

		private MimicFlashlight? _flashlight;

		private MimicNameTag? _nameTag;

		private MimicVoice? _voice;

		private NavMeshQueryFilter _filter;

		private NavMeshPath _path;

		private readonly Random _random = new Random();

		private Action _tick;

		private Action _lateTick;

		private bool _vanished;

		private bool _spawnFailed;

		private float _age;

		private float _walkSpeed;

		private float _keepMin;

		private float _keepMax;

		private int _ownLayer;

		private int _floorMask;

		private int _sightMask;

		private int _seenMask;

		private float _doorCheck;

		private float _doorLogAt;

		private AttackClock _attackClock;

		private float _warningDistance;

		private VanishReason? _pendingVanish;

		private float _pendingTime;

		private float _pendingCheck;

		private readonly Collider[] _overlap = (Collider[])(object)new Collider[64];

		private Mode _mode;

		private float _modeTime;

		private float _modeDuration;

		private float _speedFactor;

		private float _stuckTime;

		private float _offMeshTime;

		private int _busyCount;

		private float _bodyYaw;

		private float? _bodyYawTarget;

		private float _yawRate;

		private float _turnHold;

		private float _speed;

		private float _bodyYOffset;

		private float _gazeYaw;

		private float _gazePitch;

		private bool _gazeAhead;

		private bool _gazeAtVictim;

		private float _gazeTimer;

		private float _headYaw;

		private float _headPitch;

		private float _stareTime;

		private float _victimGlanceTimer;

		private float _seenTimer;

		private readonly VoiceReaction _reaction = new VoiceReaction();

		private float _reactYawSpeed;

		private float _reactPitchSpeed;

		private int _voiceActor;

		private float _phraseTimer;

		private bool _firstPhraseDone;

		private bool _firstPhraseDelaySet;

		private bool _wasSpeaking;

		private bool _silentLogged;

		private int _phrasesSpoken;

		private static readonly int MovingHash = Animator.StringToHash("Moving");

		private static readonly int TurningHash = Animator.StringToHash("Turning");

		private static readonly int SprintingHash = Animator.StringToHash("Sprinting");

		private bool _hasMoving;

		private bool _hasTurning;

		private bool _hasSprinting;

		internal static int VisionMask
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (_visionMask == -1)
				{
					LayerMask val = SemiFunc.LayerMaskGetVisionObstruct();
					_visionMask = ((LayerMask)(ref val)).value & ~LayerMask.GetMask(new string[1] { "Player" });
				}
				return _visionMask;
			}
		}

		internal static int SeeMask
		{
			get
			{
				if (_seeMask == -1)
				{
					_seeMask = VisionMask & ~LayerMask.GetMask(new string[2] { "PhysGrabObject", "PhysGrabObjectCart" });
				}
				return _seeMask;
			}
		}

		internal static int DoorMask
		{
			get
			{
				if (_doorMask == -1)
				{
					_doorMask = LayerMask.GetMask(new string[1] { "PhysGrabObjectHinge" });
				}
				return _doorMask;
			}
		}

		internal static float StandingHeight
		{
			get
			{
				if (_standingHeight > 0f)
				{
					return _standingHeight;
				}
				GameObject val = Resources.Load<GameObject>("PlayerAvatar");
				Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("Player Avatar Controller/Collision") : null);
				if (!FromCapsule(((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<CapsuleCollider>() : null, out var _, out var height))
				{
					return 2f;
				}
				_standingHeight = height;
				return height;
			}
		}

		public PlayerAvatar Victim { get; private set; }

		public PlayerAvatar Imitated { get; private set; }

		public bool SeenByVictim { get; private set; }

		public bool SpawnFailed => _spawnFailed;

		public float Age => _age;

		public event Action<MimicBrain, VanishReason>? Vanished;

		public static MimicBrain Spawn(PlayerAvatar victim, PlayerAvatar imitated, Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Bot");
			val.SetActive(false);
			MimicBrain mimicBrain = val.AddComponent<MimicBrain>();
			mimicBrain.Victim = victim;
			mimicBrain.Imitated = imitated;
			mimicBrain._settings = MimicSettings.Current;
			mimicBrain._attackClock = new AttackClock(mimicBrain._settings);
			try
			{
				mimicBrain._spawnFailed = !mimicBrain.Build(position);
			}
			finally
			{
				val.SetActive(true);
			}
			if (!mimicBrain._spawnFailed)
			{
				mimicBrain._spawnFailed = !mimicBrain.BuildParts();
			}
			if (!mimicBrain._spawnFailed)
			{
				Live.Add(mimicBrain);
			}
			return mimicBrain;
		}

		public void Vanish(VanishReason reason)
		{
			if (!_vanished)
			{
				_vanished = true;
				Live.Remove(this);
				ReleaseVoice();
				DestroyParts();
				this.Vanished?.Invoke(this, reason);
			}
		}

		public void RequestVanish(VanishReason reason)
		{
			if (!_vanished && !_pendingVanish.HasValue && _mode != Mode.Lunge)
			{
				_pendingVanish = reason;
				_pendingTime = 0f;
				_pendingCheck = 0f;
				if ((Object)(object)_voice != (Object)null)
				{
					_voice.StopSpeaking();
				}
				if (_mode == Mode.Warning)
				{
					EnterPause(Range(1f, 2f));
				}
			}
		}

		private void Touch(string what)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!_vanished)
			{
				ClownLaugh.PlayAt(LaughPoint());
				Vanish(VanishReason.Touched);
			}
		}

		private Vector3 LaughPoint()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_body != (Object)null))
			{
				return ((Component)this).transform.position + Vector3.up * 1.5f;
			}
			return _body.Head.position;
		}

		private void ReleaseVoice()
		{
			MimicVoice voice = _voice;
			_voice = null;
			if (!((Object)(object)voice == (Object)null) && voice.IsPlaying)
			{
				voice.StopSpeaking();
				((Component)voice).transform.SetParent((Transform)null, true);
				Object.Destroy((Object)(object)((Component)voice).gameObject, 0.2f);
			}
		}

		private bool Build(Vector3 asked)
		{
			//IL_0071: 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_0089: 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_0097: 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_00e9: 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_0109: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Victim == (Object)null || (Object)(object)Imitated == (Object)null || (Object)(object)Imitated.playerAvatarVisuals == (Object)null)
			{
				return false;
			}
			LevelGenerator instance = LevelGenerator.Instance;
			if ((Object)(object)instance == (Object)null || !instance.Generated || (Object)(object)instance.NavMeshSurface == (Object)null)
			{
				return false;
			}
			if (!instance.NavMeshReady)
			{
				return false;
			}
			int agentTypeID = instance.NavMeshSurface.agentTypeID;
			NavMeshQueryFilter filter = default(NavMeshQueryFilter);
			((NavMeshQueryFilter)(ref filter)).agentTypeID = agentTypeID;
			((NavMeshQueryFilter)(ref filter)).areaMask = -1;
			_filter = filter;
			NavMeshHit val = default(NavMeshHit);
			if (!NavMesh.SamplePosition(asked, ref val, 2f, _filter))
			{
				return false;
			}
			_keepMin = Mathf.Max(1f, _settings.KeepMinDistance);
			_keepMax = Mathf.Max(_keepMin + 2f, _settings.KeepMaxDistance);
			Vector3 position = ((NavMeshHit)(ref val)).position;
			_bodyYaw = InitialYaw(position);
			_gazeYaw = _bodyYaw;
			((Component)this).transform.SetPositionAndRotation(position, Quaternion.Euler(0f, _bodyYaw, 0f));
			MeasurePlayer(out var radius, out var height);
			_walkSpeed = WalkSpeed(out string _);
			_ownLayer = LayerMask.NameToLayer("PlayerOnlyCollision");
			if (_ownLayer < 0)
			{
				_ownLayer = 0;
			}
			((Component)this).gameObject.layer = _ownLayer;
			_capsule = ((Component)this).gameObject.AddComponent<CapsuleCollider>();
			_capsule.direction = 1;
			_capsule.radius = radius;
			_capsule.height = height;
			_capsule.center = new Vector3(0f, height * 0.5f, 0f);
			Rigidbody obj = ((Component)this).gameObject.AddComponent<Rigidbody>();
			obj.isKinematic = true;
			obj.useGravity = false;
			_agent = ((Component)this).gameObject.AddComponent<NavMeshAgent>();
			_agent.agentTypeID = agentTypeID;
			_agent.radius = radius;
			_agent.height = height;
			_agent.baseOffset = 0f;
			_agent.speed = 0f;
			_agent.acceleration = 6f;
			_agent.angularSpeed = 150f;
			_agent.updateRotation = false;
			_agent.stoppingDistance = 0.2f;
			_agent.autoBraking = true;
			_agent.avoidancePriority = 99;
			_agent.obstacleAvoidanceType = (ObstacleAvoidanceType)0;
			_sightMask = VisionMask & ~(1 << _ownLayer);
			_seenMask = SeeMask & ~(1 << _ownLayer);
			_ = DoorMask;
			return true;
		}

		private bool BuildParts()
		{
			//IL_0016: 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_0042: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent agent = _agent;
			if (!agent.isOnNavMesh)
			{
				agent.Warp(((Component)this).transform.position);
			}
			if (!agent.isOnNavMesh)
			{
				return false;
			}
			MimicBody mimicBody = (_body = MimicBody.Create(Imitated, ((Component)this).transform.position, ((Component)this).transform.rotation));
			Transform transform = ((Component)mimicBody).transform;
			transform.SetParent(((Component)this).transform, false);
			transform.localPosition = Vector3.zero;
			transform.localRotation = Quaternion.identity;
			if ((Object)(object)mimicBody.Animator != (Object)null)
			{
				mimicBody.Animator.applyRootMotion = false;
				ReadAnimatorParameters(mimicBody.Animator);
			}
			if (!((Object)(object)mimicBody.HeadSide == (Object)null))
			{
				_ = (Object)(object)mimicBody.HeadUp == (Object)null;
			}
			int num = (((Object)(object)Materials.Instance != (Object)null) ? ((LayerMask)(ref Materials.Instance.LayerMask)).value : LayerMask.GetMask(new string[1] { "Default" }));
			_floorMask = num & ~(1 << _ownLayer);
			float? num2 = FloorOffset();
			_bodyYOffset = (num2.HasValue ? Mathf.Clamp(num2.Value, -0.3f, 0.3f) : 0f);
			transform.localPosition = new Vector3(0f, _bodyYOffset, 0f);
			_footsteps = MimicFootsteps.Create(((Component)this).transform, _ownLayer);
			MimicAnimationEvents componentInChildren = ((Component)transform).GetComponentInChildren<MimicAnimationEvents>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.Footsteps = _footsteps;
			}
			_flashlight = MimicFlashlight.Create(Imitated, mimicBody, ((Component)this).transform);
			_nameTag = MimicNameTag.Create(this, Imitated.playerName, mimicBody.Head, transform, (Collider)(object)_capsule);
			PlayerVoiceChat val = VoiceOf(Imitated);
			_voiceActor = ModPresence.ActorOf(((Object)(object)val != (Object)null) ? val.photonView : Imitated.photonView);
			if ((Object)(object)val != (Object)null)
			{
				_voice = MimicVoice.Create(mimicBody.Head, val);
			}
			_ = (Object)(object)mimicBody.Jaw == (Object)null;
			EnterPause(Range(1f, 2f));
			return true;
		}

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			_tick = Tick;
			_lateTick = LateTick;
			_path = new NavMeshPath();
		}

		private void Start()
		{
			MimicGuard.Run("brain start", delegate
			{
				if (_spawnFailed)
				{
					Vanish(VanishReason.LevelEnd);
				}
			});
		}

		private void Update()
		{
			if (MimicGuard.Disabled)
			{
				if (!_vanished)
				{
					_vanished = true;
					DestroyParts();
				}
			}
			else
			{
				MimicGuard.Run("brain", _tick);
			}
		}

		private void LateUpdate()
		{
			if (!MimicGuard.Disabled)
			{
				MimicGuard.Run("brain look", _lateTick);
			}
		}

		private void OnDestroy()
		{
			Live.Remove(this);
			if ((Object)(object)_nameTag != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_nameTag).gameObject);
			}
			_nameTag = null;
			if (!_vanished)
			{
				_vanished = true;
				MimicGuard.Run("brain destroyed", delegate
				{
					this.Vanished?.Invoke(this, VanishReason.LevelEnd);
				});
			}
		}

		private void DestroyParts()
		{
			if ((Object)(object)_nameTag != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_nameTag).gameObject);
			}
			_nameTag = null;
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void Tick()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0094: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			if (_vanished || _spawnFailed || (Object)(object)_agent == (Object)null || (Object)(object)_body == (Object)null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			if (deltaTime <= 0f)
			{
				return;
			}
			_age += deltaTime;
			if (!_agent.isOnNavMesh)
			{
				_offMeshTime += deltaTime;
				if (_offMeshTime > 2f)
				{
					Vanish(VanishReason.LevelEnd);
				}
				return;
			}
			_offMeshTime = 0f;
			Vector3 position = ((Component)this).transform.position;
			bool flag = false;
			Vector3 val = position;
			float num = float.PositiveInfinity;
			if ((Object)(object)Victim != (Object)null)
			{
				flag = true;
				val = ((Component)Victim).transform.position;
				num = Vector3.Distance(position, val);
			}
			bool flag2 = flag && num < _keepMin;
			if (flag && CheckContact())
			{
				return;
			}
			_modeTime += deltaTime;
			UpdateAttack(deltaTime, flag, num);
			if (_vanished)
			{
				return;
			}
			if (_mode == Mode.Lunge)
			{
				TickLunge(val, num);
				if (_vanished)
				{
					return;
				}
			}
			else if (_mode != Mode.Warning)
			{
				if (flag2 && _mode != Mode.BusyWalk && _mode != Mode.BusyPause)
				{
					EnterBusy(position, val, num);
				}
				switch (_mode)
				{
				case Mode.Pause:
					if (_modeTime >= _modeDuration)
					{
						AfterPause(position, flag, val, num);
					}
					break;
				case Mode.Walk:
				case Mode.StepBack:
				case Mode.BusyWalk:
					if (DoorAhead(deltaTime) || Arrived() || _modeTime > 8f || Stuck(deltaTime))
					{
						if (_mode == Mode.BusyWalk)
						{
							EnterBusyPause(flag, val);
						}
						else
						{
							EnterPause(Range(1f, 4f));
						}
					}
					break;
				case Mode.BusyPause:
					if (_modeTime >= _modeDuration)
					{
						if (flag2)
						{
							EnterBusy(position, val, num);
						}
						else
						{
							EnterPause(Range(1f, 2.5f));
						}
					}
					break;
				}
			}
			UpdateReaction(deltaTime, flag, num);
			SteerBody(deltaTime);
			UpdateGaze(deltaTime, flag, flag2);
			UpdateAnimator(deltaTime);
			if ((Object)(object)_footsteps != (Object)null)
			{
				_footsteps.Tick(_speed > 0.1f, _speed, deltaTime);
			}
			CheckSeen(deltaTime, flag);
			UpdateSpeech(deltaTime, num);
			UpdatePendingVanish(deltaTime);
		}

		private void UpdateAttack(float deltaTime, bool hasVictim, float distance)
		{
			if (!hasVictim || _pendingVanish.HasValue || _mode == Mode.Lunge)
			{
				return;
			}
			float distanceToVictim = distance;
			if (distance < Mathf.Max(_settings.NearRadius, _settings.AttackReach) && !ClearLineToVictim())
			{
				distanceToVictim = float.PositiveInfinity;
			}
			AttackPhase phase = _attackClock.Phase;
			bool flag = VictimAlive();
			AttackPhase attackPhase = _attackClock.Tick(deltaTime, distanceToVictim, flag);
			if (attackPhase == phase)
			{
				return;
			}
			switch (attackPhase)
			{
			case AttackPhase.Warning:
				EnterWarning(distance);
				break;
			case AttackPhase.Strike:
				EnterLunge(distance);
				break;
			case AttackPhase.Escaped:
				if (!flag)
				{
					RequestVanish(VanishReason.VictimGone);
				}
				else
				{
					RequestVanish(VanishReason.Crowd);
				}
				break;
			}
		}

		private bool ClearLineToVictim()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003d: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.up * (((Object)(object)_capsule != (Object)null) ? (_capsule.height * 0.5f) : 1f);
			return !Physics.Linecast(((Component)this).transform.position + val, ((Component)Victim).transform.position + val, _sightMask, (QueryTriggerInteraction)1);
		}

		private void EnterWarning(float distance)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			_warningDistance = distance;
			if ((Object)(object)_voice != (Object)null)
			{
				_voice.StopSpeaking();
			}
			StopAgent();
			if ((Object)(object)_agent != (Object)null && _agent.isOnNavMesh)
			{
				_agent.velocity = Vector3.zero;
			}
			SetMode(Mode.Warning, _settings.WarningSeconds, 0f);
			_bodyYawTarget = null;
			_stareTime = 0f;
			float num = YawTo(VictimHead());
			float num2 = Mathf.DeltaAngle(_bodyYaw, num);
			float num3 = 70f;
			if (Mathf.Abs(num2) > num3)
			{
				_bodyYaw = num - Mathf.Sign(num2) * num3;
				((Component)this).transform.rotation = Quaternion.Euler(0f, _bodyYaw, 0f);
				num2 = Mathf.Sign(num2) * num3;
			}
			_gazeAhead = false;
			_gazeAtVictim = true;
			_gazeYaw = num;
			_gazePitch = PitchTo(VictimHead());
			_headYaw = num2;
			_headPitch = Mathf.Clamp(_gazePitch, -20f, 25f);
			(((Object)(object)_body != (Object)null) ? _body.Face : null)?.BeginAngry();
		}

		private void EnterLunge(float distance)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent agent = _agent;
			SetMode(Mode.Lunge, 0.7f, 1f);
			agent.acceleration = 60f;
			agent.autoBraking = false;
			agent.stoppingDistance = 0f;
			if ((Object)(object)Victim != (Object)null)
			{
				agent.SetDestination(((Component)Victim).transform.position);
			}
			if ((Object)(object)_body != (Object)null)
			{
				_ = _body.Face;
			}
		}

		private void TickLunge(Vector3 victimPosition, float distance)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (Object)(object)Victim != (Object)null && (Object)(object)Victim.RoomVolumeCheck != (Object)null && Victim.RoomVolumeCheck.inTruck;
			if (!VictimAlive() || !InMainState() || flag)
			{
				NavMeshAgent? agent = _agent;
				agent.acceleration = 6f;
				agent.autoBraking = true;
				agent.stoppingDistance = 0.2f;
				EnterPause(Range(1f, 2f));
				RequestVanish(VanishReason.VictimGone);
			}
			else if (distance > 1.2f && _modeTime < 0.7f)
			{
				_agent.SetDestination(victimPosition);
			}
			else
			{
				string why = "";
				if (distance > 2f)
				{
					Miss(distance, why);
				}
				else if (!ClearLineToVictim())
				{
					Miss(distance, why);
				}
				else
				{
					Strike(distance);
				}
			}
		}

		private void Miss(float distance, string why)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ClownLaugh.PlayAt(LaughPoint());
			Vanish(VanishReason.Attacked);
		}

		private void Strike(float distance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0071: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar victim = Victim;
			if (!victim.isLocal)
			{
				string why = "";
				Miss(distance, why);
				return;
			}
			PlayerHealth playerHealth = victim.playerHealth;
			if ((Object)(object)playerHealth != (Object)null)
			{
				_ = playerHealth.health;
			}
			Vector3 val = Flat(((Component)victim).transform.position - ((Component)this).transform.position);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = ((Component)this).transform.forward;
			}
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = Vector3.Lerp(val, Vector3.up, 0.6f) * 45f;
			if ((Object)(object)playerHealth != (Object)null)
			{
				playerHealth.Hurt(_settings.AttackDamage, false, -1, false);
			}
			if (!victim.deadSet && (Object)(object)victim.tumble != (Object)null)
			{
				victim.tumble.TumbleRequest(true, false);
				victim.tumble.TumbleForce(val2);
			}
			ClownLaugh.PlayAt(LaughPoint());
			Vanish(VanishReason.Attacked);
		}

		private bool VictimAlive()
		{
			if ((Object)(object)Victim != (Object)null && !Victim.deadSet)
			{
				return !Victim.isDisabled;
			}
			return false;
		}

		private static bool InMainState()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((Object)(object)GameDirector.instance != (Object)null)
			{
				return (int)GameDirector.instance.currentState == 2;
			}
			return false;
		}

		private void UpdatePendingVanish(float deltaTime)
		{
			if (!_pendingVanish.HasValue || _vanished)
			{
				return;
			}
			_pendingTime += deltaTime;
			_pendingCheck -= deltaTime;
			bool flag = _pendingTime >= _settings.VanishWaitMax;
			if (flag || !(_pendingCheck > 0f))
			{
				_pendingCheck = 0.25f;
				if (!VisibleNow() || flag)
				{
					Vanish(_pendingVanish.Value);
				}
			}
		}

		private bool VisibleNow()
		{
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null || (Object)(object)_body == (Object)null || (Object)(object)_capsule == (Object)null)
			{
				return false;
			}
			return VisibleTo(main);
		}

		private bool CheckContact()
		{
			if (!Victim.isLocal || (Object)(object)_capsule == (Object)null)
			{
				return false;
			}
			if (GrabAimedAtMe(out string what))
			{
				Touch(what);
				return true;
			}
			if (!OverlapTouch(out string what2))
			{
				return false;
			}
			Touch(what2);
			return true;
		}

		private bool GrabAimedAtMe(out string what)
		{
			//IL_00da: 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)
			what = "";
			if (!SemiFunc.InputHold((InputKey)10) && !SemiFunc.InputDown((InputKey)10))
			{
				return false;
			}
			Transform val = (((Object)(object)Victim.localCamera != (Object)null) ? Victim.localCamera.GetOverrideTransform() : null);
			if ((Object)(object)val == (Object)null && (Object)(object)Camera.main != (Object)null)
			{
				val = ((Component)Camera.main).transform;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			PhysGrabber physGrabber = Victim.physGrabber;
			if ((Object)(object)physGrabber != (Object)null && physGrabber.grabbed)
			{
				return false;
			}
			float num = (((Object)(object)physGrabber != (Object)null && physGrabber.grabRange > 0f) ? physGrabber.grabRange : 4f);
			int num2 = (((Object)(object)physGrabber != (Object)null) ? ((LayerMask)(ref physGrabber.mask)).value : VisionMask) | (1 << _ownLayer);
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val.position, val.forward, ref val2, num, num2, (QueryTriggerInteraction)1) || (Object)(object)((RaycastHit)(ref val2)).collider != (Object)(object)_capsule)
			{
				return false;
			}
			return true;
		}

		private bool OverlapTouch(out string what)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_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_0057: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			what = "";
			CapsuleCollider capsule = _capsule;
			Vector3 up = ((Component)this).transform.up;
			Vector3 val = ((Component)this).transform.TransformPoint(capsule.center);
			float num = Mathf.Max(0f, capsule.height * 0.5f - capsule.radius);
			int num2 = Physics.OverlapCapsuleNonAlloc(val - up * num, val + up * num, capsule.radius + 0.25f, _overlap, ~(1 << _ownLayer), (QueryTriggerInteraction)2);
			HurtCollider val3 = default(HurtCollider);
			for (int i = 0; i < num2; i++)
			{
				Collider val2 = _overlap[i];
				_overlap[i] = null;
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				if (((Component)val2).TryGetComponent<HurtCollider>(ref val3))
				{
					if (((Behaviour)val3).isActiveAndEnabled && !val3.detectionOnly && !val3.deathPit && HurtFromVictim(val3, out string _))
					{
						return true;
					}
					continue;
				}
				Rigidbody attachedRigidbody = val2.attachedRigidbody;
				if ((Object)(object)attachedRigidbody == (Object)null)
				{
					continue;
				}
				PhysGrabObject val4 = ((Component)attachedRigidbody).GetComponent<PhysGrabObject>();
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ((Component)attachedRigidbody).GetComponentInParent<PhysGrabObject>();
				}
				if (!((Object)(object)val4 == (Object)null) && !val4.isPlayer && !val4.isEnemy)
				{
					float num3;
					if (!attachedRigidbody.isKinematic)
					{
						Vector3 linearVelocity = attachedRigidbody.linearVelocity;
						num3 = ((Vector3)(ref linearVelocity)).magnitude;
					}
					else
					{
						num3 = 0f;
					}
					float num4 = Mathf.Max(num3, ((Vector3)(ref val4.rbVelocity)).magnitude);
					if (val4.grabbedLocal)
					{
						return true;
					}
					if (num4 > 2f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool HurtFromVictim(HurtCollider hurt, out string by)
		{
			by = "";
			if ((Object)(object)hurt.enemyHost != (Object)null || (Object)(object)((Component)hurt).GetComponentInParent<Enemy>() != (Object)null)
			{
				return false;
			}
			PlayerAvatar victim = Victim;
			if ((Object)(object)hurt.playerCausingHurt == (Object)(object)victim || (Object)(object)hurt.playerCausingHurtOverride == (Object)(object)victim)
			{
				return true;
			}
			PhysGrabObject parentPhysGrabObject = hurt.parentPhysGrabObject;
			if ((Object)(object)parentPhysGrabObject != (Object)null && (parentPhysGrabObject.grabbedLocal || (Object)(object)parentPhysGrabObject.lastPlayerGrabbing == (Object)(object)victim))
			{
				return true;
			}
			return false;
		}

		private void CheckBullet(Vector3 from, Vector3 to)
		{
			//IL_0024: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0068: 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_0074: 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)
			if (!_vanished && !((Object)(object)_capsule == (Object)null))
			{
				CapsuleCollider capsule = _capsule;
				Vector3 up = ((Component)this).transform.up;
				Vector3 val = ((Component)this).transform.TransformPoint(capsule.center);
				float num = Mathf.Max(0f, capsule.height * 0.5f - capsule.radius);
				if (!(SegmentDistance(val - up * num, val + up * num, from, to) > capsule.radius + 0.05f))
				{
					string what = "";
					Touch(what);
				}
			}
		}

		internal static void InstallPatches(Harmony harmony)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = typeof(ItemGunBullet).GetMethod("ActivateAll", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) ?? throw new MissingMethodException("ItemGunBullet", "ActivateAll");
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(MimicBrain).GetMethod("BulletPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception)
			{
			}
		}

		private static void BulletPrefix(ItemGunBullet __instance)
		{
			if (Live.Count == 0 || MimicGuard.Disabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			MimicGuard.Run("bullet", delegate
			{
				//IL_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: 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 position = ((Component)__instance).transform.position;
				Vector3 hitPosition = __instance.hitPosition;
				MimicBrain[] array = Live.ToArray();
				foreach (MimicBrain mimicBrain in array)
				{
					if ((Object)(object)mimicBrain != (Object)null)
					{
						mimicBrain.CheckBullet(position, hitPosition);
					}
				}
			});
		}

		private static float SegmentDistance(Vector3 p1, Vector3 q1, Vector3 p2, Vector3 q2)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0011: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0021: 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_002a: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_0118: 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_011c: 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)
			//IL_0127: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = q1 - p1;
			Vector3 val2 = q2 - p2;
			Vector3 val3 = p1 - p2;
			float num = Vector3.Dot(val, val);
			float num2 = Vector3.Dot(val2, val2);
			float num3 = Vector3.Dot(val2, val3);
			if (num <= 1E-08f && num2 <= 1E-08f)
			{
				return Vector3.Distance(p1, p2);
			}
			float num4;
			float num5;
			if (num <= 1E-08f)
			{
				num4 = 0f;
				num5 = Mathf.Clamp01(num3 / num2);
			}
			else
			{
				float num6 = Vector3.Dot(val, val3);
				if (num2 <= 1E-08f)
				{
					num5 = 0f;
					num4 = Mathf.Clamp01((0f - num6) / num);
				}
				else
				{
					float num7 = Vector3.Dot(val, val2);
					float num8 = num * num2 - num7 * num7;
					num4 = ((num8 > 1E-08f) ? Mathf.Clamp01((num7 * num3 - num6 * num2) / num8) : 0f);
					num5 = (num7 * num4 + num3) / num2;
					if (num5 < 0f)
					{
						num5 = 0f;
						num4 = Mathf.Clamp01((0f - num6) / num);
					}
					else if (num5 > 1f)
					{
						num5 = 1f;
						num4 = Mathf.Clamp01((num7 - num6) / num);
					}
				}
			}
			return Vector3.Distance(p1 + val * num4, p2 + val2 * num5);
		}

		private static float PointSegmentDistance(Vector3 point, Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0020: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrMagnitude <= 1E-08f)
			{
				return Vector3.Distance(point, a);
			}
			float num = Mathf.Clamp01(Vector3.Dot(point - a, val) / sqrMagnitude);
			return Vector3.Distance(point, a + val * num);
		}

		private void LateTick()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			if (_vanished || _spawnFailed || (Object)(object)_body == (Object)null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			float? num = FloorOffset();
			if (num.HasValue)
			{
				float num2 = Mathf.Clamp(num.Value, -0.3f, 0.3f);
				_bodyYOffset = Mathf.MoveTowards(_bodyYOffset, num2, 1.5f * deltaTime);
			}
			Transform transform = ((Component)_body).transform;
			transform.localPosition = new Vector3(0f, _bodyYOffset, 0f);
			transform.localRotation = Quaternion.identity;
			int num3;
			int num4;
			if (_mode != Mode.Warning)
			{
				num3 = ((_mode == Mode.Lunge) ? 1 : 0);
				if (num3 == 0)
				{
					num4 = (_reaction.Active ? 1 : 0);
					goto IL_00bf;
				}
			}
			else
			{
				num3 = 1;
			}
			num4 = 0;
			goto IL_00bf;
			IL_00bf:
			bool flag = (byte)num4 != 0;
			float num5 = ((num3 != 0) ? 900f : (flag ? _reactYawSpeed : 160f));
			float num6 = ((num3 != 0) ? 900f : (flag ? _reactPitchSpeed : 60f));
			float num7 = Mathf.Clamp(Mathf.DeltaAngle(_bodyYaw, _gazeYaw), -80f, 80f);
			_headYaw = Mathf.MoveTowards(_headYaw, num7, num5 * deltaTime);
			_headPitch = Mathf.MoveTowards(_headPitch, Mathf.Clamp(_gazePitch, -20f, 25f), num6 * deltaTime);
			MimicFace face = _body.Face;
			face?.Step(deltaTime);
			float num8 = face?.HeadPitchOffset ?? 0f;
			float num9 = face?.BodyPitchOffset ?? 0f;
			if ((Object)(object)_body.HeadSide != (Object)null)
			{
				_body.HeadSide.localRotation = Quaternion.Euler(0f, _headYaw * (2f / 3f), 0f);
			}
			if ((Object)(object)_body.BodyTopSide != (Object)null)
			{
				_body.BodyTopSide.localRotation = Quaternion.Euler(0f, _headYaw / 3f, 0f);
			}
			if ((Object)(object)_body.HeadUp != (Object)null)
			{
				_body.HeadUp.localRotation = Quaternion.Euler(_headPitch * (2f / 3f) + num8, 0f, 0f);
			}
			if ((Object)(object)_body.BodyTopUp != (Object)null)
			{
				_body.BodyTopUp.localRotation = Quaternion.Euler(_headPitch / 3f + num9, 0f, 0f);
			}
			if ((Object)(object)_body.Head != (Object)(object)transform)
			{
				_body.Head.rotation = Quaternion.Euler(_headPitch, _bodyYaw + _headYaw, 0f);
			}
			if ((Object)(object)_body.Jaw != (Object)null)
			{
				float num10 = (((Object)(object)_voice != (Object)null) ? (_voice.Loudness * _voice.VolumeMultiplier) : 0f);
				float num11 = ((num10 > 0.005f) ? Mathf.Lerp(0f, 0f - _body.JawMaxAngle, num10 * 4f) : 0f);
				_body.Jaw.localRotation = Quaternion.Slerp(_body.Jaw.localRotation, Quaternion.Euler(num11, 0f, 0f), 100f * deltaTime);
			}
			face?.Apply(transform);
			if ((Object)(object)_flashlight != (Object)null)
			{
				_flashlight.Tick(_body.Head, _headPitch, deltaTime);
			}
		}

		private void EnterPause(float duration)
		{
			//IL_0045: 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)
			StopAgent();
			SetMode(Mode.Pause, duration, 0f);
			_busyCount = 0;
			_gazeTimer = 0f;
			if ((Object)(object)Victim != (Object)null && Mathf.Abs(Mathf.DeltaAngle(_bodyYaw, YawTo(((Component)Victim).transform.position))) < 30f)
			{
				_bodyYawTarget = YawTo(((Component)Victim).transform.position) + Side() * Range(50f, 100f);
			}
		}

		private void AfterPause(Vector3 position, bool hasVictim, Vector3 victimPosition, float distance)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			Vector3 target2;
			if ((!hasVictim || distance <= _keepMax) && Chance(0.2f) && TryPickStepBack(position, hasVictim, victimPosition, distance, out var target))
			{
				EnterWalk(target, Mode.StepBack, 0.45f);
			}
			else if (TryPickWalkTarget(position, hasVictim, victimPosition, distance, out target2))
			{
				EnterWalk(target2, Mode.Walk, 1f);
			}
			else
			{
				EnterPause(Range(1f, 2f));
			}
		}

		private void EnterWalk(Vector3 target, Mode mode, float speedFactor)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!_agent.SetDestination(target))
			{
				EnterPause(Range(1f, 2f));
				return;
			}
			SetMode(mode, 0f, speedFactor);
			_stuckTime = 0f;
			_bodyYawTarget = null;
			_gazeTimer = 0f;
			_doorCheck = 0.25f;
		}

		private void EnterBusy(Vector3 position, Vector3 victimPosition, float distance)
		{
			//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_0041: 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)
			_busyCount++;
			if ((_busyCount <= 1 || !Chance(0.4f)) && TryPickBusyTarget(position, victimPosition, distance, out var target))
			{
				EnterWalk(target, Mode.BusyWalk, 0.7f);
			}
			else
			{
				EnterBusyPause(hasVictim: true, victimPosition);
			}
		}

		private void EnterBusyPause(bool hasVictim, Vector3 victimPosition)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			StopAgent();
			SetMode(Mode.BusyPause, Range(1.5f, 3f), 0f);
			_gazeTimer = 0f;
			if (hasVictim)
			{
				float num = YawTo(victimPosition);
				if (Mathf.Abs(Mathf.DeltaAngle(_bodyYaw, num)) < 60f)
				{
					_bodyYawTarget = num + Side() * Range(80f, 120f);
				}
			}
		}

		private void SetMode(Mode mode, float duration, float speedFactor)
		{
			_ = _mode;
			_mode = mode;
			_modeTime = 0f;
			_modeDuration = duration;
			_speedFactor = speedFactor;
		}

		private void StopAgent()
		{
			if ((Object)(object)_agent != (Object)null && _agent.isOnNavMesh)
			{
				_agent.ResetPath();
			}
		}

		private bool Arrived()
		{
			NavMeshAgent agent = _agent;
			if (agent.pathPending)
			{
				return false;
			}
			if (agent.hasPath)
			{
				return agent.remainingDistance <= agent.stoppingDistance + 0.05f;
			}
			return true;
		}

		private bool Stuck(float deltaTime)
		{
			if (_speed < 0.05f && _yawRate < 5f && _modeTime > 1f)
			{
				_stuckTime += deltaTime;
			}
			else
			{
				_stuckTime = 0f;
			}
			return _stuckTime > 2f;
		}

		private bool TryPickWalkTarget(Vector3 position, bool hasVictim, Vector3 victimPosition, float distance, out Vector3 target)
		{
			//IL_01d7: Un