Decompiled source of hololive 5th Generation v1.0.1

NePoLaBoSuit.dll

Decompiled 24 minutes 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 System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
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 NePoLaBoSuit;

[Serializable]
public struct NePoLaBoLightingContext
{
	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 NePoLaBoLightingContext(bool factory, bool ship)
	{
		InsideFactory = factory;
		InsideShip = ship;
	}
}
public sealed class NePoLaBoCorpseLightingContext
{
	private NePoLaBoLightingContext context;

	private bool trackedItem;

	public NePoLaBoCorpseLightingContext(NePoLaBoLightingContext death)
	{
		context = death;
	}

	public NePoLaBoLightingContext Observe(bool bodyInShip, bool hasHolder, NePoLaBoLightingContext holder, bool hasItem, NePoLaBoLightingContext item)
	{
		if (hasHolder)
		{
			context = holder;
			trackedItem = true;
		}
		else if (hasItem && trackedItem)
		{
			context = item;
		}
		if (!bodyInShip)
		{
			return context;
		}
		return new NePoLaBoLightingContext(factory: false, ship: true);
	}
}
[DefaultExecutionOrder(600)]
public sealed class NePoLaBoAdaptiveLighting : 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<NePoLaBoLightingContext> contextReader;

	private bool initialized;

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

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

	public NePoLaBoLightingContext 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<NePoLaBoLightingContext> reader)
	{
		contextReader = reader;
		Refresh();
	}

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

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

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

	public void Apply(NePoLaBoLightingContext 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 NePoLaBoLightingControl
{
	private sealed class Death
	{
		internal ulong Owner;

		internal NePoLaBoLightingContext 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 NePoLaBoLightingContext Native(PlayerControllerB player)
	{
		if (!Object.op_Implicit((Object)(object)player))
		{
			return default(NePoLaBoLightingContext);
		}
		return new NePoLaBoLightingContext(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(NePoLaBoLightingControl), "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(NePoLaBoLightingControl), "Ragdoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NePoLaBoLightingControl), "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(NePoLaBoLightingControl), "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(NePoLaBoLightingControl), "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 NePoLaBoBody nePoLaBoBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)nePoLaBoBody).controller))
		{
			FieldInfo[] array = new FieldInfo[3] { sourceField, shadowField, viewField };
			for (int i = 0; i < array.Length; i++)
			{
				object? obj = array[i]?.GetValue(nePoLaBoBody);
				Bind((GameObject)((obj is GameObject) ? obj : null), ((BodyReplacementBase)nePoLaBoBody).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<NePoLaBoAdaptiveLighting>()))
		{
			Bind(view, playerObject.GetComponent<PlayerControllerB>());
		}
	}

	private static void Ragdoll(BodyReplacementBase __instance, GameObject __result)
	{
		if (__instance is NePoLaBoBody nePoLaBoBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)nePoLaBoBody).controller))
		{
			Bind(__result, ((BodyReplacementBase)nePoLaBoBody).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;
		}
		NePoLaBoAdaptiveLighting nePoLaBoAdaptiveLighting = model.GetComponent<NePoLaBoAdaptiveLighting>() ?? model.AddComponent<NePoLaBoAdaptiveLighting>();
		nePoLaBoAdaptiveLighting.Rebind();
		ulong owner = ((NetworkBehaviour)player).OwnerClientId;
		if (!corpse)
		{
			nePoLaBoAdaptiveLighting.BindContext(() => (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).OwnerClientId != owner) ? default(NePoLaBoLightingContext) : Native(player));
			return;
		}
		Death value;
		NePoLaBoLightingContext death = ((deaths.TryGetValue(player, out value) && value.Owner == owner) ? value.Context : Native(player));
		NePoLaBoCorpseLightingContext corpseContext = new NePoLaBoCorpseLightingContext(death);
		DeadBodyInfo nativeBody = player.deadBody;
		nePoLaBoAdaptiveLighting.BindContext(delegate
		{
			if (!Object.op_Implicit((Object)(object)nativeBody))
			{
				return corpseContext.Observe(bodyInShip: false, hasHolder: false, default(NePoLaBoLightingContext), hasItem: false, default(NePoLaBoLightingContext));
			}
			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 NePoLaBoLightingContext(grabBodyObject.isInFactory, grabBodyObject.isInShipRoom) : default(NePoLaBoLightingContext));
		});
	}

	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 NePoLaBoAttentionSelection
{
	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 NePoLaBoAttention
{
	private sealed class ItemRenderer
	{
		public GrabbableObject Item;

		public Renderer Renderer;
	}

	private readonly NePoLaBoAttentionSelection selection = new NePoLaBoAttentionSelection();

	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 = NePoLaBoSceneCache.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 (NePoLaBoAttentionSelection.InView(origin, forward, val, range))
		{
			int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5));
			if (NePoLaBoAttentionSelection.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 = NePoLaBoVoiceActivity.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 NePoLaBoVoiceActivity
{
	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 = NePoLaBoFace.Read(player, "voicePlayerState") ?? NePoLaBoFace.Read(NePoLaBoFace.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 = NePoLaBoFace.Read(StartOfRound.Instance, "voiceChatModule");
			if (comms != null)
			{
				string text = (((NetworkBehaviour)player).IsOwner ? (NePoLaBoFace.Read(comms, "LocalPlayerName") as string) : (NePoLaBoFace.Read(player, "voicePlayerName") as string));
				if (!string.IsNullOrEmpty(text))
				{
					try
					{
						obj = NePoLaBoRuntimeMembers.CallString(comms, "FindPlayer", text);
						if (obj != null)
						{
							states[instanceID] = obj;
						}
					}
					catch
					{
					}
				}
			}
		}
		bool value3;
		bool flag = NePoLaBoRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3;
		if (NePoLaBoRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4)
		{
			return false;
		}
		if (!NePoLaBoRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5))
		{
			return flag;
		}
		return NePoLaBoAttentionSelection.ActiveSpeech(flag, value5);
	}

	internal static void Clear()
	{
		comms = null;
		retry.Clear();
		states.Clear();
	}
}
public sealed class NePoLaBoBundleCache
{
	public const string PackedSHA256 = "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94";

