Decompiled source of hololive English Promise v1.0.1

PromiseSuit.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
using ModelReplacement.Scripts.Enemies;
using ModelReplacement.Scripts.Player;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCopyright("© 2016 cover corp.")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace PromiseSuit;

public static class MaskedAppearanceCompatibility
{
	private static readonly Type HostType = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Monobehaviors.Enemies.MaskedReplacementBase");

	private static readonly FieldInfo ModelField = ((HostType == null) ? null : AccessTools.Field(HostType, "replacementModel"));

	private static readonly FieldInfo ActiveField = ((HostType == null) ? null : AccessTools.Field(HostType, "IsActive"));

	private static readonly PropertyInfo AvatarProperty = ((HostType == null) ? null : AccessTools.Property(HostType, "avatar"));

	private static readonly MethodInfo Replace = ((HostType == null) ? null : AccessTools.Method(HostType, "SetReplacement", new Type[1] { typeof(PlayerControllerB) }, (Type[])null));

	private static readonly ManualLogSource Log = Logger.CreateLogSource("Promise masked compatibility");

	public static void Install(Harmony harmony)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Expected O, but got Unknown
		if (Replace == null || ModelField == null || AvatarProperty == null)
		{
			Log.LogWarning((object)"Masked API entry points unavailable; player replacements remain enabled.");
			return;
		}
		harmony.Patch((MethodBase)Replace, new HarmonyMethod(typeof(MaskedAppearanceCompatibility), "Assign", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(MaskedPlayerEnemy), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaskedAppearanceCompatibility), "Spawned", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static bool Owns(PlayerControllerB player, out BodyReplacementBase body)
	{
		body = null;
		if (Object.op_Implicit((Object)(object)player) && ModelReplacementAPI.GetPlayerModelReplacement(player, ref body) && Object.op_Implicit((Object)(object)body))
		{
			return ((object)body).GetType().Assembly == typeof(Plugin).Assembly;
		}
		return false;
	}

	private static void Spawned(MaskedPlayerEnemy __instance)
	{
		if (Object.op_Implicit((Object)(object)__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<MaskedAppearanceRetry>()))
		{
			((Component)__instance).gameObject.AddComponent<MaskedAppearanceRetry>().Enemy = __instance;
		}
	}

	internal static void Retry(MaskedPlayerEnemy enemy)
	{
		if (!Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit((Object)(object)enemy.mimickingPlayer) || !Owns(enemy.mimickingPlayer, out var body) || !Object.op_Implicit((Object)(object)body.replacementModel) || (Object)(object)body.viewState == (Object)null)
		{
			return;
		}
		Component component = ((Component)enemy).GetComponent(HostType);
		if (!Object.op_Implicit((Object)(object)component))
		{
			((Component)enemy).gameObject.AddComponent(HostType);
			return;
		}
		object? value = ModelField.GetValue(component);
		if (!Object.op_Implicit((Object)((value is GameObject) ? value : null)))
		{
			Replace.Invoke(component, new object[1] { enemy.mimickingPlayer });
		}
	}

	private static bool Assign(object __instance, PlayerControllerB __0)
	{
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Expected O, but got Unknown
		if (!Owns(__0, out var body))
		{
			return true;
		}
		if (!Object.op_Implicit((Object)(object)body.replacementModel) || (Object)(object)body.viewState == (Object)null)
		{
			return false;
		}
		object obj = ((__instance is Component) ? __instance : null);
		MaskedPlayerEnemy val = ((obj != null) ? ((Component)obj).GetComponent<MaskedPlayerEnemy>() : null);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return true;
		}
		GameObject val2 = null;
		object? value = ModelField.GetValue(__instance);
		GameObject val3 = (GameObject)((value is GameObject) ? value : null);
		try
		{
			MaskedModelFaceDriver maskedModelFaceDriver = (Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<MaskedModelFaceDriver>() : null);
			if (Object.op_Implicit((Object)(object)maskedModelFaceDriver) && (Object)(object)maskedModelFaceDriver.SourcePlayer == (Object)(object)__0 && (Object)(object)maskedModelFaceDriver.SourceModel == (Object)(object)body.replacementModel)
			{
				return false;
			}
			val2 = Object.Instantiate<GameObject>(body.replacementModel);
			((Object)val2).name = ((Object)body.replacementModel).name + " (Masked)";
			val2.transform.localPosition = Vector3.zero;
			MaskedModelFaceDriver.DetachPlayerControllers(val2);
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer obj2 in componentsInChildren)
			{
				((Component)obj2).gameObject.layer = body.viewState.VisibleLayer;
				obj2.shadowCastingMode = (ShadowCastingMode)1;
				obj2.enabled = true;
			}
			Camera[] componentsInChildren2 = val2.GetComponentsInChildren<Camera>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Behaviour)componentsInChildren2[i]).enabled = false;
			}
			NaturalEyeSockets.Ensure(val2).Aim(Vector2.zero);
			val2.AddComponent<MaskedModelFaceDriver>().Initialize(val, __0, body.replacementModel);
			MaskedAvatarUpdater val4 = new MaskedAvatarUpdater();
			val4.AssignModelReplacement(((Component)val).gameObject, val2);
			AvatarProperty.SetValue(__instance, val4, null);
			ModelField.SetValue(__instance, val2);
			ActiveField?.SetValue(__instance, true);
			val2.SetActive(true);
			SkinnedMeshRenderer[] array = (SkinnedMeshRenderer[])(object)new SkinnedMeshRenderer[3] { val.rendererLOD0, val.rendererLOD1, val.rendererLOD2 };
			foreach (SkinnedMeshRenderer val5 in array)
			{
				if (Object.op_Implicit((Object)(object)val5))
				{
					((Renderer)val5).enabled = false;
					((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			if (Object.op_Implicit((Object)(object)val3) && (Object)(object)val3 != (Object)(object)val2)
			{
				Object.Destroy((Object)(object)val3);
			}
			return false;
		}
		catch (Exception ex)
		{
			if (Object.op_Implicit((Object)(object)val2))
			{
				Object.Destroy((Object)(object)val2);
			}
			Log.LogWarning((object)("Masked adapter could not initialize; retaining MRAPI fallback: " + ex));
			return true;
		}
	}
}
public sealed class MaskedAppearanceRetry : MonoBehaviour
{
	public MaskedPlayerEnemy Enemy;

	private float next;

	private void Update()
	{
		if (!(Time.unscaledTime < next))
		{
			next = Time.unscaledTime + 1f;
			if (!Object.op_Implicit((Object)(object)Enemy) || ((EnemyAI)Enemy).isEnemyDead)
			{
				((Behaviour)this).enabled = false;
			}
			else
			{
				MaskedAppearanceCompatibility.Retry(Enemy);
			}
		}
	}
}
[DefaultExecutionOrder(9000)]
public sealed class MaskedModelFaceDriver : MonoBehaviour
{
	private sealed class Face
	{
		public SkinnedMeshRenderer Renderer;

		public int Blink;

		public int Left;

		public int Right;

		public int Up;

		public int Down;
	}

	public PlayerControllerB SourcePlayer;

	public GameObject SourceModel;

	private MaskedPlayerEnemy enemy;

	private MaskedVanillaBadges.Binding vanillaBadges;

	private NaturalEyeSockets sockets;

	private Vector2 gaze;

	private bool morphGaze;

	private float nextBlink;

	private float blinkStart = -10f;

	private readonly List<Face> faces = new List<Face>();

	private static int Shape(Mesh mesh, string name)
	{
		for (int i = 0; i < mesh.blendShapeCount; i++)
		{
			string blendShapeName = mesh.GetBlendShapeName(i);
			if (blendShapeName == name || blendShapeName.EndsWith("." + name, StringComparison.Ordinal) || blendShapeName.EndsWith("_" + name, StringComparison.Ordinal))
			{
				return i;
			}
		}
		return -1;
	}

	private static void Set(Face face, int index, float value)
	{
		if (Object.op_Implicit((Object)(object)face.Renderer) && index >= 0)
		{
			face.Renderer.SetBlendShapeWeight(index, value);
		}
	}

	public static void DetachPlayerControllers(GameObject clone)
	{
		MaskedCloneIsolation.Detach(clone, typeof(MaskedModelFaceDriver).Namespace);
	}

	public void Initialize(MaskedPlayerEnemy masked, PlayerControllerB source, GameObject model)
	{
		enemy = masked;
		SourcePlayer = source;
		SourceModel = model;
		vanillaBadges = MaskedVanillaBadges.Bind(((Component)masked).gameObject, (Object)(object)this);
		sockets = NaturalEyeSockets.Ensure(((Component)this).gameObject);
		nextBlink = Time.time + (float)Random.Range(2, 5);
		SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			if (Object.op_Implicit((Object)(object)val.sharedMesh) && ((Object)val).name.IndexOf("Ink", StringComparison.OrdinalIgnoreCase) < 0)
			{
				Mesh sharedMesh = val.sharedMesh;
				int num = Shape(sharedMesh, "blink");
				if (num < 0)
				{
					num = Shape(sharedMesh, "Fac_Eye_Close");
				}
				if (num >= 0)
				{
					Face face = new Face
					{
						Renderer = val,
						Blink = num,
						Left = Shape(sharedMesh, "eyes_look_left"),
						Right = Shape(sharedMesh, "eyes_look_right"),
						Up = Shape(sharedMesh, "eyes_look_up"),
						Down = Shape(sharedMesh, "eyes_look_down")
					};
					morphGaze |= face.Left >= 0 && face.Right >= 0;
					faces.Add(face);
				}
			}
		}
		PromiseAdaptiveLighting component = ((Component)this).GetComponent<PromiseAdaptiveLighting>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return;
		}
		component.Rebind();
		component.BindContext(delegate
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			bool factory = Object.op_Implicit((Object)(object)enemy) && !((EnemyAI)enemy).isOutside;
			int ship;
			if (Object.op_Implicit((Object)(object)enemy) && Object.op_Implicit((Object)(object)StartOfRound.Instance) && Object.op_Implicit((Object)(object)StartOfRound.Instance.shipInnerRoomBounds))
			{
				Bounds bounds = StartOfRound.Instance.shipInnerRoomBounds.bounds;
				ship = (((Bounds)(ref bounds)).Contains(((Component)enemy).transform.position) ? 1 : 0);
			}
			else
			{
				ship = 0;
			}
			return new PromiseLightingContext(factory, (byte)ship != 0);
		});
	}

	private void OnDestroy()
	{
		MaskedVanillaBadges.Release(vanillaBadges, (Object)(object)this);
	}

	private void LateUpdate()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: 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_0113: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00d7: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)enemy))
		{
			return;
		}
		vanillaBadges?.Hide();
		if (!Object.op_Implicit((Object)(object)sockets))
		{
			return;
		}
		Vector2 target = Vector2.zero;
		PlayerControllerB targetPlayer = ((EnemyAI)enemy).targetPlayer;
		if (!((EnemyAI)enemy).isEnemyDead && Plugin.Eyes.Value && Object.op_Implicit((Object)(object)targetPlayer) && !targetPlayer.isPlayerDead && Object.op_Implicit((Object)(object)sockets.Head))
		{
			target = NaturalEyeMath.Target((Object.op_Implicit((Object)(object)targetPlayer.playerEye) ? targetPlayer.playerEye.position : (((Component)targetPlayer).transform.position + Vector3.up * 1.5f)) - sockets.Head.position, sockets.Forward, sockets.Up);
		}
		gaze = NaturalEyeMath.Smooth(gaze, target, Time.deltaTime);
		sockets.Aim(morphGaze ? Vector2.zero : gaze);
		if (Time.time >= nextBlink)
		{
			blinkStart = Time.time;
			nextBlink = Time.time + Random.Range(2.5f, 6f);
		}
		float num = Time.time - blinkStart;
		float value = ((!((EnemyAI)enemy).isEnemyDead && Plugin.Blink.Value && num >= 0f && num < 0.18f) ? (Mathf.Sin(num / 0.18f * (float)Math.PI) * 100f) : 0f);
		foreach (Face face in faces)
		{
			Set(face, face.Blink, value);
			Set(face, face.Left, Mathf.Max(0f, (0f - gaze.x) / 12f) * 20f);
			Set(face, face.Right, Mathf.Max(0f, gaze.x / 12f) * 20f);
			Set(face, face.Up, Mathf.Max(0f, (0f - gaze.y) / 7f) * 15f);
			Set(face, face.Down, Mathf.Max(0f, gaze.y / 9f) * 15f);
		}
	}
}
public static class MaskedCloneIsolation
{
	private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static bool IsOwner(Type type)
	{
		Type type2 = type;
		while (type2 != null)
		{
			if (type2.Name == "PlayerControllerB" || type2.Name == "BodyReplacementBase")
			{
				return true;
			}
			type2 = type2.BaseType;
		}
		return false;
	}