	public const uint ContentCRC = 4040354875u;

	private string packedPath;

	private string pendingPath;

	private FileStream output;

	private SHA256 digest;

	public AssetBundle Bundle { get; private set; }

	public bool CacheHit { get; private set; }

	public bool Rebuilt { get; private set; }

	public bool UsedFallback { get; private set; }

	public string Warning { get; private set; }

	public string CachePath { get; private set; }

	private bool Prepare(string directory)
	{
		try
		{
			Directory.CreateDirectory(directory);
			CachePath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94.bundle");
			string text = Guid.NewGuid().ToString("N");
			packedPath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94." + text + ".packed");
			pendingPath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94." + text + ".pending");
			return true;
		}
		catch (Exception ex)
		{
			Warning = "Model cache unavailable: " + ex.Message;
			return false;
		}
	}

	private bool OpenOutput(Stream source)
	{
		try
		{
			source.Position = 0L;
			output = new FileStream(packedPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
			digest = SHA256.Create();
			return true;
		}
		catch (Exception ex)
		{
			Warning = "Model cache staging failed: " + ex.Message;
			CloseOutput();
			return false;
		}
	}

	private int Copy(Stream source, byte[] buffer)
	{
		try
		{
			int num = source.Read(buffer, 0, buffer.Length);
			if (num > 0)
			{
				output.Write(buffer, 0, num);
				digest.TransformBlock(buffer, 0, num, buffer, 0);
			}
			return num;
		}
		catch (Exception ex)
		{
			Warning = "Model cache write failed: " + ex.Message;
			return -1;
		}
	}

	private bool FinishOutput()
	{
		try
		{
			digest.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
			if (BitConverter.ToString(digest.Hash).Replace("-", "").ToLowerInvariant() != "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94")
			{
				Warning = "Embedded model checksum differs; loading directly.";
				return false;
			}
			return true;
		}
		catch (Exception ex)
		{
			Warning = "Model checksum verification failed: " + ex.Message;
			return false;
		}
		finally
		{
			CloseOutput();
		}
	}

	private void CloseOutput()
	{
		output?.Dispose();
		output = null;
		digest?.Dispose();
		digest = null;
	}

	private void RemoveOwnedTemporaryFiles()
	{
		CloseOutput();
		string[] array = new string[2] { packedPath, pendingPath };
		foreach (string text in array)
		{
			if (string.IsNullOrEmpty(text))
			{
				continue;
			}
			try
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
			catch (Exception)
			{
			}
		}
	}

	private bool Commit()
	{
		try
		{
			if (File.Exists(CachePath))
			{
				File.Delete(CachePath);
			}
			File.Move(pendingPath, CachePath);
			return true;
		}
		catch (Exception ex)
		{
			Warning = "Model cache commit failed: " + ex.Message;
			return false;
		}
	}

	private AssetBundleCreateRequest LoadFile()
	{
		try
		{
			return AssetBundle.LoadFromFileAsync(CachePath, 4040354875u);
		}
		catch (Exception ex)
		{
			Warning = "Model cache load failed: " + ex.Message;
			return null;
		}
	}

	private AssetBundleRecompressOperation Recompress()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			return AssetBundle.RecompressAssetBundleAsync(packedPath, pendingPath, BuildCompression.LZ4Runtime, 4040354875u, (ThreadPriority)0);
		}
		catch (Exception ex)
		{
			Warning = "Model cache conversion failed: " + ex.Message;
			return null;
		}
	}

	private AssetBundleCreateRequest LoadDirect(Stream source)
	{
		try
		{
			source.Position = 0L;
			return AssetBundle.LoadFromStreamAsync(source, 4040354875u);
		}
		catch (Exception ex)
		{
			Warning = "Direct model load failed: " + ex.Message;
			return null;
		}
	}

	public IEnumerator Load(Stream source, string directory)
	{
		if (source == null)
		{
			Warning = "Missing embedded models.";
			yield break;
		}
		try
		{
			if (Prepare(directory))
			{
				if (File.Exists(CachePath))
				{
					AssetBundleCreateRequest warm = LoadFile();
					if (warm != null)
					{
						yield return warm;
						if (Object.op_Implicit((Object)(object)warm.assetBundle))
						{
							Bundle = warm.assetBundle;
							CacheHit = true;
							yield break;
						}
					}
				}
				bool staged = OpenOutput(source);
				if (staged)
				{
					byte[] buffer = new byte[2097152];
					while (true)
					{
						int num = Copy(source, buffer);
						if (num < 0)
						{
							staged = false;
							break;
						}
						if (num == 0)
						{
							break;
						}
						yield return null;
					}
					if (staged)
					{
						staged = FinishOutput();
					}
					else
					{
						CloseOutput();
					}
				}
				if (staged)
				{
					AssetBundleRecompressOperation convert = Recompress();
					if (convert != null)
					{
						yield return convert;
						if (convert.success && Commit())
						{
							AssetBundleCreateRequest warm = LoadFile();
							if (warm != null)
							{
								yield return warm;
								if (Object.op_Implicit((Object)(object)warm.assetBundle))
								{
									Bundle = warm.assetBundle;
									Rebuilt = true;
									yield break;
								}
							}
						}
						else
						{
							Warning = "Model cache conversion did not complete: " + convert.humanReadableResult;
						}
					}
				}
			}
			UsedFallback = true;
			AssetBundleCreateRequest direct = LoadDirect(source);
			if (direct != null)
			{
				yield return direct;
				Bundle = direct.assetBundle;
			}
		}
		finally
		{
			RemoveOwnedTemporaryFiles();
		}
	}
}
public sealed class NePoLaBoChestGazeTarget : MonoBehaviour
{
	public Transform chest;