	private static void Clear(Type type, MonoBehaviour component, string field, object value)
	{
		FieldInfo field2 = type.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field2 != null && !field2.IsInitOnly)
		{
			field2.SetValue(component, value);
		}
	}

	public static void Detach(GameObject clone, string ownNamespace)
	{
		MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val in componentsInChildren)
		{
			if (!Object.op_Implicit((Object)(object)val) || ((object)val).GetType().Namespace != ownNamespace)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			bool flag = false;
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (IsOwner(fieldInfo.FieldType))
				{
					if (!fieldInfo.IsInitOnly)
					{
						fieldInfo.SetValue(val, null);
					}
					flag = true;
				}
			}
			if (flag || type.Name.EndsWith("ReactionFace", StringComparison.Ordinal) || type.Name.Contains("HeadTracking") || type.Name.EndsWith("Face", StringComparison.Ordinal) || type.Name.Contains("FirstPerson") || type.Name.Contains("RenderDiagnostics") || type.Name.Contains("RuntimeMotionAudit"))
			{
				((Behaviour)val).enabled = false;
			}
			if (type.Name.EndsWith("OutfitState", StringComparison.Ordinal))
			{
				Clear(type, val, "HasPlayerBinding", false);
				Clear(type, val, "Corpse", false);
				Clear(type, val, "SourceState", null);
				Clear(type, val, "AutomaticEars", false);
				type.GetMethod("Rebind", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(val, null);
			}
		}
	}
}
public static class MaskedVanillaBadges
{
	public sealed class Binding
	{
		internal GameObject Enemy;

		internal object[] State;

		public void Hide()
		{
			MeshRenderer[] array = (MeshRenderer[])State[1];
			foreach (MeshRenderer val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Renderer)val).enabled)
				{
					((Renderer)val).enabled = false;
				}
			}
		}
	}

	private const string Chest = "ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/";

	private const string StateKey = "RaidNight.SuitMods.MaskedVanillaBadges.v1";

	private static Dictionary<GameObject, object[]> Active
	{
		get
		{
			Dictionary<GameObject, object[]> dictionary = AppDomain.CurrentDomain.GetData("RaidNight.SuitMods.MaskedVanillaBadges.v1") as Dictionary<GameObject, object[]>;
			if (dictionary == null)
			{
				dictionary = new Dictionary<GameObject, object[]>();
				AppDomain.CurrentDomain.SetData("RaidNight.SuitMods.MaskedVanillaBadges.v1", dictionary);
			}
			return dictionary;
		}
	}

	public static Binding Bind(GameObject enemy, Object owner)
	{
		if (!Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit(owner))
		{
			return null;
		}
		if (Active.TryGetValue(enemy, out var value))
		{
			value[0] = owner;
			Binding binding = new Binding();
			binding.Enemy = enemy;
			binding.State = value;
			binding.Hide();
			return binding;
		}
		List<MeshRenderer> list = new List<MeshRenderer>();
		string[] array = new string[2] { "LevelSticker", "BetaBadge" };
		foreach (string text in array)
		{
			Transform val = enemy.transform.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/" + text);
			MeshRenderer val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<MeshRenderer>() : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				list.Add(val2);
			}
		}
		bool[] array2 = new bool[list.Count];
		for (int j = 0; j < list.Count; j++)
		{
			array2[j] = ((Renderer)list[j]).enabled;
		}
		object[] array3 = new object[3]
		{
			owner,
			list.ToArray(),
			array2
		};
		Binding obj = new Binding
		{
			Enemy = enemy,
			State = array3
		};
		Active.Add(enemy, array3);
		obj.Hide();
		return obj;
	}

	public static void Release(Binding binding, Object owner)
	{
		if (binding == null || binding.State[0] != owner || !Active.TryGetValue(binding.Enemy, out var value) || value != binding.State)
		{
			return;
		}
		Active.Remove(binding.Enemy);
		MeshRenderer[] array = (MeshRenderer[])binding.State[1];
		bool[] array2 = (bool[])binding.State[2];
		for (int i = 0; i < array.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)array[i]))
			{
				((Renderer)array[i]).enabled = array2[i];
			}
		}
	}
}
public static class NaturalEyeMath
{
	public const float YawLimit = 12f;

	public const float UpLimit = 7f;

	public const float DownLimit = 9f;

	public const float SocketLimit = 12f;

	public const float MorphHorizontal = 20f;

	public const float MorphVertical = 15f;

	private static bool Finite(float v)
	{
		if (!float.IsNaN(v))
		{
			return !float.IsInfinity(v);
		}
		return false;
	}

	public static Vector2 Clamp(Vector2 angles)
	{
		//IL_0000: 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_000d: 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_003c: 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_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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		if (!Finite(angles.x) || !Finite(angles.y))
		{
			return Vector2.zero;
		}
		float num = ((angles.y < 0f) ? 7f : 9f);
		angles.x = Mathf.Clamp(angles.x, -12f, 12f);
		angles.y = Mathf.Clamp(angles.y, -7f, 9f);
		float num2 = Mathf.Sqrt(angles.x * angles.x / 144f + angles.y * angles.y / (num * num));
		if (!(num2 > 1f))
		{
			return angles;
		}
		return angles / num2;
	}

	public static Vector2 Target(Vector3 local)
	{
		//IL_0000: 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_000d: 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_0035: 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_004e: 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_0065: 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_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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: 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)
		if (!Finite(local.x) || !Finite(local.y) || !Finite(local.z) || ((Vector3)(ref local)).sqrMagnitude < 1E-10f || local.z <= 0f)
		{
			return Vector2.zero;
		}
		float num = Mathf.Atan2(local.x, local.z) * 57.29578f;
		float num2 = (0f - Mathf.Atan2(local.y, Mathf.Sqrt(local.x * local.x + local.z * local.z))) * 57.29578f;
		float num3 = Mathf.Max(Mathf.Abs(num), Mathf.Abs(num2));
		float num4 = 1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(60f, 90f, num3));
		return Clamp(new Vector2(num, num2)) * num4;
	}

	public static Vector2 Smooth(Vector2 current, Vector2 target, float dt)
	{
		//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_0006: 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_000e: 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_0022: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		current = Clamp(current);
		target = Clamp(target);
		if (!Finite(dt) || dt <= 0f)
		{
			return current;
		}
		return Clamp(Vector2.Lerp(current, target, 1f - Mathf.Exp((0f - Mathf.Min(dt, 0.1f)) * 12f)));
	}

	public static Vector2 Target(Vector3 direction, Vector3 forward, Vector3 up)
	{
		//IL_0032: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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_0038: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (!(((Vector3)(ref forward)).sqrMagnitude < 1E-08f) && !(((Vector3)(ref up)).sqrMagnitude < 1E-08f))
		{
			Vector3 val = Vector3.Cross(up, forward);
			if (!(((Vector3)(ref val)).sqrMagnitude < 1E-08f))
			{
				return Target(Quaternion.Inverse(Quaternion.LookRotation(forward, up)) * direction);
			}
		}
		return Vector2.zero;
	}

	public static void Apply(Transform eye, Quaternion neutral, Vector3 forward, Vector3 up, Vector2 angles)
	{
		//IL_0016: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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_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)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005c: 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_006d: 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_0070: 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)
		if (Object.op_Implicit((Object)(object)eye) && Object.op_Implicit((Object)(object)eye.parent))
		{
			angles = Clamp(angles);
			Quaternion val = Quaternion.LookRotation(forward, up);
			Quaternion val2 = Quaternion.Inverse(eye.parent.rotation) * val;
			Quaternion val3 = val2 * Quaternion.Euler(angles.y, angles.x, 0f) * Quaternion.Inverse(val2) * neutral;
			eye.localRotation = Quaternion.RotateTowards(neutral, val3, 12f);
		}
	}
}
[DefaultExecutionOrder(10000)]
public sealed class NaturalEyeSockets : MonoBehaviour
{
	public Transform Left;

	public Transform Right;

	public Transform Head;

	public Quaternion LeftNeutral = Quaternion.identity;

	public Quaternion RightNeutral = Quaternion.identity;

	public Quaternion HeadToLook = Quaternion.identity;

	public bool Captured;

	public Vector3 Forward
	{
		get
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Head))
			{
				return ((Component)this).transform.forward;
			}
			return Head.rotation * HeadToLook * Vector3.forward;
		}
	}

	public Vector3 Up
	{
		get
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Head))
			{
				return ((Component)this).transform.up;
			}
			return Head.rotation * HeadToLook * Vector3.up;
		}
	}

	public static NaturalEyeSockets Ensure(GameObject model)
	{
		NaturalEyeSockets naturalEyeSockets = model.GetComponent<NaturalEyeSockets>();
		if (!Object.op_Implicit((Object)(object)naturalEyeSockets))
		{
			naturalEyeSockets = model.AddComponent<NaturalEyeSockets>();
		}
		naturalEyeSockets.Capture();
		return naturalEyeSockets;
	}

	private void Awake()
	{
		Capture();
	}

	public void Capture()
	{
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		if (Captured)
		{
			return;
		}
		Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>(true);
		if (Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman)
		{
			Head = componentInChildren.GetBoneTransform((HumanBodyBones)10);
			Left = componentInChildren.GetBoneTransform((HumanBodyBones)21);
			Right = componentInChildren.GetBoneTransform((HumanBodyBones)22);
		}
		Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == "head.x" || (!Object.op_Implicit((Object)(object)Head) && (((Object)val).name == "DEF-spine.006" || ((Object)val).name == "spine.004")))
			{
				Head = val;
			}
			if (((Object)val).name == "Skn_L_Eye")
			{
				Left = val;
			}
			if (((Object)val).name == "Skn_R_Eye")
			{
				Right = val;
			}
		}
		if (Object.op_Implicit((Object)(object)Left))
		{
			LeftNeutral = Left.localRotation;
		}
		if (Object.op_Implicit((Object)(object)Right))
		{
			RightNeutral = Right.localRotation;
		}
		Transform val2 = null;
		componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
		foreach (Transform val3 in componentsInChildren)
		{
			if (((Object)val3).name.EndsWith("GazeFrame", StringComparison.Ordinal))
			{
				val2 = val3;
				break;
			}
		}
		if (Object.op_Implicit((Object)(object)Head))
		{
			HeadToLook = Quaternion.Inverse(Head.rotation) * (Object.op_Implicit((Object)(object)val2) ? val2.rotation : ((Component)this).transform.rotation);
		}
		Captured = Object.op_Implicit((Object)(object)Head);
	}

	private static void Limit(Transform eye, Quaternion neutral)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)eye))
		{
			eye.localRotation = Quaternion.RotateTowards(neutral, eye.localRotation, 12f);
		}
	}

	private void LateUpdate()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		Capture();
		Limit(Left, LeftNeutral);
		Limit(Right, RightNeutral);
	}

	public void Aim(Vector2 angles)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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_0031: 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)
		Capture();
		NaturalEyeMath.Apply(Left, LeftNeutral, Forward, Up, angles);
		NaturalEyeMath.Apply(Right, RightNeutral, Forward, Up, angles);
	}
}
[Serializable]
public struct PromiseLightingContext
{
	public bool InsideFactory;

	public bool InsideShip;

	public bool Indoors
	{
		get
		{
			if (!InsideFactory)
			{
				return InsideShip;
			}
			return true;
		}
	}

	public float Floor
	{
		get
		{
			if (!Indoors)
			{
				return 0.075f;
			}
			return 0f;
		}
	}

	public PromiseLightingContext(bool factory, bool ship)
	{
		InsideFactory = factory;
		InsideShip = ship;
	}
}
public sealed class PromiseCorpseLightingContext
{
	private PromiseLightingContext context;

	private bool trackedItem;

	public PromiseCorpseLightingContext(PromiseLightingContext death)
	{
		context = death;
	}

	public PromiseLightingContext Observe(bool bodyInShip, bool hasHolder, PromiseLightingContext holder, bool hasItem, PromiseLightingContext item)
	{
		if (hasHolder)
		{
			context = holder;
			trackedItem = true;
		}
		else if (hasItem && trackedItem)
		{
			context = item;
		}
		if (!bodyInShip)
		{
			return context;
		}
		return new PromiseLightingContext(factory: false, ship: true);
	}
}
[DefaultExecutionOrder(600)]
public sealed class PromiseAdaptiveLighting : MonoBehaviour
{
	private struct Draw
	{
		public Renderer Renderer;

		public int Slot;

		public bool Floor;

		public bool Ink;

		public Color InkColor;
	}

	public Renderer[] receivers;

	private readonly List<Draw> draws = new List<Draw>();

	private MaterialPropertyBlock block;

	private Func<PromiseLightingContext> contextReader;

	private bool initialized;

	private static readonly int FloorId = Shader.PropertyToID("_GflAmbientFloor");

	private static readonly int InkId = Shader.PropertyToID("_InkColor");

	public PromiseLightingContext Context { get; private set; }

	public float CurrentFloor => Context.Floor;

	public int FloorSlots { get; private set; }

	public int InkSlots { get; private set; }

	private void Awake()
	{
		Rebind();
		Refresh();
	}

	private void OnEnable()
	{
		if (initialized)
		{
			Refresh();
		}
	}

	public void Rebind()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_00da: 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_00df: Unknown result type (might be due to invalid IL or missing references)
		if (block == null)
		{
			block = new MaterialPropertyBlock();
		}
		draws.Clear();
		int floorSlots = (InkSlots = 0);
		FloorSlots = floorSlots;
		receivers = ((Component)this).GetComponentsInChildren<Renderer>(true);
		Renderer[] array = receivers;
		foreach (Renderer val in array)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				Material val2 = sharedMaterials[i];
				if (!Object.op_Implicit((Object)(object)val2))
				{
					continue;
				}
				bool flag = val2.HasProperty(FloorId);
				bool flag2 = val2.HasProperty(InkId);
				if (flag || flag2)
				{
					draws.Add(new Draw
					{
						Renderer = val,
						Slot = i,
						Floor = flag,
						Ink = flag2,
						InkColor = (flag2 ? val2.GetColor(InkId) : Color.black)
					});
					if (flag)
					{
						FloorSlots++;
					}
					if (flag2)
					{
						InkSlots++;
					}
				}
			}
		}
		initialized = true;
		Apply(Context);
	}

	public void BindContext(Func<PromiseLightingContext> reader)
	{
		contextReader = reader;
		Refresh();
	}

	public PromiseLightingContext ReadContext()
	{
		if (contextReader == null)
		{
			return Context;
		}
		return contextReader();
	}

	public void InheritContext(PromiseAdaptiveLighting source)
	{
		if (Object.op_Implicit((Object)(object)source))
		{
			BindContext(source.ReadContext);
		}
	}

	public void Refresh()
	{
		Apply(ReadContext());
	}

	public void Apply(PromiseLightingContext context)
	{
		//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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized)
		{
			Rebind();
		}
		Context = context;
		foreach (Draw draw in draws)
		{
			if (!Object.op_Implicit((Object)(object)draw.Renderer))
			{
				continue;
			}
			block.Clear();
			draw.Renderer.GetPropertyBlock(block, draw.Slot);
			if (draw.Floor)
			{
				block.SetFloat(FloorId, context.Floor);
			}
			if (draw.Ink)
			{
				Color inkColor = draw.InkColor;
				if (context.Indoors)
				{
					((Color)(ref inkColor))..ctor(0f, 0f, 0f, inkColor.a);
				}
				block.SetColor(InkId, inkColor);
			}
			draw.Renderer.SetPropertyBlock(block, draw.Slot);
		}
	}

	private void LateUpdate()
	{
		Refresh();
	}
}
internal static class PromiseLightingControl
{
	private sealed class Death
	{
		internal ulong Owner;

		internal PromiseLightingContext Context;
	}

	private static readonly Dictionary<PlayerControllerB, Death> deaths = new Dictionary<PlayerControllerB, Death>();

	private static readonly FieldInfo sourceField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel");

	private static readonly FieldInfo shadowField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow");

	private static readonly FieldInfo viewField = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel");

	private static PromiseLightingContext Native(PlayerControllerB player)
	{
		if (!Object.op_Implicit((Object)(object)player))
		{
			return default(PromiseLightingContext);
		}
		return new PromiseLightingContext(player.isInsideFactory, player.isInHangarShipRoom);
	}

	internal static void Install(Harmony harmony)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Expected O, but got Unknown
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Expected O, but got Unknown
		harmony.Patch((MethodBase)AccessTools.Method(typeof(BodyReplacementBase), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PromiseLightingControl), "Created", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		MethodInfo methodInfo = AccessTools.Method(typeof(BodyReplacementBase), "LoadRagdollReplacement", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PromiseLightingControl), "Ragdoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PromiseLightingControl), "CaptureDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "SpawnDeadBody", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PromiseLightingControl), "CaptureRemoteDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(StartOfRound), "ReviveDeadPlayers", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PromiseLightingControl), "Clear", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void CaptureDeath(PlayerControllerB __instance)
	{
		if (Object.op_Implicit((Object)(object)__instance) && !__instance.isPlayerDead)
		{
			deaths[__instance] = new Death
			{
				Owner = ((NetworkBehaviour)__instance).OwnerClientId,
				Context = Native(__instance)
			};
		}
	}

	private static void CaptureRemoteDeath(PlayerControllerB deadPlayerController)
	{
		if (Object.op_Implicit((Object)(object)deadPlayerController) && !((NetworkBehaviour)deadPlayerController).IsOwner)
		{
			deaths[deadPlayerController] = new Death
			{
				Owner = ((NetworkBehaviour)deadPlayerController).OwnerClientId,
				Context = Native(deadPlayerController)
			};
		}
	}