	public Transform[] breasts = (Transform[])(object)new Transform[0];

	public Vector3 Point
	{
		get
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			int num = 0;
			Transform[] array = breasts;
			foreach (Transform val2 in array)
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					val += val2.position;
					num++;
				}
			}
			if (num <= 0)
			{
				if (!Object.op_Implicit((Object)(object)chest))
				{
					return ((Component)this).transform.position + Vector3.up * 1.3f;
				}
				return chest.position;
			}
			return val / (float)num;
		}
	}
}
public enum NePoLaBoExpression : byte
{
	Neutral,
	Frightened,
	Hurt,
	Happy,
	Surprised,
	VeryHappy,
	Dead
}
public struct NePoLaBoExpressionContext
{
	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 NePoLaBoExpressionSelection
{
	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 NePoLaBoExpression Choose(NePoLaBoExpressionContext c, double now)
	{
		if (c.Dead)
		{
			return NePoLaBoExpression.Dead;
		}
		if (c.Critical || now < hurtUntil)
		{
			return NePoLaBoExpression.Hurt;
		}
		if (c.Unsafe)
		{
			return NePoLaBoExpression.Frightened;
		}
		if (now < treasureUntil)
		{
			if (!surprised)
			{
				return NePoLaBoExpression.VeryHappy;
			}
			return NePoLaBoExpression.Surprised;
		}
		if (c.Dancing)
		{
			return NePoLaBoExpression.Happy;
		}
		return NePoLaBoExpression.Neutral;
	}
}
public struct NePoLaBoExpressionWeight
{
	public string Shape;

	public float Weight;

	public bool Eyes;

	public bool Mouth;

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

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

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

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

	public static NePoLaBoExpressionWeight[] Weights(NePoLaBoExpression state)
	{
		return profiles[(uint)state];
	}
}
public sealed class NePoLaBoExpressionMixer
{
	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;

	private readonly List<Tuple<SkinnedMeshRenderer, int>> angerDraws = new List<Tuple<SkinnedMeshRenderer, int>>();

	private readonly MaterialPropertyBlock angerBlock = new MaterialPropertyBlock();

	public NePoLaBoExpressionMixer(GameObject model)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		NePoLaBoExpressionWeight[] array;
		foreach (NePoLaBoExpression value in Enum.GetValues(typeof(NePoLaBoExpression)))
		{
			array = NePoLaBoExpressionProfiles.Weights(value);
			for (int i = 0; i < array.Length; i++)
			{
				NePoLaBoExpressionWeight nePoLaBoExpressionWeight = array[i];
				if (!slots.ContainsKey(nePoLaBoExpressionWeight.Shape))
				{
					slots[nePoLaBoExpressionWeight.Shape] = shapes.Count;
					shapes.Add(nePoLaBoExpressionWeight.Shape);
				}
			}
		}
		array = NePoLaBoPersonalityProfiles.Managed;
		for (int i = 0; i < array.Length; i++)
		{
			NePoLaBoExpressionWeight nePoLaBoExpressionWeight2 = array[i];
			if (!slots.ContainsKey(nePoLaBoExpressionWeight2.Shape))
			{
				slots[nePoLaBoExpressionWeight2.Shape] = shapes.Count;
				shapes.Add(nePoLaBoExpressionWeight2.Shape);
			}
		}
		values = new float[shapes.Count];
		target = new float[shapes.Count];
		eyes = new bool[shapes.Count];
		mouth = new bool[shapes.Count];
		foreach (NePoLaBoExpression value2 in Enum.GetValues(typeof(NePoLaBoExpression)))
		{
			array = NePoLaBoExpressionProfiles.Weights(value2);
			for (int i = 0; i < array.Length; i++)
			{
				NePoLaBoExpressionWeight nePoLaBoExpressionWeight3 = array[i];
				int num = slots[nePoLaBoExpressionWeight3.Shape];
				eyes[num] |= nePoLaBoExpressionWeight3.Eyes;
				mouth[num] |= nePoLaBoExpressionWeight3.Mouth;
			}
		}
		array = NePoLaBoPersonalityProfiles.Managed;
		for (int i = 0; i < array.Length; i++)
		{
			NePoLaBoExpressionWeight nePoLaBoExpressionWeight4 = array[i];
			int num2 = slots[nePoLaBoExpressionWeight4.Shape];
			eyes[num2] |= nePoLaBoExpressionWeight4.Eyes;
			mouth[num2] |= nePoLaBoExpressionWeight4.Mouth;
		}
		SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			if (!Object.op_Implicit((Object)(object)val.sharedMesh) || NePoLaBoInkOutline.IsInk(val))
			{
				continue;
			}
			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);
			Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
			for (int k = 0; k < sharedMaterials.Length; k++)
			{
				if (Object.op_Implicit((Object)(object)sharedMaterials[k]) && ((Object)sharedMaterials[k]).name.Contains("_AngerMark_"))
				{
					angerDraws.Add(Tuple.Create<SkinnedMeshRenderer, int>(val, k));
				}
			}
		}
	}

	public void Step(NePoLaBoExpression state, float delta, bool immediate = false)
	{
		Step("", new NePoLaBoFaceState(state), delta, immediate);
	}

	public void Step(string character, NePoLaBoFaceState face, float delta, bool immediate = false)
	{
		NePoLaBoExpression expression = face.Expression;
		Array.Clear(target, 0, target.Length);
		float num = ((face.Reaction == NePoLaBoReaction.None) ? 1f : ((float)(int)face.Strength / 255f));
		NePoLaBoExpressionWeight[] array = NePoLaBoPersonalityProfiles.Weights(character, face);
		for (int i = 0; i < array.Length; i++)
		{
			NePoLaBoExpressionWeight nePoLaBoExpressionWeight = array[i];
			target[slots[nePoLaBoExpressionWeight.Shape]] = nePoLaBoExpressionWeight.Weight * ((nePoLaBoExpressionWeight.Shape == "expr_anger_mark") ? 1f : num);
		}
		if (character == "ShishiroBotan" && face.Reaction == NePoLaBoReaction.Critical)
		{
			target[slots["expr_ears_side"]] = 1f;
		}
		if (character == "ShishiroBotan" && face.Reaction == NePoLaBoReaction.Stunned)
		{
			target[slots["expr_ears_up"]] = 1f;
		}
		foreach (Tuple<SkinnedMeshRenderer, int> angerDraw in angerDraws)
		{
			if (Object.op_Implicit((Object)(object)angerDraw.Item1))
			{
				((Renderer)angerDraw.Item1).GetPropertyBlock(angerBlock, angerDraw.Item2);
				angerBlock.SetFloat("_GflOpacity", (face.Reaction == NePoLaBoReaction.Angry) ? num : 0f);
				((Renderer)angerDraw.Item1).SetPropertyBlock(angerBlock, angerDraw.Item2);
			}
		}
		float num2 = ((immediate || expression == NePoLaBoExpression.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], num2);
		}
		foreach (Binding binding in bindings)
		{
			if (!Object.op_Implicit((Object)(object)binding.Renderer))
			{
				continue;
			}
			float num3 = ((binding.Blink < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Blink) / 100f));
			float num4 = ((binding.Open < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Open) / 85f));
			if (expression == NePoLaBoExpression.Dead)
			{
				num3 = 1f;
				num4 = 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 num5 = values[k];
					if (eyes[k])
					{
						num5 *= 1f - num3;
					}
					if (mouth[k])
					{
						num5 *= 1f - num4 * 0.55f;
					}
					binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num5 * 100f);
				}
			}
		}
	}
}
[DefaultExecutionOrder(280)]
public sealed class NePoLaBoDeathFace : MonoBehaviour
{
	private NePoLaBoExpressionMixer mixer;

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

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

	public ulong Owner;

	public byte Character;

	public NePoLaBoExpression Expression;

	public uint Revision;

	public NePoLaBoReaction Reaction;

	public byte Strength;

	public ulong GazePlayerId;

	public float GazeWeight;
}
public sealed class NePoLaBoExpressionStore
{
	private sealed class Entry
	{
		public NePoLaBoExpressionRecord Record;

		public double At;
	}

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