	private static void Created(BodyReplacementBase __instance)
	{
		if (__instance is PromiseBody promiseBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)promiseBody).controller))
		{
			FieldInfo[] array = new FieldInfo[3] { sourceField, shadowField, viewField };
			for (int i = 0; i < array.Length; i++)
			{
				object? obj = array[i]?.GetValue(promiseBody);
				Bind((GameObject)((obj is GameObject) ? obj : null), ((BodyReplacementBase)promiseBody).controller);
			}
		}
	}

	internal static void AttachView(GameObject playerObject, GameObject view)
	{
		if (Object.op_Implicit((Object)(object)playerObject) && Object.op_Implicit((Object)(object)view) && Object.op_Implicit((Object)(object)view.GetComponent<PromiseAdaptiveLighting>()))
		{
			Bind(view, playerObject.GetComponent<PlayerControllerB>());
		}
	}

	private static void Ragdoll(BodyReplacementBase __instance, GameObject __result)
	{
		if (__instance is PromiseBody promiseBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)promiseBody).controller))
		{
			Bind(__result, ((BodyReplacementBase)promiseBody).controller, corpse: true);
		}
	}

	private static void Bind(GameObject model, PlayerControllerB player, bool corpse = false)
	{
		if (!Object.op_Implicit((Object)(object)model) || !Object.op_Implicit((Object)(object)player))
		{
			return;
		}
		PromiseAdaptiveLighting promiseAdaptiveLighting = model.GetComponent<PromiseAdaptiveLighting>() ?? model.AddComponent<PromiseAdaptiveLighting>();
		promiseAdaptiveLighting.Rebind();
		ulong owner = ((NetworkBehaviour)player).OwnerClientId;
		if (!corpse)
		{
			promiseAdaptiveLighting.BindContext(() => (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).OwnerClientId != owner) ? default(PromiseLightingContext) : Native(player));
			return;
		}
		Death value;
		PromiseLightingContext death = ((deaths.TryGetValue(player, out value) && value.Owner == owner) ? value.Context : Native(player));
		PromiseCorpseLightingContext corpseContext = new PromiseCorpseLightingContext(death);
		DeadBodyInfo nativeBody = player.deadBody;
		promiseAdaptiveLighting.BindContext(delegate
		{
			if (!Object.op_Implicit((Object)(object)nativeBody))
			{
				return corpseContext.Observe(bodyInShip: false, hasHolder: false, default(PromiseLightingContext), hasItem: false, default(PromiseLightingContext));
			}
			GrabbableObject grabBodyObject = nativeBody.grabBodyObject;
			PlayerControllerB val = ((Object.op_Implicit((Object)(object)grabBodyObject) && grabBodyObject.isHeld) ? grabBodyObject.playerHeldBy : null);
			return corpseContext.Observe(nativeBody.isInShip || nativeBody.parentedToShip, Object.op_Implicit((Object)(object)val), Native(val), Object.op_Implicit((Object)(object)grabBodyObject), Object.op_Implicit((Object)(object)grabBodyObject) ? new PromiseLightingContext(grabBodyObject.isInFactory, grabBodyObject.isInShipRoom) : default(PromiseLightingContext));
		});
	}

	internal static void Clear()
	{
		deaths.Clear();
	}
}
public enum AttentionKind
{
	Player,
	Enemy,
	Item
}
public struct AttentionCandidate
{
	public int Key;

	public AttentionKind Kind;

	public float Distance;

	public bool Speaking;

	public bool Eligible;

	public AttentionCandidate(int key, AttentionKind kind, float distance, bool speaking = true, bool eligible = true)
	{
		Key = key;
		Kind = kind;
		Distance = distance;
		Speaking = speaking;
		Eligible = eligible;
	}
}
public sealed class PromiseAttentionSelection
{
	private float lastSpeech;

	private float selectedAt;

	public int CurrentKey { get; private set; }

	public bool HasTarget { get; private set; }

	public AttentionKind CurrentKind { get; private set; }

	public void Reset()
	{
		HasTarget = false;
		CurrentKey = 0;
		lastSpeech = (selectedAt = 0f);
	}

	public int Choose(IList<AttentionCandidate> candidates, float now, float pauseHold = 1.2f)
	{
		AttentionCandidate attentionCandidate = default(AttentionCandidate);
		AttentionCandidate c = default(AttentionCandidate);
		AttentionCandidate c2 = default(AttentionCandidate);
		bool flag = false;
		bool flag2 = false;
		bool flag3 = false;
		foreach (AttentionCandidate candidate in candidates)
		{
			if (!candidate.Eligible || float.IsNaN(candidate.Distance) || float.IsInfinity(candidate.Distance) || candidate.Distance < 0f)
			{
				continue;
			}
			if (HasTarget && candidate.Key == CurrentKey && candidate.Kind == CurrentKind)
			{
				attentionCandidate = candidate;
				flag = true;
			}
			if (candidate.Kind == AttentionKind.Player)
			{
				if (candidate.Speaking && (!flag2 || candidate.Distance < c.Distance))
				{
					c = candidate;
					flag2 = true;
				}
			}
			else if (!flag3 || candidate.Kind < c2.Kind || (candidate.Kind == c2.Kind && candidate.Distance < c2.Distance))
			{
				c2 = candidate;
				flag3 = true;
			}
		}
		if (flag && attentionCandidate.Kind == AttentionKind.Player && attentionCandidate.Speaking)
		{
			lastSpeech = now;
		}
		if (flag2)
		{
			if (flag && attentionCandidate.Kind == AttentionKind.Player && attentionCandidate.Speaking && (now - selectedAt < 0.65f || c.Distance >= attentionCandidate.Distance * 0.7f))
			{
				return CurrentKey;
			}
			return Select(c, now);
		}
		if (flag && attentionCandidate.Kind == AttentionKind.Player && now - lastSpeech <= Mathf.Clamp(pauseHold, 0f, 5f))
		{
			return CurrentKey;
		}
		if (flag3)
		{
			if (flag && attentionCandidate.Kind == c2.Kind && attentionCandidate.Kind != AttentionKind.Player && (now - selectedAt < 1.5f || c2.Distance >= attentionCandidate.Distance * 0.7f))
			{
				return CurrentKey;
			}
			return Select(c2, now);
		}
		Reset();
		return 0;
	}

	private int Select(AttentionCandidate c, float now)
	{
		if (!HasTarget || c.Key != CurrentKey || c.Kind != CurrentKind)
		{
			selectedAt = now;
		}
		HasTarget = true;
		CurrentKey = c.Key;
		CurrentKind = c.Kind;
		if (c.Kind == AttentionKind.Player && c.Speaking)
		{
			lastSpeech = now;
		}
		return CurrentKey;
	}

	public static bool InView(Vector3 origin, Vector3 forward, Vector3 point, float radius)
	{
		//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_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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = point - origin;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		if (sqrMagnitude < 0.0225f || sqrMagnitude > radius * radius)
		{
			return false;
		}
		Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up);
		Vector3 val3 = Vector3.ProjectOnPlane(forward, Vector3.up);
		if (Vector3.Angle(val2, val3) <= 65f)
		{
			return Mathf.Abs(Mathf.Atan2(val.y, ((Vector3)(ref val2)).magnitude) * 57.29578f) <= 60f;
		}
		return false;
	}

	public static bool ActiveSpeech(bool speaking, float amplitude)
	{
		if (speaking && !float.IsNaN(amplitude) && !float.IsInfinity(amplitude))
		{
			return amplitude >= 0.002f;
		}
		return false;
	}

	public static bool Visible(Vector3 origin, Vector3 point, int mask, Transform observer, Transform model, Transform target, RaycastHit[] hits)
	{
		//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_001a: 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)
		Vector3 val = point - origin;
		float magnitude = ((Vector3)(ref val)).magnitude;
		if (magnitude < 0.05f)
		{
			return true;
		}
		int num = Physics.RaycastNonAlloc(origin, val / magnitude, hits, magnitude, mask, (QueryTriggerInteraction)1);
		if (num == hits.Length)
		{
			return false;
		}
		for (int i = 0; i < num; i++)
		{
			Transform transform = ((RaycastHit)(ref hits[i])).transform;
			if (Object.op_Implicit((Object)(object)transform) && (!Object.op_Implicit((Object)(object)observer) || !transform.IsChildOf(observer)) && (!Object.op_Implicit((Object)(object)model) || !transform.IsChildOf(model)) && (!Object.op_Implicit((Object)(object)target) || !transform.IsChildOf(target)))
			{
				return false;
			}
		}
		return true;
	}
}
public sealed class PromiseAttention
{
	private sealed class ItemRenderer
	{
		public GrabbableObject Item;

		public Renderer Renderer;
	}

	private readonly PromiseAttentionSelection selection = new PromiseAttentionSelection();

	private readonly List<AttentionCandidate> candidates = new List<AttentionCandidate>(64);

	private readonly Dictionary<int, Object> objects = new Dictionary<int, Object>();

	private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[24];

	private static EnemyAI[] enemies = (EnemyAI[])(object)new EnemyAI[0];

	private static GrabbableObject[] items = (GrabbableObject[])(object)new GrabbableObject[0];

	private static float nextSceneScan;

	private static StartOfRound scene;

	private static readonly Dictionary<int, ItemRenderer> itemRenderers = new Dictionary<int, ItemRenderer>();

	private static readonly HashSet<int> aliveItems = new HashSet<int>();

	private static readonly List<int> staleItems = new List<int>();

	private Object target;

	private float nextScan;

	public void Reset()
	{
		selection.Reset();
		target = null;
		nextScan = 0f;
	}

	private static void ScanScene(float now)
	{
		if ((Object)(object)scene != (Object)(object)StartOfRound.Instance)
		{
			scene = StartOfRound.Instance;
			nextSceneScan = 0f;
			itemRenderers.Clear();
		}
		if (now < nextSceneScan)
		{
			return;
		}
		nextSceneScan = now + 1f;
		enemies = PromiseSceneCache.Enemies(now);
		items = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0);
		aliveItems.Clear();
		GrabbableObject[] array = items;
		foreach (GrabbableObject val in array)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				aliveItems.Add(((Object)val).GetInstanceID());
			}
		}
		staleItems.Clear();
		foreach (KeyValuePair<int, ItemRenderer> itemRenderer in itemRenderers)
		{
			if (!aliveItems.Contains(itemRenderer.Key))
			{
				staleItems.Add(itemRenderer.Key);
			}
		}
		foreach (int staleItem in staleItems)
		{
			itemRenderers.Remove(staleItem);
		}
	}

	internal static void ClearSceneCache()
	{
		scene = null;
		nextSceneScan = 0f;
		enemies = (EnemyAI[])(object)new EnemyAI[0];
		items = (GrabbableObject[])(object)new GrabbableObject[0];
		itemRenderers.Clear();
		aliveItems.Clear();
		staleItems.Clear();
	}

	private static Vector3 Point(Object value)
	{
		//IL_003d: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = (PlayerControllerB)(object)((value is PlayerControllerB) ? value : null);
		if (val != null)
		{
			if (!Object.op_Implicit((Object)(object)val.playerEye))
			{
				return ((Component)val).transform.position + Vector3.up * 1.6f;
			}
			return val.playerEye.position;
		}
		EnemyAI val2 = (EnemyAI)(object)((value is EnemyAI) ? value : null);
		if (val2 != null)
		{
			if (!Object.op_Implicit((Object)(object)val2.eye))
			{
				return ((Component)val2).transform.position + Vector3.up;
			}
			return val2.eye.position;
		}
		GrabbableObject val3 = (GrabbableObject)(object)((value is GrabbableObject) ? value : null);
		if (val3 != null)
		{
			int instanceID = ((Object)val3).GetInstanceID();
			if (!itemRenderers.TryGetValue(instanceID, out var value2) || (Object)(object)value2.Item != (Object)(object)val3)
			{
				value2 = new ItemRenderer
				{
					Item = val3,
					Renderer = ((Component)val3).GetComponentInChildren<Renderer>()
				};
				itemRenderers[instanceID] = value2;
			}
			if (!Object.op_Implicit((Object)(object)value2.Renderer))
			{
				return ((Component)val3).transform.position;
			}
			Bounds bounds = value2.Renderer.bounds;
			return ((Bounds)(ref bounds)).center;
		}
		return Vector3.zero;
	}

	private void Add(Component value, AttentionKind kind, Vector3 origin, Vector3 forward, float range, bool speaking, PlayerControllerB owner, Transform model)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0031: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Point((Object)(object)value);
		if (PromiseAttentionSelection.InView(origin, forward, val, range))
		{
			int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5));
			if (PromiseAttentionSelection.Visible(origin, val, mask, ((Component)owner).transform, model, value.transform, hits))
			{
				int instanceID = ((Object)value).GetInstanceID();
				objects[instanceID] = (Object)(object)value;
				candidates.Add(new AttentionCandidate(instanceID, kind, Vector3.Distance(origin, val), speaking));
			}
		}
	}

	public bool Resolve(PlayerControllerB owner, Transform model, Vector3 origin, Vector3 forward, float now, out Vector3 direction)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		direction = forward;
		if (!Object.op_Implicit((Object)(object)owner) || owner.isPlayerDead || !owner.isPlayerControlled || !Object.op_Implicit((Object)(object)StartOfRound.Instance))
		{
			Reset();
			return false;
		}
		if (now >= nextScan)
		{
			nextScan = now + 0.1f;
			candidates.Clear();
			objects.Clear();
			ScanScene(now);
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)owner) && val.isPlayerControlled && !val.isPlayerDead && ((Component)val).gameObject.activeInHierarchy)
				{
					bool flag = PromiseVoiceActivity.IsSpeaking(val);
					if (flag || (selection.HasTarget && selection.CurrentKind == AttentionKind.Player && selection.CurrentKey == ((Object)val).GetInstanceID()))
					{
						Add((Component)(object)val, AttentionKind.Player, origin, forward, Plugin.TalkingPlayersRange.Value, flag, owner, model);
					}
				}
			}
			EnemyAI[] array = enemies;
			foreach (EnemyAI val2 in array)
			{
				if (Object.op_Implicit((Object)(object)val2) && !val2.isEnemyDead && ((Behaviour)val2).isActiveAndEnabled)
				{
					Add((Component)(object)val2, AttentionKind.Enemy, origin, forward, Plugin.EnemiesRange.Value, speaking: false, owner, model);
				}
			}
			GrabbableObject[] array2 = items;
			foreach (GrabbableObject val3 in array2)
			{
				if (Object.op_Implicit((Object)(object)val3) && !val3.isHeld && !val3.isPocketed && !val3.isHeldByEnemy && ((Behaviour)val3).isActiveAndEnabled)
				{
					Add((Component)(object)val3, AttentionKind.Item, origin, forward, Plugin.ItemsRange.Value, speaking: false, owner, model);
				}
			}
			int key = selection.Choose(candidates, now, Plugin.SpeechPauseHold.Value);
			target = ((selection.HasTarget && objects.TryGetValue(key, out var value)) ? value : null);
		}
		if (!Object.op_Implicit(target))
		{
			return false;
		}
		Object obj = target;
		PlayerControllerB val4 = (PlayerControllerB)(object)((obj is PlayerControllerB) ? obj : null);
		if (val4 == null || (val4.isPlayerControlled && !val4.isPlayerDead))
		{
			Object obj2 = target;
			EnemyAI val5 = (EnemyAI)(object)((obj2 is EnemyAI) ? obj2 : null);
			if (val5 == null || !val5.isEnemyDead)
			{
				Object obj3 = target;
				GrabbableObject val6 = (GrabbableObject)(object)((obj3 is GrabbableObject) ? obj3 : null);
				if (val6 == null || (!val6.isHeld && !val6.isPocketed && !val6.isHeldByEnemy))
				{
					direction = Point(target) - origin;
					return ((Vector3)(ref direction)).sqrMagnitude > 1E-06f;
				}
			}
		}
		target = null;
		selection.Reset();
		nextScan = 0f;
		return false;
	}
}
internal static class PromiseVoiceActivity
{
	private static object comms;

	private static readonly Dictionary<int, float> retry = new Dictionary<int, float>();

	private static readonly Dictionary<int, object> states = new Dictionary<int, object>();

	internal static bool IsSpeaking(PlayerControllerB player)
	{
		object obj = PromiseFace.Read(player, "voicePlayerState") ?? PromiseFace.Read(PromiseFace.Read(player, "currentVoiceChatIngameSettings"), "_playerState");
		int instanceID = ((Object)player).GetInstanceID();
		if (obj == null && states.TryGetValue(instanceID, out var value))
		{
			obj = value;
		}
		if (obj == null && (!retry.TryGetValue(instanceID, out var value2) || Time.unscaledTime >= value2))
		{
			retry[instanceID] = Time.unscaledTime + 1f;
			comms = PromiseFace.Read(StartOfRound.Instance, "voiceChatModule");
			if (comms != null)
			{
				string text = (((NetworkBehaviour)player).IsOwner ? (PromiseFace.Read(comms, "LocalPlayerName") as string) : (PromiseFace.Read(player, "voicePlayerName") as string));
				if (!string.IsNullOrEmpty(text))
				{
					try
					{
						obj = PromiseRuntimeMembers.CallString(comms, "FindPlayer", text);
						if (obj != null)
						{
							states[instanceID] = obj;
						}
					}
					catch
					{
					}
				}
			}
		}
		bool value3;
		bool flag = PromiseRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3;
		if (PromiseRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4)
		{
			return false;
		}
		if (!PromiseRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5))
		{
			return flag;
		}
		return PromiseAttentionSelection.ActiveSpeech(flag, value5);
	}

	internal static void Clear()
	{
		comms = null;
		retry.Clear();
		states.Clear();
	}
}
public static class PromiseClockMath
{
	public static float Minutes(float normalized, float hours)
	{
		if (float.IsNaN(normalized) || float.IsInfinity(normalized) || float.IsNaN(hours) || float.IsInfinity(hours) || hours <= 0f)
		{
			return 360f;
		}
		return Mathf.Clamp(normalized * 60f * hours + 360f, 360f, 1440f);
	}

	public static Vector3 Angles(float minutes)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		if (float.IsNaN(minutes) || float.IsInfinity(minutes))
		{
			minutes = 360f;
		}
		return new Vector3(Mathf.Repeat(minutes, 720f) * 0.5f, Mathf.Repeat(minutes, 60f) * 6f, Mathf.Repeat(minutes * 60f, 60f) * 6f);
	}
}
[DefaultExecutionOrder(850)]
public sealed class PromiseClock : MonoBehaviour
{
	[Serializable]
	public class Hand
	{
		public Transform Bone;

		public Quaternion Neutral = Quaternion.identity;

		public Vector3 Axis;

		public Vector3 Up;

		public Vector3 RestDirection;
	}

	public Hand Hour;

	public Hand Minute;

	public Hand Second;

	public float LastGameMinutes = 360f;

	public bool HasGameTime;

	private PromiseOutfitState state;

	public bool SyncEnabled { get; private set; }

	public void SetMinutes(float minutes)
	{
		//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)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		LastGameMinutes = minutes;
		Vector3 val = PromiseClockMath.Angles(minutes);
		Apply(Hour, val.x);
		Apply(Minute, val.y);
		Apply(Second, val.z);
	}

	private static void Apply(Hand hand, float clockwiseDegrees)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		if (hand != null && Object.op_Implicit((Object)(object)hand.Bone))
		{
			hand.Bone.localRotation = Quaternion.AngleAxis(clockwiseDegrees, hand.Axis) * Quaternion.FromToRotation(hand.RestDirection, hand.Up) * hand.Neutral;
		}
	}

	private static void Restore(Hand hand)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (hand != null && Object.op_Implicit((Object)(object)hand.Bone))
		{
			hand.Bone.localRotation = hand.Neutral;
		}
	}

	public void UpdateClock(float minutes)
	{
		if (!Object.op_Implicit((Object)(object)state))
		{
			state = ((Component)this).GetComponent<PromiseOutfitState>();
		}
		LastGameMinutes = minutes;
		SyncEnabled = Object.op_Implicit((Object)(object)state) && (state.AlternateMask & 4) != 0;
		if (SyncEnabled)
		{
			SetMinutes(minutes);
			return;
		}
		Restore(Hour);
		Restore(Minute);
		Restore(Second);
	}

	private void LateUpdate()
	{
		float minutes = LastGameMinutes;
		TimeOfDay instance = TimeOfDay.Instance;
		if (Object.op_Implicit((Object)(object)instance))
		{
			HasGameTime = true;
			minutes = PromiseClockMath.Minutes(instance.normalizedTimeOfDay, instance.numberOfHours);
		}
		UpdateClock(minutes);
	}
}
public enum PromiseExpression : byte
{
	Neutral,
	Frightened,
	Hurt,
	Happy,
	Surprised,
	VeryHappy,
	Dead
}
public struct PromiseExpressionContext
{
	public bool Dead;