	public bool Accept(ulong sender, ulong actualOwner, NePoLaBoExpressionRecord value, double now)
	{
		if (sender != actualOwner || value.Owner != actualOwner || !NePoLaBoPersonalityProfiles.Valid(value.Character, new NePoLaBoFaceState
		{
			Expression = value.Expression,
			Reaction = value.Reaction,
			Strength = value.Strength
		}) || float.IsNaN(value.GazeWeight) || float.IsInfinity(value.GazeWeight) || value.GazeWeight < 0f || value.GazeWeight > 1f || (value.GazeWeight > 0f && (value.Character != 3 || value.Reaction != NePoLaBoReaction.Hearts || value.GazePlayerId == value.PlayerId)) || 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 || value.Reaction != value2.Record.Reaction || value.Strength != value2.Record.Strength || value.GazePlayerId != value2.Record.GazePlayerId || value.GazeWeight != value2.Record.GazeWeight))))
		{
			return false;
		}
		records[value.PlayerId] = new Entry
		{
			Record = value,
			At = now
		};
		return true;
	}

	public bool TryGet(ulong id, double now, out NePoLaBoExpressionRecord value)
	{
		value = default(NePoLaBoExpressionRecord);
		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 NePoLaBoExpressionRecord[] Snapshot(double now)
	{
		List<NePoLaBoExpressionRecord> list = new List<NePoLaBoExpressionRecord>();
		foreach (Entry value in records.Values)
		{
			if (now >= value.At && now - value.At <= 5.0)
			{
				list.Add(value.Record);
			}
		}
		list.Sort((NePoLaBoExpressionRecord a, NePoLaBoExpressionRecord 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 NePoLaBoFirstPersonMesh
{
	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("NePoLaBo 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("NePoLaBo 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("NePoLaBo 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 + "_NePoLaBoFirstPerson",
			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)
	{
		NePoLaBoSourceRotationGrant component = model.GetComponent<NePoLaBoSourceRotationGrant>();
		NePoLaBoSourceRotationGrant.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);
		NePoLaBoViewModelPose obj = model.GetComponent<NePoLaBoViewModelPose>() ?? model.AddComponent<NePoLaBoViewModelPose>();
		obj.SourceGrants = sourceGrants;
		obj.Initialize();
		model.GetComponent<NePoLaBoAdaptiveLighting>()?.Rebind();
		model.GetComponent<NePoLaBoOutfitState>()?.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 "NePoLaBoSuit.NePoLaBoSecondaryMotion":
				case "NePoLaBoSuit.NePoLaBoHeadTracking":
				case "NePoLaBoSuit.NePoLaBoFace":
				case "NePoLaBoSuit.NePoLaBoToonFrame":
				case "NePoLaBoSuit.NePoLaBoSourceRotationGrant":
				case "NePoLaBoSuit.NePoLaBoReactionFace":
				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 NePoLaBoFirstPersonPatch
{
	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(NePoLaBoFirstPersonPatch), "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(NePoLaBoFirstPersonPatch), "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(NePoLaBoFirstPersonPatch), "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(NePoLaBoFirstPersonPatch), "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("NePoLaBo_", StringComparison.Ordinal))
		{
			return true;
		}
		__result = NePoLaBoFirstPersonMesh.Convert(__0);
		return false;
	}

	private static void AfterBodyCreated(BodyReplacementBase __instance)
	{
		if (!(__instance is NePoLaBoBody))
		{
			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))
		{
			NePoLaBoFirstPersonMesh.StripSimulation(val2);
			val2.AddComponent<NePoLaBoShadowPose>().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))
		{
			NePoLaBoViewModelPose component = val3.GetComponent<NePoLaBoViewModelPose>();
			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;
		}
		NePoLaBoViewModelPose component = replacementViewModel.GetComponent<NePoLaBoViewModelPose>();
		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;
		}
		NePoLaBoOutfitControl.AttachView(__0, __1);
		NePoLaBoViewModelPose component = __1.GetComponent<NePoLaBoViewModelPose>();
		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 NePoLaBoFootAlignment : 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 == "NePoLaBoSole.L"));
			rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NePoLaBoSole.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 NePoLaBoHandAlignment : 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 - arm.PlayerUpper.position);
				Aim(arm.Lower, arm.Hand, arm.PlayerHand.position - arm.PlayerLower.position);
				arm.Hand.rotation = rotation;
			}
		}
	}

	private static void Aim(Transform joint, Transform end, Vector3 direction)
	{
		//IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_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)
		Vector3 val = end.position - joint.position;
		if (((Vector3)(ref val)).sqrMagnitude > 1E-08f && ((Vector3)(ref direction)).sqrMagnitude > 1E-08f)
		{
			joint.rotation = Quaternion.FromToRotation(val, direction) * joint.rotation;
		}
	}
}
[DefaultExecutionOrder(200)]
public class NePoLaBoHeadTracking : MonoBehaviour
{
	public PlayerControllerB Player;

	private readonly NePoLaBoAttention attention = new NePoLaBoAttention();

	public Quaternion? WorldAimFrame;

	public bool TrackingEnabled = true;

	private Transform neck;