	public bool Critical;

	public bool EnemyNear;

	public bool Fear;

	public bool Chased;

	public bool Dancing;

	public bool Unsafe
	{
		get
		{
			if (!EnemyNear && !Fear)
			{
				return Chased;
			}
			return true;
		}
	}
}
public sealed class PromiseExpressionSelection
{
	private double hurtUntil = -1.0;

	private double treasureUntil = -1.0;

	private bool surprised = true;

	private int pickups;

	public void Damage(double now)
	{
		hurtUntil = now + 2.0;
	}

	public void PickedUp(int value, double now)
	{
		if (value > 100)
		{
			treasureUntil = now + 3.5;
			surprised = pickups++ % 2 == 0;
		}
	}

	public void Reset()
	{
		hurtUntil = (treasureUntil = -1.0);
		pickups = 0;
		surprised = true;
	}

	public PromiseExpression Choose(PromiseExpressionContext c, double now)
	{
		if (c.Dead)
		{
			return PromiseExpression.Dead;
		}
		if (c.Critical || now < hurtUntil)
		{
			return PromiseExpression.Hurt;
		}
		if (c.Unsafe)
		{
			return PromiseExpression.Frightened;
		}
		if (now < treasureUntil)
		{
			if (!surprised)
			{
				return PromiseExpression.VeryHappy;
			}
			return PromiseExpression.Surprised;
		}
		if (c.Dancing)
		{
			return PromiseExpression.Happy;
		}
		return PromiseExpression.Neutral;
	}
}
public struct PromiseExpressionWeight
{
	public string Shape;

	public float Weight;

	public bool Eyes;

	public bool Mouth;

	public PromiseExpressionWeight(string shape, float weight, bool eyes = false, bool mouth = false)
	{
		Shape = "expr_" + shape;
		Weight = weight;
		Eyes = eyes;
		Mouth = mouth;
	}
}
public static class PromiseExpressionProfiles
{
	private static readonly PromiseExpressionWeight[][] profiles = new PromiseExpressionWeight[7][]
	{
		new PromiseExpressionWeight[0],
		new PromiseExpressionWeight[4]
		{
			B("worry", 0.75f),
			B("brow_up", 0.25f),
			E("surprise", 0.85f),
			M("triangle", 0.6f)
		},
		new PromiseExpressionWeight[4]
		{
			B("worry", 0.85f),
			B("serious", 0.25f),
			E("focus", 0.45f),
			M("clench", 0.8f)
		},
		new PromiseExpressionWeight[3]
		{
			B("happy_brows", 0.45f),
			E("smile_eyes", 0.65f),
			M("smile", 0.85f)
		},
		new PromiseExpressionWeight[3]
		{
			B("brow_up", 0.65f),
			E("surprise", 0.9f),
			M("o", 0.65f)
		},
		new PromiseExpressionWeight[3]
		{
			B("happy_brows", 0.65f),
			E("smile_eyes", 0.85f),
			M("laugh", 0.85f)
		},
		new PromiseExpressionWeight[2]
		{
			B("worry", 0.7f),
			M("clench", 0.55f)
		}
	};

	private static PromiseExpressionWeight B(string n, float w)
	{
		return new PromiseExpressionWeight(n, w);
	}

	private static PromiseExpressionWeight E(string n, float w)
	{
		return new PromiseExpressionWeight(n, w, eyes: true);
	}

	private static PromiseExpressionWeight M(string n, float w)
	{
		return new PromiseExpressionWeight(n, w, eyes: false, mouth: true);
	}

	public static PromiseExpressionWeight[] Weights(PromiseExpression state)
	{
		return profiles[(uint)state];
	}
}
public sealed class PromiseExpressionMixer
{
	private sealed class Binding
	{
		public SkinnedMeshRenderer Renderer;

		public int[] Indices;

		public int Blink;

		public int Open;

		public int Round;
	}

	private readonly List<string> shapes = new List<string>();

	private readonly Dictionary<string, int> slots = new Dictionary<string, int>();

	private readonly List<Binding> bindings = new List<Binding>();

	private float[] values;

	private float[] target;

	private bool[] eyes;

	private bool[] mouth;

	public PromiseExpressionMixer(GameObject model)
	{
		foreach (PromiseExpression value in Enum.GetValues(typeof(PromiseExpression)))
		{
			PromiseExpressionWeight[] array = PromiseExpressionProfiles.Weights(value);
			for (int i = 0; i < array.Length; i++)
			{
				PromiseExpressionWeight promiseExpressionWeight = array[i];
				if (!slots.ContainsKey(promiseExpressionWeight.Shape))
				{
					slots[promiseExpressionWeight.Shape] = shapes.Count;
					shapes.Add(promiseExpressionWeight.Shape);
				}
			}
		}
		values = new float[shapes.Count];
		target = new float[shapes.Count];
		eyes = new bool[shapes.Count];
		mouth = new bool[shapes.Count];
		foreach (PromiseExpression value2 in Enum.GetValues(typeof(PromiseExpression)))
		{
			PromiseExpressionWeight[] array = PromiseExpressionProfiles.Weights(value2);
			for (int i = 0; i < array.Length; i++)
			{
				PromiseExpressionWeight promiseExpressionWeight2 = array[i];
				int num = slots[promiseExpressionWeight2.Shape];
				eyes[num] |= promiseExpressionWeight2.Eyes;
				mouth[num] |= promiseExpressionWeight2.Mouth;
			}
		}
		SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			if (Object.op_Implicit((Object)(object)val.sharedMesh) && !PromiseInkOutline.IsInk(val))
			{
				Binding binding = new Binding
				{
					Renderer = val,
					Indices = new int[shapes.Count],
					Blink = val.sharedMesh.GetBlendShapeIndex("blink"),
					Open = val.sharedMesh.GetBlendShapeIndex("speech_open"),
					Round = val.sharedMesh.GetBlendShapeIndex("speech_round")
				};
				for (int j = 0; j < shapes.Count; j++)
				{
					binding.Indices[j] = val.sharedMesh.GetBlendShapeIndex(shapes[j]);
				}
				bindings.Add(binding);
			}
		}
	}

	public void Step(PromiseExpression state, float delta, bool immediate = false)
	{
		Array.Clear(target, 0, target.Length);
		PromiseExpressionWeight[] array = PromiseExpressionProfiles.Weights(state);
		for (int i = 0; i < array.Length; i++)
		{
			PromiseExpressionWeight promiseExpressionWeight = array[i];
			target[slots[promiseExpressionWeight.Shape]] = promiseExpressionWeight.Weight;
		}
		float num = ((immediate || state == PromiseExpression.Dead) ? 1f : (1f - Mathf.Exp((0f - Mathf.Clamp(delta, 0f, 0.1f)) * 13f)));
		for (int j = 0; j < values.Length; j++)
		{
			values[j] = Mathf.Lerp(values[j], target[j], num);
		}
		foreach (Binding binding in bindings)
		{
			if (!Object.op_Implicit((Object)(object)binding.Renderer))
			{
				continue;
			}
			float num2 = ((binding.Blink < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Blink) / 100f));
			float num3 = ((binding.Open < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Open) / 85f));
			if (state == PromiseExpression.Dead)
			{
				num2 = 1f;
				num3 = 0f;
				if (binding.Blink >= 0)
				{
					binding.Renderer.SetBlendShapeWeight(binding.Blink, 100f);
				}
				if (binding.Open >= 0)
				{
					binding.Renderer.SetBlendShapeWeight(binding.Open, 0f);
				}
				if (binding.Round >= 0)
				{
					binding.Renderer.SetBlendShapeWeight(binding.Round, 0f);
				}
			}
			for (int k = 0; k < values.Length; k++)
			{
				if (binding.Indices[k] >= 0)
				{
					float num4 = values[k];
					if (eyes[k])
					{
						num4 *= 1f - num2;
					}
					if (mouth[k])
					{
						num4 *= 1f - num3 * 0.55f;
					}
					binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num4 * 100f);
				}
			}
		}
	}
}
[DefaultExecutionOrder(280)]
public sealed class PromiseDeathFace : MonoBehaviour
{
	private PromiseExpressionMixer mixer;

	public void Initialize()
	{
		mixer = new PromiseExpressionMixer(((Component)this).gameObject);
		mixer.Step(PromiseExpression.Dead, 0f, immediate: true);
	}

	private void LateUpdate()
	{
		if (mixer == null)
		{
			Initialize();
		}
		mixer.Step(PromiseExpression.Dead, 0f, immediate: true);
	}
}
public struct PromiseExpressionRecord
{
	public ulong PlayerId;

	public ulong Owner;

	public byte Character;

	public PromiseExpression Expression;

	public uint Revision;
}
public sealed class PromiseExpressionStore
{
	private sealed class Entry
	{
		public PromiseExpressionRecord Record;

		public double At;
	}

	private readonly Dictionary<ulong, Entry> records = new Dictionary<ulong, Entry>();

	public bool Accept(ulong sender, ulong actualOwner, PromiseExpressionRecord value, double now)
	{
		if (sender != actualOwner || value.Owner != actualOwner || value.Character >= PromiseOutfitProtocol.Characters.Length || (int)value.Expression > 6 || double.IsNaN(now) || double.IsInfinity(now))
		{
			return false;
		}
		if (records.TryGetValue(value.PlayerId, out var value2) && value2.Record.Owner == actualOwner && (value.Revision < value2.Record.Revision || (value.Revision == value2.Record.Revision && (value.Character != value2.Record.Character || value.Expression != value2.Record.Expression))))
		{
			return false;
		}
		records[value.PlayerId] = new Entry
		{
			Record = value,
			At = now
		};
		return true;
	}