	private Transform head;

	private Quaternion headToLook;

	private Quaternion neckBase;

	private Quaternion headBase;

	private Quaternion neckApplied;

	private Quaternion headApplied;

	private Quaternion neutralNeck;

	private Quaternion neutralHead;

	private bool ready;

	private bool applied;

	private int previousFrame = int.MinValue;

	private float yaw;

	private float pitch;

	private float aimWeight;

	public const float MaximumYaw = 50f;

	public const float MaximumUpPitch = 35f;

	public const float MaximumDownPitch = 45f;

	public const float MaximumCorrection = 55f;

	public const float NeckShare = 0.3f;

	public bool HasAttentionTarget { get; private set; }

	public Vector3 AttentionDirection { get; private set; }

	public float CurrentYaw => yaw;

	public float CurrentPitch => pitch;

	public float LastCorrectionAngle { get; private set; }

	public bool Ready => ready;

	public Vector3 LookForward
	{
		get
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!ready)
			{
				return ((Component)this).transform.forward;
			}
			return head.rotation * headToLook * Vector3.forward;
		}
	}

	public Vector3 LookUp
	{
		get
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!ready)
			{
				return ((Component)this).transform.up;
			}
			return head.rotation * headToLook * Vector3.up;
		}
	}

	private void Awake()
	{
		Initialize();
	}

	private void Initialize()
	{
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: 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_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		if (ready)
		{
			return;
		}
		Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
		Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>();
		neck = ((Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman) ? componentInChildren.GetBoneTransform((HumanBodyBones)9) : null);
		head = ((Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman) ? componentInChildren.GetBoneTransform((HumanBodyBones)10) : null);
		if (!Object.op_Implicit((Object)(object)neck))
		{
			neck = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-spine.005"));
		}
		if (!Object.op_Implicit((Object)(object)head))
		{
			head = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-spine.006"));
		}
		ready = Object.op_Implicit((Object)(object)neck) && Object.op_Implicit((Object)(object)head) && head.IsChildOf(neck);
		if (ready)
		{
			Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NePoLaBoGazeFrame"));
			headToLook = Quaternion.Inverse(head.rotation) * (Object.op_Implicit((Object)(object)val) ? val.rotation : Quaternion.identity);
			neckBase = (neutralNeck = neck.localRotation);
			headBase = (neutralHead = head.localRotation);
		}
	}

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

	private static bool Finite(Vector3 value)
	{
		//IL_0000: 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)
		if (Finite(value.x) && Finite(value.y))
		{
			return Finite(value.z);
		}
		return false;
	}

	private static bool SameRotation(Quaternion a, Quaternion b)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: 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_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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)
		float num = ((!(Quaternion.Dot(a, b) < 0f)) ? 1 : (-1));
		float num2 = a.x - num * b.x;
		float num3 = a.y - num * b.y;
		float num4 = a.z - num * b.z;
		float num5 = a.w - num * b.w;
		return num2 * num2 + num3 * num3 + num4 * num4 + num5 * num5 < 1E-09f;
	}

	private void RestoreAppliedPose()
	{
		//IL_0017: 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_0040: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		if (ready && applied)
		{
			if (SameRotation(neck.localRotation, neckApplied))
			{
				neck.localRotation = neckBase;
			}
			if (SameRotation(head.localRotation, headApplied))
			{
				head.localRotation = headBase;
			}
			applied = false;
		}
	}

	public void PrepareForAvatarPose()
	{
		RestoreAppliedPose();
	}

	public void StepFromDirection(Vector3 direction, float deltaTime, int frameToken, bool tracking = true)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		Initialize();
		if (!ready)
		{
			return;
		}
		RestoreAppliedPose();
		neckBase = neck.localRotation;
		headBase = head.localRotation;
		bool flag = tracking && TrackingEnabled && Finite(direction) && ((Vector3)(ref direction)).sqrMagnitude > 1E-08f;
		Quaternion val = (Quaternion)(((??)WorldAimFrame) ?? ((Component)this).transform.rotation);
		if (previousFrame != frameToken)
		{
			previousFrame = frameToken;
			float num = yaw;
			float num2 = pitch;
			if (flag)
			{
				Vector3 val2 = Quaternion.Inverse(val) * ((Vector3)(ref direction)).normalized;
				num = Mathf.Clamp(Mathf.Atan2(val2.x, val2.z) * 57.29578f, -50f, 50f);
				num2 = Mathf.Clamp(Mathf.Atan2(val2.y, Mathf.Sqrt(val2.x * val2.x + val2.z * val2.z)) * 57.29578f, -45f, 35f);
			}
			float num3 = 1f - Mathf.Exp((0f - Mathf.Clamp(deltaTime, 0f, 0.1f)) * 10f);
			yaw = Mathf.Lerp(yaw, num, num3);
			pitch = Mathf.Lerp(pitch, num2, num3);
			aimWeight = Mathf.Lerp(aimWeight, (float)(flag ? 1 : 0), num3);
		}
		LastCorrectionAngle = 0f;
		if (TrackingEnabled && !(aimWeight < 1E-06f))
		{
			Vector3 val3 = val * Quaternion.Euler(0f - pitch, yaw, 0f) * Vector3.forward;
			Quaternion val4 = Quaternion.FromToRotation(LookForward, val3);
			val4 = Quaternion.RotateTowards(Quaternion.identity, val4, 55f);
			val4 = Quaternion.Slerp(Quaternion.identity, val4, aimWeight);
			LastCorrectionAngle = Quaternion.Angle(Quaternion.identity, val4);
			neck.rotation = Quaternion.Slerp(Quaternion.identity, val4, 0.3f) * neck.rotation;
			head.rotation = Quaternion.Slerp(Quaternion.identity, val4, 0.7f) * head.rotation;
			neckApplied = neck.localRotation;
			headApplied = head.localRotation;
			applied = true;
		}
	}

	public void Step()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: 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)
		TrackingEnabled = Plugin.HeadTracking.Value;
		bool flag = Object.op_Implicit((Object)(object)Player) && TrackingEnabled && !Player.isPlayerDead && Player.isPlayerControlled;
		Initialize();
		WorldAimFrame = (Object.op_Implicit((Object)(object)Player) ? new Quaternion?(((Component)Player).transform.rotation) : ((Quaternion?)null));
		Vector3 val = (Quaternion)(((??)WorldAimFrame) ?? ((Component)this).transform.rotation) * Vector3.forward;
		Vector3 direction = val;
		HasAttentionTarget = flag && ready && attention.Resolve(Player, ((Component)this).transform, head.position, val, Time.unscaledTime, out direction);
		AttentionDirection = direction;
		if (!flag)
		{
			attention.Reset();
		}
		StepFromDirection(direction, Time.deltaTime, Time.frameCount, HasAttentionTarget);
	}

	public void PrepareNeutralTrackingPose()
	{
		//IL_001c: 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)
		Initialize();
		if (ready)
		{
			RestoreAppliedPose();
			neck.localRotation = neutralNeck;
			head.localRotation = neutralHead;
		}
	}

	private void LateUpdate()
	{
		Step();
	}

	public void ResetAim()
	{
		RestoreAppliedPose();
		yaw = (pitch = (aimWeight = 0f));
		previousFrame = int.MinValue;
		LastCorrectionAngle = 0f;
		HasAttentionTarget = false;
		attention.Reset();
	}

	private void OnDisable()
	{
		ResetAim();
	}
}
[DefaultExecutionOrder(1000)]
public sealed class NePoLaBoInkOutline : MonoBehaviour
{
	private sealed class Pair
	{
		public SkinnedMeshRenderer Source;

		public SkinnedMeshRenderer Ink;

		public Mesh Mesh;

		public int Shapes;

		public Bounds Bounds;
	}

	public const string Prefix = "NePoLaBo Ink ";

	private readonly List<Pair> pairs = new List<Pair>();

	private bool initialized;

	public int RendererPairs
	{
		get
		{
			Initialize();
			return pairs.Count;
		}
	}

	public static bool IsInk(SkinnedMeshRenderer r)
	{
		if (Object.op_Implicit((Object)(object)r))
		{
			return ((Object)r).name.StartsWith("NePoLaBo Ink ", StringComparison.Ordinal);
		}
		return false;
	}

	public void Initialize()
	{
		if (initialized)
		{
			return;
		}
		initialized = true;
		SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			if (IsInk(val) && Object.op_Implicit((Object)(object)((Component)val).transform.parent))
			{
				SkinnedMeshRenderer component = ((Component)((Component)val).transform.parent).GetComponent<SkinnedMeshRenderer>();
				if (Object.op_Implicit((Object)(object)component))
				{
					pairs.Add(new Pair
					{
						Source = component,
						Ink = val
					});
				}
			}
		}
	}

	public void Step(bool forceShapes = false)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Invalid comparison between Unknown and I4
		//IL_00ee: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		Initialize();
		foreach (Pair pair in pairs)
		{
			if (!Object.op_Implicit((Object)(object)pair.Source) || !Object.op_Implicit((Object)(object)pair.Ink))
			{
				continue;
			}
			SkinnedMeshRenderer source = pair.Source;
			SkinnedMeshRenderer ink = pair.Ink;
			bool flag = ((Renderer)source).enabled && (int)((Renderer)source).shadowCastingMode != 3;
			if (((Renderer)ink).enabled != flag)
			{
				((Renderer)ink).enabled = flag;
			}
			int layer = ((Component)source).gameObject.layer;
			if (((Component)ink).gameObject.layer != layer)
			{
				((Component)ink).gameObject.layer = layer;
			}
			if ((Object)(object)pair.Mesh != (Object)(object)source.sharedMesh)
			{
				pair.Mesh = source.sharedMesh;
				ink.sharedMesh = pair.Mesh;
				pair.Shapes = (Object.op_Implicit((Object)(object)pair.Mesh) ? pair.Mesh.blendShapeCount : 0);
			}
			Bounds localBounds = ((Renderer)source).localBounds;
			if (pair.Bounds != localBounds)
			{
				pair.Bounds = localBounds;
				((Renderer)ink).localBounds = localBounds;
			}
			if (!((Renderer)ink).enabled || (!forceShapes && !((Renderer)source).isVisible && !((Renderer)ink).isVisible))
			{
				continue;
			}
			for (int i = 0; i < pair.Shapes; i++)
			{
				float blendShapeWeight = source.GetBlendShapeWeight(i);
				if (ink.GetBlendShapeWeight(i) != blendShapeWeight)
				{
					ink.SetBlendShapeWeight(i, blendShapeWeight);
				}
			}
		}
	}

	private void Awake()
	{
		Initialize();
	}

	private void LateUpdate()
	{
		Step();
	}
}
internal sealed class NePoLaBoLootLamyContext
{
	private sealed class Entry
	{
		internal ulong Owner;