	public bool TryGet(ulong id, double now, out PromiseExpressionRecord value)
	{
		value = default(PromiseExpressionRecord);
		if (!records.TryGetValue(id, out var value2) || now - value2.At > 5.0 || now < value2.At)
		{
			return false;
		}
		value = value2.Record;
		return true;
	}

	public uint NextRevision(ulong id, ulong owner)
	{
		if (!records.TryGetValue(id, out var value) || value.Record.Owner != owner)
		{
			return 1u;
		}
		return value.Record.Revision + 1;
	}

	public PromiseExpressionRecord[] Snapshot(double now)
	{
		List<PromiseExpressionRecord> list = new List<PromiseExpressionRecord>();
		foreach (Entry value in records.Values)
		{
			if (now >= value.At && now - value.At <= 5.0)
			{
				list.Add(value.Record);
			}
		}
		list.Sort((PromiseExpressionRecord a, PromiseExpressionRecord b) => a.PlayerId.CompareTo(b.PlayerId));
		return list.ToArray();
	}

	public void RemoveOwner(ulong owner)
	{
		List<ulong> list = new List<ulong>();
		foreach (KeyValuePair<ulong, Entry> record in records)
		{
			if (record.Value.Record.Owner == owner)
			{
				list.Add(record.Key);
			}
		}
		foreach (ulong item in list)
		{
			records.Remove(item);
		}
	}

	public void Clear()
	{
		records.Clear();
	}
}
public static class PromiseFirstPersonMesh
{
	private sealed class Entry
	{
		public Mesh Mesh;

		public int[] BoneIndices;

		public int[] MaterialSlots;
	}

	private static readonly Dictionary<Mesh, Entry> Cache = new Dictionary<Mesh, Entry>();

	public static int CachedMeshes => Cache.Count;

	private static HashSet<Transform> ArmBones(GameObject model)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		Animator componentInChildren = model.GetComponentInChildren<Animator>(true);
		if (!Object.op_Implicit((Object)(object)componentInChildren) || !componentInChildren.isHuman)
		{
			throw new InvalidOperationException("Promise first-person avatar must be humanoid.");
		}
		HashSet<Transform> hashSet = new HashSet<Transform>();
		HumanBodyBones[] array = new HumanBodyBones[6];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		HumanBodyBones[] array2 = (HumanBodyBones[])(object)array;
		foreach (HumanBodyBones val in array2)
		{
			Transform boneTransform = componentInChildren.GetBoneTransform(val);
			if (Object.op_Implicit((Object)(object)boneTransform))
			{
				Transform[] componentsInChildren = ((Component)boneTransform).GetComponentsInChildren<Transform>(true);
				foreach (Transform item in componentsInChildren)
				{
					hashSet.Add(item);
				}
			}
		}
		return hashSet;
	}

	public static void Prime(GameObject model)
	{
		HashSet<Transform> arms = ArmBones(model);
		SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Get(componentsInChildren[i], arms);
		}
	}

	public static IEnumerator PrimeIncremental(GameObject model)
	{
		HashSet<Transform> arms = ArmBones(model);
		SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Get(componentsInChildren[i], arms);
			yield return null;
		}
	}

	private static bool Allowed(BoneWeight weight, bool[] bones)
	{
		if ((((BoneWeight)(ref weight)).weight0 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex0]) && (((BoneWeight)(ref weight)).weight1 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex1]) && (((BoneWeight)(ref weight)).weight2 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex2]))
		{
			if (!(((BoneWeight)(ref weight)).weight3 <= 0f))
			{
				return bones[((BoneWeight)(ref weight)).boneIndex3];
			}
			return true;
		}
		return false;
	}

	private static Entry Get(SkinnedMeshRenderer renderer, HashSet<Transform> arms)
	{
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Expected O, but got Unknown
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0466: Unknown result type (might be due to invalid IL or missing references)
		Mesh sharedMesh = renderer.sharedMesh;
		if (!Object.op_Implicit((Object)(object)sharedMesh))
		{
			return null;
		}
		if (Cache.TryGetValue(sharedMesh, out var value))
		{
			return value;
		}
		if (!sharedMesh.isReadable)
		{
			throw new InvalidOperationException("Promise first-person source mesh is not readable: " + ((Object)sharedMesh).name);
		}
		Transform[] bones = renderer.bones;
		bool[] array = new bool[bones.Length];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = Object.op_Implicit((Object)(object)bones[i]) && arms.Contains(bones[i]);
		}
		BoneWeight[] boneWeights = sharedMesh.boneWeights;
		if (boneWeights.Length != sharedMesh.vertexCount)
		{
			throw new InvalidOperationException("Promise arms require four-weight source skinning.");
		}
		bool[] array2 = new bool[sharedMesh.vertexCount];
		for (int j = 0; j < boneWeights.Length; j++)
		{
			array2[j] = Allowed(boneWeights[j], array);
		}
		List<int> list = new List<int>();
		Dictionary<int, int> dictionary = new Dictionary<int, int>();
		List<int[]> list2 = new List<int[]>();
		List<int> list3 = new List<int>();
		for (int k = 0; k < sharedMesh.subMeshCount; k++)
		{
			int[] triangles = sharedMesh.GetTriangles(k);
			List<int> list4 = new List<int>();
			for (int l = 0; l < triangles.Length; l += 3)
			{
				if (!array2[triangles[l]] || !array2[triangles[l + 1]] || !array2[triangles[l + 2]])
				{
					continue;
				}
				for (int m = 0; m < 3; m++)
				{
					int num = triangles[l + m];
					if (!dictionary.TryGetValue(num, out var value2))
					{
						value2 = list.Count;
						dictionary.Add(num, value2);
						list.Add(num);
					}
					list4.Add(value2);
				}
			}
			if (list4.Count > 0)
			{
				list3.Add(k);
				list2.Add(list4.ToArray());
			}
		}
		if (list.Count == 0)
		{
			Cache.Add(sharedMesh, null);
			return null;
		}
		List<int> list5 = new List<int>();
		Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
		BoneWeight[] array3 = (BoneWeight[])(object)new BoneWeight[list.Count];
		for (int n = 0; n < array3.Length; n++)
		{
			BoneWeight val = boneWeights[list[n]];
			int[] array4 = new int[4]
			{
				((BoneWeight)(ref val)).boneIndex0,
				((BoneWeight)(ref val)).boneIndex1,
				((BoneWeight)(ref val)).boneIndex2,
				((BoneWeight)(ref val)).boneIndex3
			};
			float[] array5 = new float[4]
			{
				((BoneWeight)(ref val)).weight0,
				((BoneWeight)(ref val)).weight1,
				((BoneWeight)(ref val)).weight2,
				((BoneWeight)(ref val)).weight3
			};
			for (int num2 = 0; num2 < 4; num2++)
			{
				if (array5[num2] <= 0f)
				{
					array4[num2] = 0;
					continue;
				}
				if (!dictionary2.TryGetValue(array4[num2], out var value3))
				{
					value3 = list5.Count;
					dictionary2.Add(array4[num2], value3);
					list5.Add(array4[num2]);
				}
				array4[num2] = value3;
			}
			((BoneWeight)(ref val)).boneIndex0 = array4[0];
			((BoneWeight)(ref val)).boneIndex1 = array4[1];
			((BoneWeight)(ref val)).boneIndex2 = array4[2];
			((BoneWeight)(ref val)).boneIndex3 = array4[3];
			array3[n] = val;
		}
		Mesh val2 = new Mesh
		{
			name = ((Object)sharedMesh).name + "_PromiseFirstPerson",
			indexFormat = (IndexFormat)(list.Count > 65535)
		};
		val2.vertices = Subset(sharedMesh.vertices, list);
		if (sharedMesh.normals.Length == sharedMesh.vertexCount)
		{
			val2.normals = Subset(sharedMesh.normals, list);
		}
		if (sharedMesh.tangents.Length == sharedMesh.vertexCount)
		{
			val2.tangents = Subset(sharedMesh.tangents, list);
		}
		if (sharedMesh.colors32.Length == sharedMesh.vertexCount)
		{
			val2.colors32 = Subset(sharedMesh.colors32, list);
		}
		for (int num3 = 0; num3 < 8; num3++)
		{
			List<Vector4> list6 = new List<Vector4>();
			sharedMesh.GetUVs(num3, list6);
			if (list6.Count == sharedMesh.vertexCount)
			{
				val2.SetUVs(num3, Subset(list6.ToArray(), list));
			}
		}
		for (int num4 = 0; num4 < sharedMesh.blendShapeCount; num4++)
		{
			string blendShapeName = sharedMesh.GetBlendShapeName(num4);
			if (!blendShapeName.StartsWith("opt_", StringComparison.Ordinal))
			{
				continue;
			}
			Vector3[] array6 = (Vector3[])(object)new Vector3[sharedMesh.vertexCount];
			sharedMesh.GetBlendShapeFrameVertices(num4, 0, array6, (Vector3[])null, (Vector3[])null);
			Vector3[] array7 = Subset(array6, list);
			bool flag = false;
			Vector3[] array8 = array7;
			for (int num5 = 0; num5 < array8.Length; num5++)
			{
				Vector3 val3 = array8[num5];
				if (((Vector3)(ref val3)).sqrMagnitude > 1E-14f)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				val2.AddBlendShapeFrame(blendShapeName, sharedMesh.GetBlendShapeFrameWeight(num4, 0), array7, (Vector3[])null, (Vector3[])null);
			}
		}
		val2.boneWeights = array3;
		val2.bindposes = Subset(sharedMesh.bindposes, list5);
		val2.subMeshCount = list2.Count;
		for (int num6 = 0; num6 < list2.Count; num6++)
		{
			val2.SetTriangles(list2[num6], num6, false);
		}
		val2.RecalculateBounds();
		value = new Entry
		{
			Mesh = val2,
			BoneIndices = list5.ToArray(),
			MaterialSlots = list3.ToArray()
		};
		Cache.Add(sharedMesh, value);
		return value;
	}

	private static T[] Subset<T>(T[] source, List<int> indices)
	{
		T[] array = new T[indices.Count];
		for (int i = 0; i < indices.Count; i++)
		{
			array[i] = source[indices[i]];
		}
		return array;
	}

	public static GameObject Convert(GameObject model)
	{
		PromiseSourceRotationGrant component = model.GetComponent<PromiseSourceRotationGrant>();
		PromiseSourceRotationGrant.Grant[] sourceGrants = (Object.op_Implicit((Object)(object)component) ? component.grants : null);
		HashSet<Transform> arms = ArmBones(model);
		SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			Entry entry = Get(val, arms);
			if (entry == null)
			{
				((Renderer)val).enabled = false;
				Remove((Object)(object)val);
				continue;
			}
			Transform[] bones = val.bones;
			Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
			Transform[] array = (Transform[])(object)new Transform[entry.BoneIndices.Length];
			Material[] array2 = (Material[])(object)new Material[entry.MaterialSlots.Length];
			for (int j = 0; j < array.Length; j++)
			{
				array[j] = bones[entry.BoneIndices[j]];
			}
			for (int k = 0; k < array2.Length; k++)
			{
				array2[k] = sharedMaterials[entry.MaterialSlots[k]];
			}
			val.sharedMesh = entry.Mesh;
			val.bones = array;
			((Renderer)val).sharedMaterials = array2;
			val.quality = (SkinQuality)4;
			val.updateWhenOffscreen = true;
			((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
		}
		StripSimulation(model);
		PromiseViewModelPose obj = model.GetComponent<PromiseViewModelPose>() ?? model.AddComponent<PromiseViewModelPose>();
		obj.SourceGrants = sourceGrants;
		obj.Initialize();
		model.GetComponent<PromiseAdaptiveLighting>()?.Rebind();
		model.GetComponent<PromiseOutfitState>()?.Rebind();
		return model;
	}

	public static void StripSimulation(GameObject model)
	{
		Collider[] componentsInChildren = model.GetComponentsInChildren<Collider>(true);
		foreach (Collider obj in componentsInChildren)
		{
			obj.enabled = false;
			Remove((Object)(object)obj);
		}
		MonoBehaviour[] componentsInChildren2 = model.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val in componentsInChildren2)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				switch (((object)val).GetType().FullName)
				{
				case "PromiseSuit.PromiseSecondaryMotion":
				case "PromiseSuit.PromiseHeadTracking":
				case "PromiseSuit.PromiseFace":
				case "PromiseSuit.PromiseToonFrame":
				case "PromiseSuit.PromiseSourceRotationGrant":
				case "PromiseSuit.PromiseReactionFace":
				case "JigglePhysics.JiggleRigBuilder":
					((Behaviour)val).enabled = false;
					Remove((Object)(object)val);
					break;
				}
			}
		}
	}

	private static void Remove(Object component)
	{
		if (Application.isPlaying)
		{
			Object.Destroy(component);
		}
		else
		{
			Object.DestroyImmediate(component);
		}
	}

	public static void Clear()
	{
		foreach (Entry value in Cache.Values)
		{
			if (value != null && Object.op_Implicit((Object)(object)value.Mesh))
			{
				Remove((Object)(object)value.Mesh);
			}
		}
		Cache.Clear();
	}
}
public static class PromiseFirstPersonPatch
{
	public static void Install(Harmony harmony)
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		Type type = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.MeshHelper", throwOnError: true);
		MethodInfo methodInfo = AccessTools.Method(type, "ConvertModelToViewModel", new Type[1] { typeof(GameObject) }, (Type[])null);
		if (methodInfo == null)
		{
			throw new MissingMethodException(type.FullName, "ConvertModelToViewModel");
		}
		harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PromiseFirstPersonPatch), "BeforeConvert", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(BodyReplacementBase), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PromiseFirstPersonPatch), "AfterBodyCreated", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		Type type2 = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.Player.ViewModelUpdater", throwOnError: true);
		MethodInfo methodInfo2 = AccessTools.Method(type2, "UpdateViewModel", Type.EmptyTypes, (Type[])null);
		if (methodInfo2 == null)
		{
			throw new MissingMethodException(type2.FullName, "UpdateViewModel");
		}
		harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(PromiseFirstPersonPatch), "BeforeViewPose", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(type2, "AssignViewModelReplacement", new Type[2]
		{
			typeof(GameObject),
			typeof(GameObject)
		}, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(PromiseFirstPersonPatch), "AfterViewAssigned", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static bool BeforeConvert(GameObject __0, ref GameObject __result)
	{
		if (!Object.op_Implicit((Object)(object)__0) || !((Object)__0).name.StartsWith("Promise_", StringComparison.Ordinal))
		{
			return true;
		}
		__result = PromiseFirstPersonMesh.Convert(__0);
		return false;
	}

	private static void AfterBodyCreated(BodyReplacementBase __instance)
	{
		if (!(__instance is PromiseBody))
		{
			return;
		}
		object? value = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel").GetValue(__instance);
		GameObject val = (GameObject)((value is GameObject) ? value : null);
		object? value2 = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow").GetValue(__instance);
		GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null);
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
		{
			PromiseFirstPersonMesh.StripSimulation(val2);
			val2.AddComponent<PromiseShadowPose>().Initialize(val);
		}
		object? value3 = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel").GetValue(__instance);
		GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null);
		if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)__instance.controller))
		{
			PromiseViewModelPose component = val3.GetComponent<PromiseViewModelPose>();
			SkinnedMeshRenderer thisPlayerModelArms = __instance.controller.thisPlayerModelArms;
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)thisPlayerModelArms))
			{
				component.Bind(thisPlayerModelArms, __instance.controller.playerModelArmsMetarig);
			}
		}
	}

	private static bool BeforeViewPose(ViewModelUpdater __instance)
	{
		GameObject replacementViewModel = __instance.replacementViewModel;
		if (!Object.op_Implicit((Object)(object)replacementViewModel))
		{
			return true;
		}
		PromiseViewModelPose component = replacementViewModel.GetComponent<PromiseViewModelPose>();
		if (Object.op_Implicit((Object)(object)component))
		{
			return !component.Step();
		}
		return true;
	}

	private static void AfterViewAssigned(GameObject __0, GameObject __1)
	{
		if (!Object.op_Implicit((Object)(object)__0) || !Object.op_Implicit((Object)(object)__1))
		{
			return;
		}
		PromiseOutfitControl.AttachView(__0, __1);
		PromiseViewModelPose component = __1.GetComponent<PromiseViewModelPose>();
		if (Object.op_Implicit((Object)(object)component))
		{
			PlayerControllerB component2 = __0.GetComponent<PlayerControllerB>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component.Bind(component2.thisPlayerModelArms, component2.playerModelArmsMetarig);
			}
		}
	}
}
public class PromiseFootAlignment : MonoBehaviour
{
	private Transform hip;