		internal PlayerControllerB Player;

		internal NePoLaBoLootLamyRules Rules = new NePoLaBoLootLamyRules();
	}

	private sealed class Rig
	{
		internal GameObject Model;

		internal Transform[] Breasts;

		internal Transform Chest;

		internal NePoLaBoChestGazeTarget Authored;

		internal int Suit;
	}

	internal static ConfigEntry<bool> StarsEnabled;

	internal static ConfigEntry<bool> HeartsEnabled;

	internal static ConfigEntry<bool> LadderHearts;

	internal static ConfigEntry<bool> ChestGaze;

	internal static ConfigEntry<string> HeartSuits;

	internal static ConfigEntry<int> LootValue;

	internal static ConfigEntry<int> PileCount;

	internal static ConfigEntry<int> PileValue;

	internal static ConfigEntry<float> Duration;

	internal static ConfigEntry<float> NearRange;

	internal static ConfigEntry<float> GazeDelay;

	internal static ConfigEntry<float> GazeRamp;

	internal static ConfigEntry<float> PileRadius;

	internal static ConfigEntry<float> LadderRange;

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

	private static readonly Dictionary<int, Rig> rigs = new Dictionary<int, Rig>();

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

	private static StartOfRound scene;

	private static bool phaseSeeded;

	private static bool inShipPhase;

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

	private static InteractTrigger[] ladders = (InteractTrigger[])(object)new InteractTrigger[0];

	private static float nextObjects;

	private static string suitConfig;

	private static string[] suitTokens = new string[0];

	private readonly bool isLamy;

	private readonly PlayerControllerB player;

	private readonly Transform model;

	private NePoLaBoLootLamyRules rules;

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

	private float nextScan;

	private PlayerControllerB nearPlayer;

	private bool ladderHeart;

	internal bool Heart
	{
		get
		{
			if (isLamy && HeartsEnabled.Value)
			{
				if (!Object.op_Implicit((Object)(object)nearPlayer))
				{
					return ladderHeart;
				}
				return true;
			}
			return false;
		}
	}

	internal bool Stars
	{
		get
		{
			if (StarsEnabled.Value)
			{
				return rules.Stars(Time.unscaledTime);
			}
			return false;
		}
	}

	internal ulong GazePlayerId
	{
		get
		{
			if (!Object.op_Implicit((Object)(object)nearPlayer))
			{
				return ulong.MaxValue;
			}
			return nearPlayer.playerClientId;
		}
	}

	internal float GazeWeight
	{
		get
		{
			if (!Plugin.Eyes.Value || !ChestGaze.Value || !Object.op_Implicit((Object)(object)nearPlayer))
			{
				return 0f;
			}
			return rules.GazeWeight;
		}
	}

	internal static void Configure(ConfigFile config)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Expected O, but got Unknown
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Expected O, but got Unknown
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Expected O, but got Unknown
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Expected O, but got Unknown
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Expected O, but got Unknown
		StarsEnabled = config.Bind<bool>("Loot expressions", "StarEyes", true, "Star eyes for newly discovered valuable scrap, first pickup, and a qualifying visible ship pile on entry.");
		HeartsEnabled = config.Bind<bool>("Lamy expressions", "HeartEyes", true, "Heart eyes beside configured suits or below another climber on the same ladder.");
		LadderHearts = config.Bind<bool>("Lamy expressions", "LadderHeartEyes", true, (ConfigDescription)null);
		ChestGaze = config.Bind<bool>("Lamy expressions", "GradualChestGaze", true, "Allow only Lamy's eyes to drift toward the nearby target's authored breast bones, with humanoid chest fallback.");
		HeartSuits = config.Bind<string>("Lamy expressions", "HeartSuitNames", "Elizabeth Rose Bloodflame;Raora Panthera;Fuwawa Abyssgard;Mori Calliope;Shiori Novella;Nerissa Ravencroft;Kronii;Botan", "Semicolon-separated case-insensitive suit-name fragments. Spaces and punctuation are ignored. Empty list disables proximity hearts; ladder hearts remain independent.");
		LootValue = config.Bind<int>("Loot expressions", "HighValueLootThreshold", 100, new ConfigDescription("Value must be strictly greater than this threshold.", (