	private Transform leftSole;

	private Transform rightSole;

	private Transform playerLeft;

	private Transform playerRight;

	private Vector3 leftReference;

	private Vector3 rightReference;

	private SkinnedMeshRenderer source;

	private bool ready;

	public float LastCorrection { get; private set; }

	public void Align(SkinnedMeshRenderer player)
	{
		//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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)player))
		{
			return;
		}
		if (!ready || (Object)(object)source != (Object)(object)player)
		{
			source = player;
			Animator component = ((Component)this).GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component) || !component.isHuman)
			{
				return;
			}
			hip = component.GetBoneTransform((HumanBodyBones)0);
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			leftSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "PromiseSole.L"));
			rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "PromiseSole.R"));
			Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.L"));
			Transform val2 = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.R"));
			playerLeft = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.L"));
			playerRight = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.R"));
			ready = Object.op_Implicit((Object)(object)hip) && Object.op_Implicit((Object)(object)leftSole) && Object.op_Implicit((Object)(object)rightSole) && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)playerLeft) && Object.op_Implicit((Object)(object)playerRight);
			if (!ready)
			{
				return;
			}
			leftReference = val.localPosition;
			rightReference = val2.localPosition;
		}
		float num = Mathf.Min(playerLeft.TransformPoint(leftReference).y, playerRight.TransformPoint(rightReference).y);
		float num2 = Mathf.Min(leftSole.position.y, rightSole.position.y);
		LastCorrection = num - num2;
		if (!float.IsNaN(LastCorrection) && !float.IsInfinity(LastCorrection))
		{
			Transform obj = hip;
			obj.position += Vector3.up * LastCorrection;
		}
	}
}
public class PromiseHandAlignment : MonoBehaviour
{
	private class Arm
	{
		public Transform Upper;

		public Transform Lower;

		public Transform Hand;

		public Transform PlayerUpper;

		public Transform PlayerLower;

		public Transform PlayerHand;
	}

	private Arm[] arms;

	private SkinnedMeshRenderer source;

	public void Align(SkinnedMeshRenderer player)
	{
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)player))
		{
			return;
		}
		if (arms == null || (Object)(object)source != (Object)(object)player)
		{
			Animator component = ((Component)this).GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component) || !component.isHuman)
			{
				return;
			}
			source = player;
			arms = new Arm[2];
			for (int i = 0; i < 2; i++)
			{
				bool flag = i == 0;
				string s = (flag ? "L" : "R");
				arms[i] = new Arm
				{
					Upper = component.GetBoneTransform((HumanBodyBones)(flag ? 13 : 14)),
					Lower = component.GetBoneTransform((HumanBodyBones)(flag ? 15 : 16)),
					Hand = component.GetBoneTransform((HumanBodyBones)(flag ? 17 : 18)),
					PlayerUpper = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "arm." + s + "_upper")),
					PlayerLower = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "arm." + s + "_lower")),
					PlayerHand = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "hand." + s))
				};
			}
		}
		Arm[] array = arms;
		foreach (Arm arm in array)
		{
			if (Object.op_Implicit((Object)(object)arm.Upper) && Object.op_Implicit((Object)(object)arm.Lower) && Object.op_Implicit((Object)(object)arm.Hand) && Object.op_Implicit((Object)(object)arm.PlayerUpper) && Object.op_Implicit((Object)(object)arm.PlayerLower) && Object.op_Implicit((Object)(object)arm.PlayerHand))
			{
				Quaternion rotation = arm.Hand.rotation;
				Aim(arm.Upper, arm.Lower, arm.PlayerLower.position