Decompiled source of Inspect v0.2.4

BepInEx/plugins/MastabaInspect/MastabaInspect.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Agents;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MastabaInspect.Firearms;
using MastabaInspect.Knives;
using Player;
using RootMotion.FinalIK;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Mastaba Inspect")]
[assembly: AssemblyFileVersion("0.2.4.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0")]
[assembly: AssemblyVersion("0.2.4.0")]
namespace MastabaInspect
{
	internal static class FingerAlignment
	{
		private const float THUMB_ROOT_LIMIT = (float)Math.PI * 13f / 36f;

		internal static Quaternion[] Straighten(Vector3[] segments, Quaternion[] rotations, Vector3 direction, float weight)
		{
			direction = Vector3.Normalize(direction);
			Quaternion quaternion = Quaternion.Identity;
			Quaternion[] array = new Quaternion[rotations.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Quaternion quaternion2 = Motion.FromTo(Vector3.Normalize(Vector3.Transform(segments[i], quaternion)), direction);
				quaternion2 = Quaternion.Slerp(Quaternion.Identity, quaternion2, weight);
				quaternion = Quaternion.Normalize(quaternion2 * quaternion);
				array[i] = Quaternion.Normalize(quaternion * rotations[i]);
			}
			return array;
		}

		internal static Quaternion[] ThumbContact(Vector3[] points, Quaternion[] rotations, Vector3 target, float weight)
		{
			Vector3 vector = points[1] - points[0];
			Vector3 vector2 = points[3] - points[1];
			Vector3 vector3 = target - points[0];
			float num = vector.Length();
			float num2 = vector2.Length();
			float num3 = MathF.Acos(Math.Clamp(Vector3.Dot(vector, vector2) / (num * num2), -1f, 1f));
			float value = MathF.Acos(Math.Clamp((vector3.LengthSquared() - num * num - num2 * num2) / (2f * num * num2), -1f, 1f));
			value = Math.Clamp(value, MathF.Max(0.08726646f, num3 - 0.6108652f), MathF.Max(0.08726646f, MathF.Min(1.9198622f, num3 + 0.6108652f)));
			Vector3 value2 = Vector3.Cross(vector, vector2);
			if (value2.LengthSquared() < 1E-12f)
			{
				value2 = Vector3.Cross(vector, vector3);
				if (value2.LengthSquared() < 1E-12f)
				{
					value2 = Vector3.Cross(vector, (MathF.Abs(vector.X / num) < 0.8f) ? Vector3.UnitX : Vector3.UnitY);
				}
			}
			Quaternion quaternion = Quaternion.CreateFromAxisAngle(Vector3.Normalize(value2), value - num3);
			Quaternion quaternion2 = Motion.FromTo(vector + Vector3.Transform(vector2, quaternion), vector3);
			float num4 = 2f * MathF.Acos(Math.Clamp(MathF.Abs(quaternion2.W), 0f, 1f));
			if (num4 > (float)Math.PI * 13f / 36f)
			{
				quaternion2 = Quaternion.Slerp(Quaternion.Identity, quaternion2, (float)Math.PI * 13f / 36f / num4);
			}
			quaternion2 = Quaternion.Slerp(Quaternion.Identity, quaternion2, weight);
			quaternion = Quaternion.Slerp(Quaternion.Identity, quaternion, weight);
			Quaternion quaternion3 = Quaternion.Normalize(quaternion2 * quaternion);
			return new Quaternion[3]
			{
				Quaternion.Normalize(quaternion2 * rotations[0]),
				Quaternion.Normalize(quaternion3 * rotations[1]),
				Quaternion.Normalize(quaternion3 * rotations[2])
			};
		}
	}
	[HarmonyPatch(typeof(InputMapper), "OnFocusStateChanged")]
	internal static class FocusPatch
	{
		[HarmonyPrefix]
		private static void Prefix([HarmonyArgument(0)] eFocusState focus)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)focus != 4)
			{
				InspectDriver local = InspectDriver.GetLocal();
				if (Object.op_Implicit((Object)(object)local))
				{
					local.Stop();
				}
			}
		}
	}
	[HarmonyPatch(typeof(FirstPersonItemHolder), "LateUpdate")]
	internal static class HolderLateUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			InspectDriver local = InspectDriver.GetLocal();
			if (Object.op_Implicit((Object)(object)local))
			{
				local.AfterHolderLateUpdate();
			}
		}
	}
	[HarmonyPatch(typeof(FirstPersonItemHolder), "Update")]
	internal static class HolderUpdatePatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			InspectDriver local = InspectDriver.GetLocal(Input.GetKeyDown((KeyCode)103));
			if (Object.op_Implicit((Object)(object)local))
			{
				local.BeforeHolderUpdate();
			}
		}
	}
	public sealed class InspectDriver : MonoBehaviour
	{
		private readonly ManualLogSource log = Logger.CreateLogSource("Mastaba Inspect");

		private readonly KnifeController knife;

		private readonly RevolverController revolver;

		private FirstPersonItemHolder holder;

		private int updateFrame = -1;

		private int poseFrame = -1;

		public InspectDriver(IntPtr pointer)
			: base(pointer)
		{
			knife = new KnifeController(log);
			revolver = new RevolverController(log);
		}

		[HideFromIl2Cpp]
		internal static InspectDriver GetLocal(bool create = false)
		{
			if (!PlayerManager.HasLocalPlayerAgent())
			{
				return null;
			}
			LocalPlayerAgent val = ((Il2CppObjectBase)PlayerManager.GetLocalPlayerAgent()).TryCast<LocalPlayerAgent>();
			FirstPersonItemHolder val2 = (Object.op_Implicit((Object)(object)val) ? ((PlayerAgent)val).FPItemHolder : null);
			if (!Object.op_Implicit((Object)(object)val2) || !((Agent)val).IsLocallyOwned)
			{
				return null;
			}
			InspectDriver inspectDriver = ((Component)val2).GetComponent<InspectDriver>();
			if (!Object.op_Implicit((Object)(object)inspectDriver) && create)
			{
				inspectDriver = ((Component)val2).gameObject.AddComponent<InspectDriver>();
				inspectDriver.holder = val2;
			}
			return inspectDriver;
		}

		[HideFromIl2Cpp]
		internal void BeforeHolderUpdate()
		{
			if (updateFrame == Time.frameCount)
			{
				return;
			}
			updateFrame = Time.frameCount;
			try
			{
				knife.RestorePose();
				revolver.RestorePose();
				bool keyDown = Input.GetKeyDown((KeyCode)103);
				knife.Update(holder, keyDown);
				revolver.BeforeHolderUpdate(holder, keyDown);
			}
			catch (Exception ex)
			{
				log.LogError((object)ex);
				Stop();
			}
		}

		[HideFromIl2Cpp]
		internal void AfterHolderLateUpdate()
		{
			if (poseFrame == Time.frameCount)
			{
				return;
			}
			poseFrame = Time.frameCount;
			try
			{
				knife.AfterHolderLateUpdate(holder);
				revolver.AfterHolderLateUpdate();
			}
			catch (Exception ex)
			{
				log.LogError((object)ex);
				Stop();
			}
		}

		[HideFromIl2Cpp]
		internal void Stop()
		{
			try
			{
				knife.Stop();
			}
			finally
			{
				revolver.Stop();
			}
		}

		public void OnDisable()
		{
			Stop();
		}

		public void OnDestroy()
		{
			try
			{
				Stop();
			}
			finally
			{
				log.Dispose();
			}
		}
	}
	[HarmonyPatch]
	internal static class InterruptPatch
	{
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(MeleeWeaponFirstPerson), "DoTriggerAttack", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(MeleeWeaponFirstPerson), "OnUnWield", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(FirstPersonItemHolder), "OnDestroy", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(LocalPlayerAgent), "LevelCleanup", (Type[])null, (Type[])null);
		}

		[HarmonyPrefix]
		private static void Prefix()
		{
			InspectDriver local = InspectDriver.GetLocal();
			if (Object.op_Implicit((Object)(object)local))
			{
				local.Stop();
			}
		}
	}
	[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "ChangeState")]
	internal static class MeleeStatePatch
	{
		[HarmonyPrefix]
		private static void Prefix([HarmonyArgument(0)] eMeleeWeaponState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)state != 1)
			{
				InspectDriver local = InspectDriver.GetLocal();
				if (Object.op_Implicit((Object)(object)local))
				{
					local.Stop();
				}
			}
		}
	}
	[BepInPlugin("fengj.mastaba.inspect", "Mastaba Inspect", "0.2.4")]
	[BepInProcess("GTFO.exe")]
	public sealed class Plugin : BasePlugin
	{
		private Harmony harmony;

		private const string PLUGIN_ID = "fengj.mastaba.inspect";

		public override void Load()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ClassInjector.RegisterTypeInIl2Cpp<InspectDriver>();
			harmony = new Harmony("fengj.mastaba.inspect");
			try
			{
				harmony.PatchAll(typeof(Plugin).Assembly);
			}
			catch
			{
				harmony.UnpatchSelf();
				throw;
			}
			((BasePlugin)this).Log.LogInfo((object)"Mastaba Inspect 0.2.4 loaded; press G with Mastaba R66, Mastaba Fixed Blade or WOX Compact.");
		}

		public override bool Unload()
		{
			foreach (InspectDriver item in Object.FindObjectsOfType<InspectDriver>())
			{
				item.Stop();
				Object.Destroy((Object)(object)item);
			}
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			return true;
		}
	}
	internal sealed class TransformLease
	{
		private Transform target;

		private Transform parent;

		private Vector3 position;

		private Quaternion rotation;

		private Vector3 appliedPosition;

		private Quaternion appliedRotation;

		private bool sealedPose;

		internal void Capture(Transform value)
		{
			//IL_0015: 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_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)
			target = value;
			parent = value.parent;
			position = value.localPosition;
			rotation = value.localRotation;
			sealedPose = false;
		}

		internal void Seal()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			appliedPosition = target.localPosition;
			appliedRotation = target.localRotation;
			sealedPose = true;
		}

		internal void Restore()
		{
			//IL_0054: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = target;
			target = null;
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val.parent != (Object)(object)parent)
			{
				return;
			}
			if (sealedPose)
			{
				Vector3 val2 = val.localPosition - appliedPosition;
				if (!(((Vector3)(ref val2)).sqrMagnitude < 1E-10f))
				{
					goto IL_005e;
				}
			}
			val.localPosition = position;
			goto IL_005e;
			IL_005e:
			if (!sealedPose || Quaternion.Angle(val.localRotation, appliedRotation) < 0.05f)
			{
				val.localRotation = rotation;
			}
			parent = null;
		}
	}
}
namespace MastabaInspect.Firearms
{
	internal sealed class ArmBinding
	{
		private readonly LimbIK limb;

		private readonly IKSolverLimb solver;

		private readonly Transform upper;

		private readonly Transform lower;

		private readonly Transform hand;

		private readonly TransformLease upperPose = new TransformLease();

		private readonly TransformLease lowerPose = new TransformLease();

		private readonly TransformLease handPose = new TransformLease();

		private float positionWeight;

		private float rotationWeight;

		private float forearmTwist;

		private bool saved;

		internal Vector3 HandPosition => hand.position;

		internal Transform HandTransform => hand;

		internal ArmBinding(LimbIK value)
		{
			limb = value;
			solver = value.solver;
			upper = ((Point)((IKSolverTrigonometric)solver).bone1).transform;
			lower = ((Point)((IKSolverTrigonometric)solver).bone2).transform;
			hand = ((Point)((IKSolverTrigonometric)solver).bone3).transform;
		}

		internal static bool CanBind(LimbIK limb, Transform item)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)limb) || limb.solver == null || !((IKSolver)limb.solver).initiated)
			{
				return false;
			}
			IKSolverLimb obj = limb.solver;
			TrigonometricBone bone = ((IKSolverTrigonometric)obj).bone1;
			Transform val = ((bone != null) ? ((Point)bone).transform : null);
			TrigonometricBone bone2 = ((IKSolverTrigonometric)obj).bone2;
			Transform val2 = ((bone2 != null) ? ((Point)bone2).transform : null);
			TrigonometricBone bone3 = ((IKSolverTrigonometric)obj).bone3;
			Transform val3 = ((bone3 != null) ? ((Point)bone3).transform : null);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val3) && val2.IsChildOf(val) && val3.IsChildOf(val2) && !val.IsChildOf(item))
			{
				Vector3 val4 = val3.position - val2.position;
				return ((Vector3)(ref val4)).sqrMagnitude > 0.0001f;
			}
			return false;
		}

		internal void Capture()
		{
			if (((Behaviour)limb).enabled)
			{
				((IKSolver)solver).Update();
			}
			upperPose.Capture(upper);
			lowerPose.Capture(lower);
			handPose.Capture(hand);
			positionWeight = ((IKSolver)solver).IKPositionWeight;
			rotationWeight = ((IKSolverTrigonometric)solver).IKRotationWeight;
			saved = true;
			((IKSolver)solver).IKPositionWeight = 0f;
			((IKSolverTrigonometric)solver).IKRotationWeight = 0f;
		}

		internal Vector3 Apply(Vector3 target, Quaternion delta)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			ArmPose armPose = Motion.SolveArm(ToNumerics(upper.position), ToNumerics(lower.position), ToNumerics(hand.position), ToNumerics(upper.rotation), ToNumerics(lower.rotation), ToNumerics(hand.rotation), ToNumerics(target), ToNumerics(delta), ref forearmTwist);
			upper.rotation = ToUnity(armPose.UpperRotation);
			lower.rotation = ToUnity(armPose.LowerRotation);
			hand.rotation = ToUnity(armPose.HandRotation);
			upperPose.Seal();
			lowerPose.Seal();
			handPose.Seal();
			return hand.position;
		}

		internal void Restore()
		{
			if (!saved)
			{
				return;
			}
			saved = false;
			try
			{
				upperPose.Restore();
				lowerPose.Restore();
				handPose.Restore();
			}
			finally
			{
				if (((IKSolver)solver).IKPositionWeight == 0f)
				{
					((IKSolver)solver).IKPositionWeight = positionWeight;
				}
				if (((IKSolverTrigonometric)solver).IKRotationWeight == 0f)
				{
					((IKSolverTrigonometric)solver).IKRotationWeight = rotationWeight;
				}
			}
		}

		internal static Vector3 ToNumerics(Vector3 value)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(value.x, value.y, value.z);
		}

		internal static Quaternion ToNumerics(Quaternion value)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(value.x, value.y, value.z, value.w);
		}

		internal static Vector3 ToUnity(Vector3 value)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(value.X, value.Y, value.Z);
		}

		internal static Quaternion ToUnity(Quaternion value)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(value.X, value.Y, value.Z, value.W);
		}
	}
	internal readonly record struct ArmPose(Vector3 Shoulder, Vector3 Elbow, Vector3 Hand, Quaternion UpperRotation, Quaternion LowerRotation, Quaternion HandRotation);
	internal static class Motion
	{
		internal static readonly PoseKey[] Keys = new PoseKey[14]
		{
			new PoseKey(0f, 0f, -0.03f, 0f, 0f),
			new PoseKey(0.28f, 0.14f, -0.028f, 0.82f, 0f),
			new PoseKey(0.85f, 0.94f, -0.022f, 1f, 0f),
			new PoseKey(1.15f, 1f, -0.012f, 1f, 0.65f),
			new PoseKey(1.55f, 1f, 0f, 1f, 1f),
			new PoseKey(2.05f, 1f, 0.045f, 1f, 1f),
			new PoseKey(2.95f, 1f, 0.88f, 1f, 1f),
			new PoseKey(3.45f, 1f, 1f, 1f, 1f),
			new PoseKey(3.95f, 1f, 0.92f, 1f, 1f),
			new PoseKey(4.9f, 1f, 0.07f, 1f, 1f),
			new PoseKey(5.35f, 1f, 0f, 1f, 1f),
			new PoseKey(5.7f, 1f, -0.015f, 1f, 0.5f),
			new PoseKey(6.1f, 0.82f, -0.03f, 0.96f, 0f),
			new PoseKey(6.8f, 0f, -0.03f, 0f, 0f)
		};

		internal const float DURATION = 6.8f;

		internal static PoseKey Sample(float time)
		{
			if (!float.IsFinite(time) || time <= 0f)
			{
				return Keys[0];
			}
			if (time >= 6.8f)
			{
				return Keys[^1];
			}
			int i;
			for (i = 0; time > Keys[i + 1].Time; i++)
			{
			}
			PoseKey poseKey = Keys[i];
			PoseKey poseKey2 = Keys[i + 1];
			float num = poseKey2.Time - poseKey.Time;
			Vector4 vector = (poseKey2.Channels - poseKey.Channels) / num;
			Vector4 vector2 = Vector4.Zero;
			Vector4 vector3 = Vector4.Zero;
			if (i > 0)
			{
				PoseKey poseKey3 = Keys[i - 1];
				float num2 = poseKey.Time - poseKey3.Time;
				vector2 = Tangent((poseKey.Channels - poseKey3.Channels) / num2, vector, num2, num);
			}
			if (i + 2 < Keys.Length)
			{
				PoseKey poseKey4 = Keys[i + 2];
				float num3 = poseKey4.Time - poseKey2.Time;
				vector3 = Tangent(vector, (poseKey4.Channels - poseKey2.Channels) / num3, num, num3);
			}
			float num4 = (time - poseKey.Time) / num;
			float num5 = num4 * num4;
			float num6 = num5 * num4;
			Vector4 vector4 = (2f * num6 - 3f * num5 + 1f) * poseKey.Channels + (num6 - 2f * num5 + num4) * num * vector2 + (-2f * num6 + 3f * num5) * poseKey2.Channels + (num6 - num5) * num * vector3;
			return new PoseKey(time, vector4.X, vector4.Y, vector4.Z, vector4.W);
		}

		private static Vector4 Tangent(Vector4 before, Vector4 after, float left, float right)
		{
			float num = 2f * right + left;
			float num2 = right + 2f * left;
			return new Vector4((before.X * after.X <= 0f) ? 0f : ((num + num2) / (num / before.X + num2 / after.X)), (before.Y * after.Y <= 0f) ? 0f : ((num + num2) / (num / before.Y + num2 / after.Y)), (before.Z * after.Z <= 0f) ? 0f : ((num + num2) / (num / before.Z + num2 / after.Z)), (before.W * after.W <= 0f) ? 0f : ((num + num2) / (num / before.W + num2 / after.W)));
		}

		internal static Quaternion Rotation(PoseKey sample)
		{
			Vector3 vector = Vector3.Normalize(new Vector3(-0.96f, 0.16f, 0.2f));
			Vector3 vector2 = Vector3.Normalize(Vector3.Cross(Vector3.UnitY, vector));
			Vector3 vector3 = Vector3.Cross(vector, vector2);
			return Quaternion.Normalize(Quaternion.CreateFromRotationMatrix(new Matrix4x4(vector2.X, vector2.Y, vector2.Z, 0f, vector3.X, vector3.Y, vector3.Z, 0f, vector.X, vector.Y, vector.Z, 0f, 0f, 0f, 0f, 1f)) * Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)Math.PI * sample.Reverse));
		}

		internal static Vector3 PresentationPivot(ReadOnlySpan<Vector3> muzzleOffsets, ViewFrame frame)
		{
			Vector3 vector = Vector3.Transform(Vector3.UnitZ, Rotation(Keys[2]));
			Vector3 vector2 = new Vector3(-1f, 0f, frame.Left);
			Vector3 vector3 = new Vector3(1f, 0f, 0f - frame.Right);
			Vector3 vector4 = new Vector3(0f, -1f, frame.Bottom);
			Vector3 vector5 = new Vector3(0f, 1f, 0f - frame.Top);
			float num = Vector3.Dot(vector2, vector);
			float num2 = Vector3.Dot(vector3, vector);
			float num3 = Vector3.Dot(vector4, vector);
			float num4 = Vector3.Dot(vector5, vector);
			float num5 = MathF.Sqrt(MathF.Max(0f, vector2.LengthSquared() - num * num));
			float num6 = MathF.Sqrt(MathF.Max(0f, vector3.LengthSquared() - num2 * num2));
			float num7 = MathF.Sqrt(MathF.Max(0f, vector4.LengthSquared() - num3 * num3));
			float num8 = MathF.Sqrt(MathF.Max(0f, vector5.LengthSquared() - num4 * num4));
			float num9 = MathF.Sqrt(MathF.Max(0f, 1f - vector.Z * vector.Z));
			float num10 = float.NegativeInfinity;
			float num11 = float.NegativeInfinity;
			float num12 = float.NegativeInfinity;
			float num13 = float.NegativeInfinity;
			float num14 = float.PositiveInfinity;
			ReadOnlySpan<Vector3> readOnlySpan = muzzleOffsets;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				Vector3 vector6 = readOnlySpan[i];
				float num15 = MathF.Sqrt(vector6.X * vector6.X + vector6.Y * vector6.Y);
				num10 = MathF.Max(num10, vector6.Z * num + num15 * num5);
				num11 = MathF.Max(num11, vector6.Z * num2 + num15 * num6);
				num12 = MathF.Max(num12, vector6.Z * num3 + num15 * num7);
				num13 = MathF.Max(num13, vector6.Z * num4 + num15 * num8);
				num14 = MathF.Min(num14, vector6.Z * vector.Z - num15 * num9);
			}
			float x = MathF.Max(0.45f, frame.Near - num14);
			x = MathF.Max(x, (num10 + num11) / (frame.Right - frame.Left));
			x = MathF.Max(x, (num12 + num13) / (frame.Top - frame.Bottom)) + 0.001f;
			return new Vector3(((frame.Left + frame.Right) * x + num10 - num11) * 0.5f, ((frame.Bottom + frame.Top) * x + num12 - num13) * 0.5f, x);
		}

		internal static Quaternion FromTo(Vector3 from, Vector3 to)
		{
			from = Vector3.Normalize(from);
			to = Vector3.Normalize(to);
			float num = Math.Clamp(Vector3.Dot(from, to), -1f, 1f);
			Vector3 vector = Vector3.Cross(from, to);
			if (num < -0.999999f)
			{
				float num2 = vector.Length();
				if (num2 > 1E-06f)
				{
					return Quaternion.CreateFromAxisAngle(vector / num2, MathF.Atan2(num2, num));
				}
				return Quaternion.CreateFromAxisAngle(Vector3.Normalize(Vector3.Cross(from, (MathF.Abs(from.X) < 0.8f) ? Vector3.UnitX : Vector3.UnitY)), (float)Math.PI);
			}
			return Quaternion.Normalize(new Quaternion(vector, 1f + num));
		}

		internal static ArmPose SolveArm(Vector3 shoulder, Vector3 elbow, Vector3 hand, Quaternion upperRotation, Quaternion lowerRotation, Quaternion handRotation, Vector3 target, Quaternion rotation, ref float forearmTwist)
		{
			float num = Vector3.Distance(shoulder, elbow);
			float num2 = Vector3.Distance(elbow, hand);
			Vector3 vector = Vector3.Normalize(target - shoulder);
			float num3 = Math.Clamp(Vector3.Distance(target, shoulder), MathF.Abs(num - num2) + 1E-05f, (num + num2) * 0.9995f);
			Vector3 vector2 = shoulder + vector * num3;
			Vector3 vector3 = elbow - shoulder;
			vector3 -= vector * Vector3.Dot(vector3, vector);
			if (vector3.LengthSquared() < 1E-09f)
			{
				vector3 = Vector3.Cross(vector, (MathF.Abs(vector.Y) < 0.8f) ? Vector3.UnitY : Vector3.UnitX);
			}
			vector3 = Vector3.Normalize(vector3);
			float num4 = (num * num - num2 * num2 + num3 * num3) / (2f * num3);
			float num5 = MathF.Sqrt(MathF.Max(0f, num * num - num4 * num4));
			Vector3 vector4 = shoulder + vector * num4 + vector3 * num5;
			Quaternion quaternion = FromTo(elbow - shoulder, vector4 - shoulder);
			Quaternion quaternion2 = FromTo(hand - elbow, vector2 - vector4);
			Quaternion quaternion3 = Quaternion.Normalize(rotation * handRotation);
			Quaternion quaternion4 = Quaternion.Normalize(quaternion3 * Quaternion.Inverse(quaternion2 * handRotation));
			Vector3 vector5 = Vector3.Normalize(vector2 - vector4);
			Vector3 vector6 = vector5 * Vector3.Dot(new Vector3(quaternion4.X, quaternion4.Y, quaternion4.Z), vector5);
			if (vector6.LengthSquared() + quaternion4.W * quaternion4.W > 1E-10f)
			{
				float num6 = 2f * MathF.Atan2(Vector3.Dot(vector6, vector5), quaternion4.W);
				num6 += (float)Math.PI * 2f * MathF.Round((forearmTwist - num6) / ((float)Math.PI * 2f));
				forearmTwist = num6;
			}
			quaternion2 = Quaternion.Normalize(Quaternion.CreateFromAxisAngle(vector5, forearmTwist * 0.7f) * quaternion2);
			return new ArmPose(shoulder, vector4, vector2, Quaternion.Normalize(quaternion * upperRotation), Quaternion.Normalize(quaternion2 * lowerRotation), quaternion3);
		}
	}
	internal readonly record struct PoseKey(float Time, float Weight, float Reverse, float Release, float Fingers)
	{
		internal Vector4 Channels => new Vector4(Weight, Reverse, Release, Fingers);

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Time = ");
			builder.Append(Time.ToString());
			builder.Append(", Weight = ");
			builder.Append(Weight.ToString());
			builder.Append(", Reverse = ");
			builder.Append(Reverse.ToString());
			builder.Append(", Release = ");
			builder.Append(Release.ToString());
			builder.Append(", Fingers = ");
			builder.Append(Fingers.ToString());
			return true;
		}
	}
	internal sealed class RevolverController
	{
		private readonly TransformLease rootPose = new TransformLease();

		private readonly ManualLogSource log;

		private FirstPersonItemHolder holder;

		private BulletWeapon weapon;

		private ArmBinding rightArm;

		private ArmBinding leftArm;

		private Camera itemCamera;

		private FingerChain indexFinger;

		private FingerChain thumb;

		private Transform hammer;

		private Vector3[] boundPoints;

		private Vector3[] cameraOffsets;

		private Vector3 presentationPivot;

		private bool presentationReady;

		private bool poseStarted;

		private bool relaxationLeased;

		private bool previousRelaxation;

		private float prepareUntil;

		private float startedAt;

		private bool active;

		private int updateFrame = -1;

		private int poseFrame = -1;

		private static readonly InputAction[] InterruptActions;

		internal RevolverController(ManualLogSource log)
		{
			this.log = log;
		}

		internal void BeforeHolderUpdate(FirstPersonItemHolder current, bool requested)
		{
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Invalid comparison between Unknown and I4
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			if (updateFrame == Time.frameCount)
			{
				return;
			}
			updateFrame = Time.frameCount;
			try
			{
				RestorePose();
				if (!Eligible(current, out var candidate))
				{
					Stop();
				}
				else if (active)
				{
					if ((Object)(object)candidate != (Object)(object)weapon || (poseStarted && Time.time - startedAt >= 6.8f))
					{
						Stop();
					}
					else
					{
						holder.DontRelax();
					}
				}
				else
				{
					if (!requested)
					{
						return;
					}
					PlayerFPSBody fPSArms = current.FPSArms;
					if (!Object.op_Implicit((Object)(object)fPSArms) || !Object.op_Implicit((Object)(object)current.m_ItemLayerCamera) || !Object.op_Implicit((Object)(object)((ItemEquippable)candidate).MuzzleAlign) || !ArmBinding.CanBind(fPSArms.m_rightHandIK, ((Component)candidate).transform) || !ArmBinding.CanBind(fPSArms.m_leftHandIK, ((Component)candidate).transform))
					{
						log.LogWarning((object)"Inspect skipped: the weapon or hand rig is unavailable.");
						return;
					}
					holder = current;
					weapon = candidate;
					rightArm = new ArmBinding(fPSArms.m_rightHandIK);
					leftArm = new ArmBinding(fPSArms.m_leftHandIK);
					indexFinger = FingerChain.Find(rightArm.HandTransform, "index", 1);
					thumb = FingerChain.Find(rightArm.HandTransform, "thumb", 0);
					if (indexFinger == null || thumb == null)
					{
						log.LogWarning((object)"Inspect skipped: the right-hand finger rig is unavailable.");
						Stop();
						return;
					}
					List<Vector3> list = new List<Vector3>();
					foreach (MeshFilter componentsInChild in ((Component)weapon).GetComponentsInChildren<MeshFilter>())
					{
						Renderer component = ((Component)componentsInChild).GetComponent<Renderer>();
						if (Object.op_Implicit((Object)(object)componentsInChild.sharedMesh) && ((Component)componentsInChild).gameObject.activeInHierarchy && Object.op_Implicit((Object)(object)component) && component.enabled)
						{
							Bounds bounds = componentsInChild.sharedMesh.bounds;
							if (((Object)componentsInChild.sharedMesh).name.StartsWith("Stock_Revolver_Hammer_1", StringComparison.Ordinal))
							{
								hammer = ((Component)componentsInChild).transform;
							}
							for (int i = 0; i < 8; i++)
							{
								Vector3 val = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1))));
								list.Add(((Component)weapon).transform.InverseTransformPoint(((Component)componentsInChild).transform.TransformPoint(val)));
							}
						}
					}
					if (list.Count == 0 || !Object.op_Implicit((Object)(object)hammer))
					{
						log.LogWarning((object)"Inspect skipped: the weapon bounds or hammer are unavailable.");
						Stop();
						return;
					}
					boundPoints = list.ToArray();
					cameraOffsets = new Vector3[boundPoints.Length];
					itemCamera = current.m_ItemLayerCamera;
					previousRelaxation = FirstPersonItemHolder.RelaxPoseEnabled;
					relaxationLeased = true;
					FirstPersonItemHolder.RelaxPoseEnabled = false;
					holder.OnTensedAction();
					holder.DontRelax();
					if ((int)holder.m_currentState == 2)
					{
						holder.ChangeState((FPItemStateName)1);
						holder.StartTransition(0.14f);
					}
					prepareUntil = Time.time + 0.18f;
					poseStarted = false;
					presentationReady = false;
					active = true;
					log.LogInfo((object)"R66 inspection preparing: right-hand grip, presentation framing enabled.");
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)ex);
				Stop();
			}
		}

		internal void AfterHolderLateUpdate()
		{
			//IL_01b0: 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_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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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_01fc: 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_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_00cd: Invalid comparison between Unknown and I4
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: 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_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			if (!active || poseFrame == Time.frameCount)
			{
				return;
			}
			poseFrame = Time.frameCount;
			try
			{
				RestorePose();
				if (!Object.op_Implicit((Object)(object)itemCamera) || !Object.op_Implicit((Object)(object)weapon) || !Object.op_Implicit((Object)(object)hammer) || !Eligible(holder, out var candidate) || (Object)(object)candidate != (Object)(object)weapon || (poseStarted && Time.time - startedAt >= 6.8f))
				{
					Stop();
					return;
				}
				Transform transform = ((Component)itemCamera).transform;
				Transform transform2 = ((Component)weapon).transform;
				if (!poseStarted)
				{
					if (Time.time < prepareUntil || (int)holder.m_currentState != 1)
					{
						return;
					}
					startedAt = Time.time;
					poseStarted = true;
					ManualLogSource obj = log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(55, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("R66 inspection started; bounds=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(boundPoints.Length);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; duration=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(6.8f);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; cameraFOV=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(itemCamera.fieldOfView, "F1");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					}
					obj.LogInfo(val);
				}
				rightArm.Capture();
				leftArm.Capture();
				indexFinger.Capture();
				thumb.Capture();
				rootPose.Capture(transform2);
				PoseKey sample = Motion.Sample(Time.time - startedAt);
				Quaternion val2 = transform.rotation * ArmBinding.ToUnity(Motion.Rotation(sample));
				Quaternion val3 = Quaternion.Slerp(Quaternion.identity, val2 * Quaternion.Inverse(((ItemEquippable)weapon).MuzzleAlign.rotation), sample.Weight);
				Vector3 handPosition = rightArm.HandPosition;
				if (!presentationReady)
				{
					Vector3 val4 = transform.InverseTransformPoint(itemCamera.ViewportToWorldPoint(new Vector3(0.1f, 0.04f, 1f)));
					Vector3 val5 = transform.InverseTransformPoint(itemCamera.ViewportToWorldPoint(new Vector3(0.9f, 0.56f, 1f)));
					ViewFrame frame = new ViewFrame(val4.x, val5.x, val4.y, val5.y, itemCamera.nearClipPlane + 0.02f);
					for (int i = 0; i < boundPoints.Length; i++)
					{
						cameraOffsets[i] = ArmBinding.ToNumerics(((ItemEquippable)weapon).MuzzleAlign.InverseTransformDirection(transform2.TransformPoint(boundPoints[i]) - handPosition));
					}
					presentationPivot = Motion.PresentationPivot(cameraOffsets, frame);
					presentationReady = true;
				}
				Vector3 value = Vector3.Lerp(ArmBinding.ToNumerics(transform.InverseTransformPoint(handPosition)), presentationPivot, sample.Weight);
				Vector3 target = transform.TransformPoint(ArmBinding.ToUnity(value));
				Vector3 val6 = val3 * (transform2.position - handPosition);
				Quaternion val7 = val3 * transform2.rotation;
				Vector3 handPosition2 = leftArm.HandPosition;
				float num = Mathf.Max(0.25f, transform.InverseTransformPoint(handPosition2).z);
				Vector3 val8 = itemCamera.ViewportToWorldPoint(new Vector3(0.12f, -0.35f, num));
				Quaternion delta = Quaternion.Slerp(Quaternion.identity, transform.rotation * Quaternion.AngleAxis(25f, Vector3.right) * Quaternion.Inverse(transform.rotation), sample.Release);
				Vector3 val9 = rightArm.Apply(target, val3);
				leftArm.Apply(Vector3.Lerp(handPosition2, val8, sample.Release), delta);
				transform2.SetPositionAndRotation(val9 + val6, val7);
				Transform muzzleAlign = ((ItemEquippable)weapon).MuzzleAlign;
				float num2 = ((Vector3.Dot(indexFinger.BasePosition - muzzleAlign.position, muzzleAlign.right) >= 0f) ? 1 : (-1));
				Vector3 val10 = muzzleAlign.forward - muzzleAlign.up * 0.24f + muzzleAlign.right * (num2 * 0.035f);
				Vector3 normalized = ((Vector3)(ref val10)).normalized;
				indexFinger.Straighten(normalized, sample.Fingers);
				Vector3 target2 = hammer.TransformPoint(new Vector3(0f, 0.0262146f, -0.0105896f)) + hammer.up * 0.004f;
				thumb.Contact(target2, sample.Fingers);
				indexFinger.Seal();
				thumb.Seal();
				rootPose.Seal();
			}
			catch (Exception ex)
			{
				log.LogError((object)ex);
				Stop();
			}
		}

		private static bool Eligible(FirstPersonItemHolder current, out BulletWeapon candidate)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			candidate = null;
			if (!Object.op_Implicit((Object)(object)current) || !Object.op_Implicit((Object)(object)current.m_owner) || !((Agent)current.m_owner).IsLocallyOwned || !((Agent)current.m_owner).Alive || !current.m_owner.IsEnabled || !current.m_isSetup)
			{
				return false;
			}
			if ((int)GameStateManager.CurrentStateName != 10 || (int)FocusStateManager.CurrentState != 4 || !InputMapper.PlayerHasFocus || (Object)(object)InputMapper.Current == (Object)null || InputMapper.Current.FocusSwitchPause)
			{
				return false;
			}
			if (current.IsPlayingAnimationSequence || current.ItemIsBusy || current.ForceItemHidden || current.ItemHiddenTrigger || current.ItemDownTrigger || current.ItemAimTrigger || !Object.op_Implicit((Object)(object)current.WieldedItem))
			{
				return false;
			}
			PlayerLocomotion locomotion = current.m_owner.Locomotion;
			if (!Object.op_Implicit((Object)(object)locomotion) || ((int)locomotion.m_currentStateEnum != 0 && (int)locomotion.m_currentStateEnum != 1 && (int)locomotion.m_currentStateEnum != 17))
			{
				return false;
			}
			candidate = ((Il2CppObjectBase)current.WieldedItem).TryCast<BulletWeapon>();
			if (!Object.op_Implicit((Object)(object)candidate) || !((ItemEquippable)candidate).IsFirstPerson || !((ItemEquippable)candidate).IsEnabled || !((ItemEquippable)candidate).m_isWielded || ((ItemEquippable)candidate).IsReloading || ((ItemEquippable)candidate).FireButton || ((ItemEquippable)candidate).AimButtonHeld || ((ItemEquippable)candidate).GearIDRange == null)
			{
				return false;
			}
			GearIDRange gearIDRange = ((ItemEquippable)candidate).GearIDRange;
			if (gearIDRange.PlayfabItemInstanceId != "OfflineGear_ID_15")
			{
				PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(15u);
				if (block == null || string.IsNullOrEmpty(block.GearJSON) || new GearIDRange(block.GearJSON).GetChecksum() != gearIDRange.GetChecksum())
				{
					return false;
				}
			}
			InputAction[] interruptActions = InterruptActions;
			foreach (InputAction val in interruptActions)
			{
				if (InputMapper.GetButton.Invoke(val, (eFocusState)4))
				{
					return false;
				}
			}
			return Math.Abs(InputMapper.GetAxis.Invoke((InputAction)30, (eFocusState)4)) < 0.01f;
		}

		internal void RestorePose()
		{
			try
			{
				thumb?.Restore();
			}
			finally
			{
				try
				{
					indexFinger?.Restore();
				}
				finally
				{
					try
					{
						rightArm?.Restore();
					}
					finally
					{
						try
						{
							leftArm?.Restore();
						}
						finally
						{
							rootPose.Restore();
						}
					}
				}
			}
		}

		internal void Stop()
		{
			active = false;
			poseStarted = false;
			presentationReady = false;
			try
			{
				RestorePose();
			}
			finally
			{
				if (relaxationLeased)
				{
					relaxationLeased = false;
					if (!FirstPersonItemHolder.RelaxPoseEnabled)
					{
						FirstPersonItemHolder.RelaxPoseEnabled = previousRelaxation;
					}
					if (Object.op_Implicit((Object)(object)holder))
					{
						holder.DontRelax();
					}
				}
				weapon = null;
				rightArm = null;
				leftArm = null;
				indexFinger = null;
				thumb = null;
				hammer = null;
				itemCamera = null;
				boundPoints = null;
				cameraOffsets = null;
			}
		}

		static RevolverController()
		{
			InputAction[] array = new InputAction[18];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			InterruptActions = (InputAction[])(object)array;
		}
	}
	internal readonly record struct ViewFrame(float Left, float Right, float Bottom, float Top, float Near);
}
namespace MastabaInspect.Knives
{
	internal readonly struct ArmPose
	{
		public readonly Vector3 ShoulderPosition;

		public readonly Vector3 ElbowPosition;

		public readonly Vector3 HandPosition;

		public readonly Quaternion ShoulderRotation;

		public readonly Quaternion ElbowRotation;

		public readonly Quaternion HandRotation;

		public ArmPose(Vector3 shoulderPosition, Vector3 elbowPosition, Vector3 handPosition, Quaternion shoulderRotation, Quaternion elbowRotation, Quaternion handRotation)
		{
			ShoulderPosition = shoulderPosition;
			ElbowPosition = elbowPosition;
			HandPosition = handPosition;
			ShoulderRotation = shoulderRotation;
			ElbowRotation = elbowRotation;
			HandRotation = handRotation;
		}
	}
	internal sealed class FingerChain
	{
		private readonly Transform[] joints;

		private readonly Transform tip;

		private readonly Vector3 tipOffset;

		private readonly TransformLease[] poses = new TransformLease[3]
		{
			new TransformLease(),
			new TransformLease(),
			new TransformLease()
		};

		internal int Kind { get; }

		internal string Name => ((Object)joints[0]).name;

		internal Vector3 BasePosition => joints[0].position;

		private FingerChain(Transform[] bones, Transform end, int kind)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			joints = bones;
			tip = end;
			Kind = kind;
			tipOffset = bones[1].InverseTransformPoint(bones[2].position) * 0.65f;
		}

		internal static FingerChain Find(Transform hand, string name, int kind)
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			int num = int.MaxValue;
			foreach (Transform componentsInChild in ((Component)hand).GetComponentsInChildren<Transform>())
			{
				if (Object.op_Implicit((Object)(object)componentsInChild) && componentsInChild.childCount != 0 && ((Object)componentsInChild).name.EndsWith("1", StringComparison.Ordinal) && ((Object)componentsInChild).name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					int num2 = 0;
					Transform val2 = componentsInChild;
					while (Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 != (Object)(object)hand && num2 < 16)
					{
						num2++;
						val2 = val2.parent;
					}
					if ((Object)(object)val2 == (Object)(object)hand && num2 < num)
					{
						val = componentsInChild;
						num = num2;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			string name2 = ((Object)val).name;
			string text = name2.Substring(0, name2.Length - 1);
			List<Transform> list = new List<Transform> { val };
			Vector3 val5;
			while (list.Count < 3)
			{
				Transform val3 = list[list.Count - 1];
				Transform val4 = null;
				for (int i = 0; i < val3.childCount; i++)
				{
					Transform child = val3.GetChild(i);
					if (string.Equals(((Object)child).name, text + (list.Count + 1), StringComparison.OrdinalIgnoreCase))
					{
						val5 = child.position - val3.position;
						if (((Vector3)(ref val5)).sqrMagnitude > 1E-10f)
						{
							val4 = child;
							break;
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)val4))
				{
					return null;
				}
				list.Add(val4);
			}
			Transform end = null;
			for (int j = 0; j < list[2].childCount; j++)
			{
				Transform child2 = list[2].GetChild(j);
				if (string.Equals(((Object)child2).name, text + "4", StringComparison.OrdinalIgnoreCase) || ((Object)child2).name.IndexOf("end", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val5 = child2.position - list[2].position;
					if (((Vector3)(ref val5)).sqrMagnitude > 1E-10f)
					{
						end = child2;
						break;
					}
				}
			}
			return new FingerChain(list.ToArray(), end, kind);
		}

		internal void Capture()
		{
			for (int i = 0; i < 3; i++)
			{
				poses[i].Capture(joints[i]);
			}
		}

		internal void Seal()
		{
			TransformLease[] array = poses;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Seal();
			}
		}

		internal void Restore()
		{
			try
			{
				poses[0].Restore();
			}
			finally
			{
				try
				{
					poses[1].Restore();
				}
				finally
				{
					poses[2].Restore();
				}
			}
		}

		internal void Straighten(Vector3 direction, float weight)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = new Vector3[3];
			Quaternion[] array2 = new Quaternion[3];
			for (int i = 0; i < 3; i++)
			{
				Vector3 val = ((i >= 2) ? ((!Object.op_Implicit((Object)(object)tip)) ? joints[2].TransformPoint(tipOffset) : tip.position) : joints[i + 1].position);
				Vector3 val2 = val - joints[i].position;
				Quaternion rotation = joints[i].rotation;
				array[i] = new Vector3(val2.x, val2.y, val2.z);
				array2[i] = new Quaternion(rotation.x, rotation.y, rotation.z, rotation.w);
			}
			Quaternion[] array3 = FingerAlignment.Straighten(array, array2, new Vector3(direction.x, direction.y, direction.z), weight);
			for (int j = 0; j < 3; j++)
			{
				Quaternion quaternion = array3[j];
				joints[j].rotation = new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
			}
		}

		internal void Contact(Vector3 target, float weight)
		{
			//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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = new Vector3[4];
			Quaternion[] array2 = new Quaternion[3];
			for (int i = 0; i < 3; i++)
			{
				Vector3 position = joints[i].position;
				Quaternion rotation = joints[i].rotation;
				array[i] = new Vector3(position.x, position.y, position.z);
				array2[i] = new Quaternion(rotation.x, rotation.y, rotation.z, rotation.w);
			}
			Vector3 val = (Object.op_Implicit((Object)(object)tip) ? tip.position : joints[2].TransformPoint(tipOffset));
			array[3] = new Vector3(val.x, val.y, val.z);
			Quaternion[] array3 = FingerAlignment.ThumbContact(array, array2, new Vector3(target.x, target.y, target.z), weight);
			for (int j = 0; j < 3; j++)
			{
				Quaternion quaternion = array3[j];
				joints[j].rotation = new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
			}
		}

		internal float Apply(Vector3 pivot, Vector3 axis, Vector3 sideAxis, float halfWidth, float degrees, MotionSample sample)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			if (sample.UprightA <= 0f)
			{
				return 0f;
			}
			Vector3[] array = new Vector3[4];
			Quaternion[] array2 = new Quaternion[3];
			for (int i = 0; i < 3; i++)
			{
				Vector3 position = joints[i].position;
				Quaternion rotation = joints[i].rotation;
				array[i] = new Vector3(position.x, position.y, position.z);
				array2[i] = new Quaternion(rotation.x, rotation.y, rotation.z, rotation.w);
			}
			Vector3 val = (Object.op_Implicit((Object)(object)tip) ? tip.position : joints[2].TransformPoint(tipOffset));
			array[3] = new Vector3(val.x, val.y, val.z);
			Vector3 target = ((Kind == 0) ? InspectMotion.ThumbTarget(array[3], array[0], pivot, axis, sideAxis, halfWidth, degrees, sample) : InspectMotion.FingerTarget(array[3], pivot, axis, degrees, sample, Kind));
			FingerPose fingerPose = InspectMotion.PoseFinger(array, array2, target, Kind == 0);
			for (int j = 0; j < 3; j++)
			{
				Quaternion quaternion = fingerPose.Rotations[j];
				joints[j].rotation = new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
			}
			return fingerPose.TargetError;
		}
	}
	internal readonly struct FingerPose
	{
		public readonly Vector3[] Points;

		public readonly Quaternion[] Rotations;

		public readonly float TargetError;

		public FingerPose(Vector3[] points, Quaternion[] rotations, float targetError)
		{
			Points = points;
			Rotations = rotations;
			TargetError = targetError;
		}
	}
	internal static class InspectMotion
	{
		private static readonly float[] Times = new float[8] { 0f, 0.9f, 1.5f, 2.4f, 3.2f, 4.1f, 4.3f, 5.2f };

		private static readonly MotionSample[] Keys = new MotionSample[8]
		{
			new MotionSample(0f, 0f),
			new MotionSample(1f, 0f),
			new MotionSample(1f, 0f),
			new MotionSample(0f, 1f),
			new MotionSample(0f, 1f),
			new MotionSample(1f, 0f),
			new MotionSample(1f, 0f),
			new MotionSample(0f, 0f)
		};

		public const float DURATION = 5.2f;

		public const float MAX_WRIST_ADJUSTMENT = 25f;

		public static MotionSample Sample(float time)
		{
			if (!float.IsFinite(time) || time <= 0f)
			{
				return Keys[0];
			}
			if (time >= 5.2f)
			{
				return Keys[^1];
			}
			int i;
			for (i = 0; time > Times[i + 1]; i++)
			{
			}
			float num = (time - Times[i]) / (Times[i + 1] - Times[i]);
			num = num * num * (3f - 2f * num);
			return new MotionSample(Keys[i].PoseB + (Keys[i + 1].PoseB - Keys[i].PoseB) * num, Keys[i].UprightA + (Keys[i + 1].UprightA - Keys[i].UprightA) * num);
		}

		public static float LiftRollSign(Vector3 forearm, Vector3 blade, Vector3 up)
		{
			return (Vector3.Dot(Vector3.Cross(forearm, blade), up) >= 0f) ? 1 : (-1);
		}

		private static Vector3 Unit(Vector3 v, Vector3 fallback)
		{
			if (!(v.LengthSquared() < 1E-10f))
			{
				return Vector3.Normalize(v);
			}
			return fallback;
		}

		private static Quaternion Turn(Vector3 axis, float degrees)
		{
			return Quaternion.CreateFromAxisAngle(Unit(axis, Vector3.UnitZ), degrees * (float)Math.PI / 180f);
		}

		private static Quaternion FromTo(Vector3 from, Vector3 to)
		{
			from = Unit(from, Vector3.UnitZ);
			to = Unit(to, from);
			float num = Math.Clamp(Vector3.Dot(from, to), -1f, 1f);
			if (num > 0f && Vector3.Cross(from, to).LengthSquared() < 1E-16f)
			{
				return Quaternion.Identity;
			}
			if (num < -0.999999f)
			{
				return Turn(Vector3.Cross(from, (Math.Abs(from.X) < 0.8f) ? Vector3.UnitX : Vector3.UnitY), 180f);
			}
			return Quaternion.Normalize(new Quaternion(Vector3.Cross(from, to), 1f + num));
		}

		public static Quaternion DisplayBladeRotation(bool faceB, float faceSign)
		{
			Vector3 vector = Vector3.Normalize(faceB ? new Vector3(0.32f, 0.945f, 0.06f) : new Vector3(0f, 1f, 0.04f));
			Vector3 vector2 = -Vector3.UnitZ * faceSign * ((!faceB) ? 1 : (-1));
			Vector3 vector3 = Vector3.Normalize(vector2 - vector * Vector3.Dot(vector2, vector));
			Vector3 vector4 = Vector3.Cross(vector, vector3);
			return Quaternion.CreateFromRotationMatrix(new Matrix4x4(vector3.X, vector3.Y, vector3.Z, 0f, vector4.X, vector4.Y, vector4.Z, 0f, vector.X, vector.Y, vector.Z, 0f, 0f, 0f, 0f, 1f));
		}

		private static Quaternion PresentationDelta(bool faceB, float faceSign, Quaternion bladeRotation, Quaternion cameraRotation, Vector3 forearm)
		{
			Quaternion quaternion = cameraRotation * DisplayBladeRotation(faceB, faceSign);
			Quaternion quaternion2 = quaternion * Quaternion.Inverse(bladeRotation);
			Vector3 vector = Vector3.Transform(Vector3.UnitZ, quaternion);
			Vector3 vector2 = Vector3.Transform(forearm, quaternion2);
			Vector3 vector3 = Vector3.Transform(Vector3.UnitZ, cameraRotation);
			float x = Vector3.Dot(vector2 - vector * Vector3.Dot(vector2, vector), vector3);
			float degrees = Math.Clamp(MathF.Atan2(Vector3.Dot(Vector3.Cross(vector, vector2), vector3), x) * 180f / (float)Math.PI, -55f, 55f);
			return Quaternion.Normalize(Turn(vector, degrees) * quaternion2);
		}

		public static ArmPose PoseArm(Vector3 shoulder, Vector3 elbow, Vector3 hand, Quaternion shoulderRotation, Quaternion elbowRotation, Quaternion handRotation, Quaternion bladeRotation, Quaternion cameraRotation, Vector3 thumbDirection, MotionSample sample, float rollSign, float faceSign)
		{
			if (sample.Weight <= 0f)
			{
				return new ArmPose(shoulder, elbow, hand, shoulderRotation, elbowRotation, handRotation);
			}
			Vector3 vector = Unit(hand - elbow, Vector3.UnitZ);
			Quaternion quaternion = PresentationDelta(faceB: true, faceSign, bladeRotation, cameraRotation, vector);
			Quaternion quaternion2 = Quaternion.Slerp(quaternion2: PresentationDelta(faceB: false, faceSign, bladeRotation, cameraRotation, vector), quaternion1: Quaternion.Normalize(quaternion * Quaternion.Inverse(Turn(vector, 180f * rollSign))), amount: sample.UprightA / sample.Weight);
			quaternion2 = Quaternion.Slerp(Quaternion.Identity, quaternion2, sample.Weight);
			Quaternion quaternion3 = Quaternion.Normalize(quaternion2 * Turn(vector, sample.ForearmRoll * rollSign));
			Quaternion handRotation2 = Quaternion.Normalize(quaternion3 * handRotation);
			Vector3 vector2 = Vector3.Transform(vector, quaternion3);
			Vector3 vector3 = Vector3.Transform(Unit(thumbDirection, vector), quaternion3);
			float num = MathF.Acos(Math.Clamp(Vector3.Dot(vector2, vector3), -1f, 1f)) * 180f / (float)Math.PI;
			Quaternion quaternion4 = Quaternion.Normalize(Quaternion.Slerp(Quaternion.Identity, FromTo(vector2, vector3), sample.UprightA * ((num > 0f) ? Math.Min(1f, 25f / num) : 0f)) * quaternion3);
			Vector3 value = new Vector3(-0.08f, 0.02f, 0f) * sample.PoseB + new Vector3(-0.095f, 0.025f, 0.005f) * sample.UprightA;
			Vector3 vector4 = hand + Vector3.Transform(value, cameraRotation);
			Vector3 vector5 = vector4 - Vector3.Transform(hand - elbow, quaternion4);
			Vector3 vector6 = Unit(vector5 - shoulder, Unit(elbow - shoulder, -Vector3.UnitY));
			Vector3 shoulderPosition = vector5 - vector6 * Vector3.Distance(elbow, shoulder);
			Quaternion quaternion5 = FromTo(elbow - shoulder, vector6);
			return new ArmPose(shoulderPosition, vector5, vector4, Quaternion.Normalize(quaternion5 * shoulderRotation), Quaternion.Normalize(quaternion4 * elbowRotation), handRotation2);
		}

		public static (Vector3 Position, Quaternion Rotation) FollowHand(Vector3 itemPosition, Quaternion itemRotation, Vector3 nativeHandPosition, Quaternion nativeHandRotation, Vector3 posedHandPosition, Quaternion posedHandRotation)
		{
			Quaternion quaternion = Quaternion.Normalize(posedHandRotation * Quaternion.Inverse(nativeHandRotation));
			return (Position: posedHandPosition + Vector3.Transform(itemPosition - nativeHandPosition, quaternion), Rotation: Quaternion.Normalize(quaternion * itemRotation));
		}

		public static float GripRollWeight(MotionSample sample)
		{
			float num = Math.Clamp((sample.UprightA - 0.12f) / 0.78f, 0f, 1f);
			return num * num * (3f - 2f * num);
		}

		public static float FaceRollAngle(Vector3 axis, Vector3 aFace, Vector3 towardCamera)
		{
			axis = Unit(axis, Vector3.UnitZ);
			Vector3 value = aFace - axis * Vector3.Dot(aFace, axis);
			Vector3 value2 = towardCamera - axis * Vector3.Dot(towardCamera, axis);
			if (value.LengthSquared() < 1E-10f || value2.LengthSquared() < 1E-10f)
			{
				return 0f;
			}
			value = Vector3.Normalize(value);
			value2 = Vector3.Normalize(value2);
			return Math.Clamp(MathF.Atan2(Vector3.Dot(axis, Vector3.Cross(value, value2)), Vector3.Dot(value, value2)) * 180f / (float)Math.PI, -100f, 100f);
		}

		public static (Vector3 Position, Quaternion Rotation) RollInGrip(Vector3 position, Quaternion rotation, Vector3 pivot, Vector3 axis, float degrees)
		{
			Quaternion quaternion = Turn(axis, degrees);
			return (Position: pivot + Vector3.Transform(position - pivot, quaternion), Rotation: Quaternion.Normalize(quaternion * rotation));
		}

		public static Vector3 FingerTarget(Vector3 tip, Vector3 pivot, Vector3 axis, float rollDegrees, MotionSample sample, int finger)
		{
			if (sample.UprightA <= 0f)
			{
				return tip;
			}
			axis = Unit(axis, Vector3.UnitZ);
			Vector3 vector = tip - pivot;
			vector -= axis * Vector3.Dot(vector, axis);
			float num = GripRollWeight(sample);
			float num2 = ((finger == 1) ? 0.35f : 0f);
			float num3 = ((finger == 1) ? 0.0015f : 0.004f) * 4f * sample.UprightA * (1f - sample.UprightA) + ((finger == 1) ? 0.0005f : 0.0015f) * sample.UprightA;
			Quaternion rotation = Turn(axis, rollDegrees * num * num2);
			return pivot + Vector3.Transform(tip - pivot, rotation) + Vector3.Transform(Unit(vector, Vector3.UnitX) * num3, rotation);
		}

		public static Vector3 ThumbTarget(Vector3 tip, Vector3 thumbBase, Vector3 pivot, Vector3 axis, Vector3 sideAxis, float halfWidth, float rollDegrees, MotionSample sample)
		{
			if (sample.UprightA <= 0f)
			{
				return tip;
			}
			axis = Vector3.Normalize(axis);
			sideAxis = Vector3.Normalize(sideAxis - axis * Vector3.Dot(sideAxis, axis));
			Vector3 vector = Vector3.Transform(sideAxis, Turn(axis, rollDegrees * (1f - GripRollWeight(sample))));
			float num = Vector3.Dot(tip - pivot, vector);
			if (Math.Abs(num) < 0.0001f)
			{
				num = Vector3.Dot(thumbBase - pivot, vector);
			}
			float num2 = MathF.CopySign(halfWidth + 0.01f, num);
			Vector3 value = tip + sideAxis * (num2 - Vector3.Dot(tip - pivot, sideAxis));
			float num3 = Math.Clamp(sample.UprightA / 0.32f, 0f, 1f);
			num3 *= num3 * (3f - 2f * num3);
			return Vector3.Lerp(tip, value, num3);
		}

		public static FingerPose PoseFinger(Vector3[] nativePoints, Quaternion[] nativeRotations, Vector3 target, bool thumb)
		{
			int num = nativeRotations.Length;
			if (num != 3 || nativePoints.Length != num + 1)
			{
				throw new ArgumentException("A finger requires three joints and one fingertip.");
			}
			Vector3[] array = (Vector3[])nativePoints.Clone();
			Quaternion[] array2 = (Quaternion[])nativeRotations.Clone();
			Vector3[] array3 = new Vector3[num];
			float[] array4 = new float[num];
			float[] array5 = new float[num];
			for (int i = 1; i < num; i++)
			{
				Vector3 vector = Unit(array[i] - array[i - 1], Vector3.UnitZ);
				Vector3 vector2 = Unit(array[i + 1] - array[i], vector);
				array3[i] = Unit(Vector3.Cross(vector, vector2), Unit(Vector3.Cross(vector, target - array[i]), Vector3.UnitX));
				array4[i] = MathF.Acos(Math.Clamp(Vector3.Dot(vector, vector2), -1f, 1f)) * 180f / (float)Math.PI;
			}
			for (int j = 0; j < 10; j++)
			{
				if (Vector3.DistanceSquared(array[num], target) < 2.5E-09f)
				{
					break;
				}
				for (int num2 = num - 1; num2 >= 0; num2--)
				{
					Quaternion quaternion3;
					if (num2 == 0)
					{
						Quaternion quaternion = FromTo(array[num] - array[num2], target - array[num2]);
						float num3 = QuaternionAngle(quaternion);
						quaternion = Quaternion.Slerp(Quaternion.Identity, quaternion, (num3 > 8f) ? (8f / num3) : 1f);
						Quaternion quaternion2 = Quaternion.Normalize(quaternion * array2[0] * Quaternion.Inverse(nativeRotations[0]));
						num3 = QuaternionAngle(quaternion2);
						float num4 = (thumb ? 28 : 16);
						quaternion2 = Quaternion.Slerp(Quaternion.Identity, quaternion2, (num3 > num4) ? (num4 / num3) : 1f);
						quaternion3 = Quaternion.Normalize(quaternion2 * nativeRotations[0] * Quaternion.Inverse(array2[0]));
					}
					else
					{
						Quaternion rotation = array2[num2 - 1] * Quaternion.Inverse(nativeRotations[num2 - 1]);
						Vector3 axis = Vector3.Transform(array3[num2], rotation);
						float value = FaceRollAngle(axis, array[num] - array[num2], target - array[num2]);
						float num5 = Math.Clamp(min: 0f - Math.Min(25f, Math.Max(0f, array4[num2] - 3f)), max: Math.Min(25f, Math.Max(0f, 155f - array4[num2])), value: array5[num2] + Math.Clamp(value, -8f, 8f));
						quaternion3 = Turn(axis, num5 - array5[num2]);
						array5[num2] = num5;
					}
					for (int k = num2 + 1; k <= num; k++)
					{
						array[k] = array[num2] + Vector3.Transform(array[k] - array[num2], quaternion3);
					}
					for (int l = num2; l < num; l++)
					{
						array2[l] = Quaternion.Normalize(quaternion3 * array2[l]);
					}
				}
			}
			return new FingerPose(array, array2, Vector3.Distance(array[num], target));
		}

		private static float QuaternionAngle(Quaternion q)
		{
			return 2f * MathF.Acos(Math.Clamp(Math.Abs(Quaternion.Normalize(q).W), 0f, 1f)) * 180f / (float)Math.PI;
		}
	}
	internal sealed class InspectSession
	{
		private float startedAt;

		public bool Active { get; private set; }

		public float Elapsed { get; private set; }

		public void Tick(float now, bool requested, bool eligible)
		{
			if (!eligible || !float.IsFinite(now))
			{
				Stop();
			}
			else if (Active)
			{
				Elapsed = now - startedAt;
				if (Elapsed < 0f || Elapsed >= 5.2f)
				{
					Stop();
				}
			}
			else if (requested)
			{
				Active = true;
				startedAt = now;
				Elapsed = 0f;
			}
		}

		public void Stop()
		{
			Active = false;
			Elapsed = 0f;
		}
	}
	internal sealed class KnifeController
	{
		private readonly ManualLogSource log;

		private readonly InspectSession session = new InspectSession();

		private FirstPersonItemHolder holder;

		private MeleeWeaponFirstPerson weapon;

		private Transform root;

		private Transform shoulder;

		private Transform forearm;

		private Transform hand;

		private Transform bladeHead;

		private Transform thumbBase;

		private Transform thumbNext;

		private Camera renderCamera;

		private IKSolverLimb rightSolver;

		private float nativePositionWeight;

		private float nativeRotationWeight;

		private bool weightsSaved;

		private readonly TransformLease rootPose = new TransformLease();

		private readonly TransformLease shoulderPose = new TransformLease();

		private readonly TransformLease forearmPose = new TransformLease();

		private readonly TransformLease handPose = new TransformLease();

		private bool poseApplied;

		private bool errorReported;

		private bool poseLogged;

		private float rollSign;

		private float faceSign;

		private Vector3 gripPivotLocal;

		private Vector3 gripSideLocal;

		private float gripHalfWidth;

		private float gripRollDegrees;

		private KnifeProfile knifeProfile;

		private readonly List<FingerChain> fingers = new List<FingerChain>();

		private int lastLoggedPose;

		private readonly InputAction[] interruptActions;

		private Quaternion BladeRotation => bladeHead.rotation * U(knifeProfile.FrameRotation);

		private Vector3 BladeForward => BladeRotation * Vector3.forward;

		private Vector3 BladeRight => BladeRotation * Vector3.right;

		internal KnifeController(ManualLogSource log)
		{
			InputAction[] array = new InputAction[16];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			interruptActions = (InputAction[])(object)array;
			base..ctor();
			this.log = log;
		}

		internal void Update(FirstPersonItemHolder current, bool requested)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			try
			{
				if (Object.op_Implicit((Object)(object)holder) && (Object)(object)holder != (Object)(object)current)
				{
					return;
				}
				if (!Object.op_Implicit((Object)(object)current) || !Object.op_Implicit((Object)(object)current.m_owner) || !((Agent)current.m_owner).IsLocallyOwned)
				{
					if (Object.op_Implicit((Object)(object)holder) && (Object)(object)holder == (Object)(object)current)
					{
						Stop();
					}
					return;
				}
				RestorePose();
				if (!requested && !session.Active)
				{
					return;
				}
				if (!CanInspect(current, out var candidate))
				{
					Stop();
					return;
				}
				if (session.Active && (Object)(object)candidate != (Object)(object)weapon)
				{
					Stop();
					return;
				}
				if (!session.Active)
				{
					if (!TryGetKnife(candidate, out var profile) || !Bind(current, candidate, profile))
					{
						return;
					}
					errorReported = false;
				}
				bool active = session.Active;
				session.Tick(Time.time, requested, eligible: true);
				if (!active && session.Active)
				{
					ManualLogSource obj = log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Inspect started: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(knifeProfile.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (ID ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(knifeProfile.OfflineID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
					}
					obj.LogInfo(val);
				}
				if (!session.Active)
				{
					Stop();
				}
			}
			catch (Exception exception)
			{
				Fail(exception);
			}
		}

		private bool CanInspect(FirstPersonItemHolder current, out MeleeWeaponFirstPerson candidate)
		{
			return BlockReason(current, out candidate) == null;
		}

		private unsafe string BlockReason(FirstPersonItemHolder current, out MeleeWeaponFirstPerson candidate)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Invalid comparison between Unknown and I4
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Invalid comparison between Unknown and I4
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Invalid comparison between Unknown and I4
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			candidate = null;
			if (!Object.op_Implicit((Object)(object)current))
			{
				return "first-person holder unavailable";
			}
			if (!Object.op_Implicit((Object)(object)current.m_owner))
			{
				return "holder owner unavailable";
			}
			if (!((Agent)current.m_owner).IsLocallyOwned)
			{
				return "holder is not locally owned";
			}
			if (!((Agent)current.m_owner).Alive)
			{
				return "player is not alive";
			}
			if (!current.m_owner.IsEnabled)
			{
				return "player IsEnabled=false";
			}
			if (!current.m_isSetup)
			{
				return "holder m_isSetup=false";
			}
			if ((int)GameStateManager.CurrentStateName != 10)
			{
				return "game state=" + ((object)GameStateManager.CurrentStateName/*cast due to .constrained prefix*/).ToString();
			}
			if ((int)FocusStateManager.CurrentState != 4)
			{
				return "focus=" + ((object)FocusStateManager.CurrentState/*cast due to .constrained prefix*/).ToString();
			}
			if (!InputMapper.PlayerHasFocus)
			{
				return "PlayerHasFocus=false";
			}
			if ((Object)(object)InputMapper.Current == (Object)null)
			{
				return "input mapper unavailable";
			}
			if (InputMapper.Current.FocusSwitchPause)
			{
				return "FocusSwitchPause=true";
			}
			if (current.IsPlayingAnimationSequence)
			{
				return "IsPlayingAnimationSequence=true";
			}
			if (current.ItemIsBusy)
			{
				return "ItemIsBusy=true";
			}
			if (current.ForceItemHidden || current.ItemHiddenTrigger || current.ItemDownTrigger)
			{
				return $"item hidden/down: force={current.ForceItemHidden}, hidden={current.ItemHiddenTrigger}, down={current.ItemDownTrigger}";
			}
			PlayerLocomotion locomotion = current.m_owner.Locomotion;
			if (!Object.op_Implicit((Object)(object)locomotion))
			{
				return "locomotion unavailable";
			}
			PLOC_State currentStateEnum = locomotion.m_currentStateEnum;
			if ((int)currentStateEnum != 0 && (int)currentStateEnum != 1 && (int)currentStateEnum != 17)
			{
				return "locomotion=" + ((object)(*(PLOC_State*)(&currentStateEnum))/*cast due to .constrained prefix*/).ToString();
			}
			if (!Object.op_Implicit((Object)(object)current.WieldedItem))
			{
				return "no wielded item";
			}
			candidate = ((Il2CppObjectBase)current.WieldedItem).TryCast<MeleeWeaponFirstPerson>();
			if (!Object.op_Implicit((Object)(object)candidate))
			{
				return "wielded item is not a first-person melee weapon";
			}
			if (!((ItemEquippable)candidate).IsFirstPerson || !((ItemEquippable)candidate).IsEnabled || !((ItemEquippable)candidate).m_isWielded)
			{
				return $"melee flags: firstPerson={((ItemEquippable)candidate).IsFirstPerson}, enabled={((ItemEquippable)candidate).IsEnabled}, wielded={((ItemEquippable)candidate).m_isWielded}";
			}
			if ((int)candidate.CurrentStateName != 1)
			{
				return "melee state=" + ((object)candidate.CurrentStateName/*cast due to .constrained prefix*/).ToString();
			}
			InputAction[] array = interruptActions;
			for (int i = 0; i < array.Length; i++)
			{
				InputAction val = array[i];
				if (InputMapper.GetButton.Invoke(val, (eFocusState)4))
				{
					return "held action=" + ((object)(*(InputAction*)(&val))/*cast due to .constrained prefix*/).ToString();
				}
			}
			if (Math.Abs(InputMapper.GetAxis.Invoke((InputAction)30, (eFocusState)4)) >= 0.01f)
			{
				return "equipment scroll input";
			}
			return null;
		}

		private bool TryGetKnife(MeleeWeaponFirstPerson item, out KnifeProfile profile)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			profile = default(KnifeProfile);
			GearIDRange gearIDRange = ((ItemEquippable)item).GearIDRange;
			if (gearIDRange == null)
			{
				return false;
			}
			KnifeProfile[] supported = KnifeProfile.Supported;
			for (int i = 0; i < supported.Length; i++)
			{
				KnifeProfile knifeProfile = supported[i];
				if (!(gearIDRange.PlayfabItemInstanceId != $"OfflineGear_ID_{knifeProfile.OfflineID}"))
				{
					profile = knifeProfile;
					return true;
				}
			}
			uint checksum = gearIDRange.GetChecksum();
			supported = KnifeProfile.Supported;
			for (int i = 0; i < supported.Length; i++)
			{
				KnifeProfile knifeProfile2 = supported[i];
				PlayerOfflineGearDataBlock block = GameDataBlockBase<PlayerOfflineGearDataBlock>.GetBlock(knifeProfile2.OfflineID);
				if (block != null && !string.IsNullOrEmpty(block.GearJSON) && new GearIDRange(block.GearJSON).GetChecksum() == checksum)
				{
					profile = knifeProfile2;
					return true;
				}
			}
			return false;
		}

		private bool Bind(FirstPersonItemHolder current, MeleeWeaponFirstPerson item, KnifeProfile profile)
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: 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_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			GearPartHolder gearPartHolder = ((ItemEquippable)item).GearPartHolder;
			if (!Object.op_Implicit((Object)(object)gearPartHolder) || !Object.op_Implicit((Object)(object)current.m_ItemLayerCamera))
			{
				log.LogWarning((object)"Inspect skipped: knife parts or first-person camera were unavailable.");
				return false;
			}
			MeshFilter val = (Object.op_Implicit((Object)(object)gearPartHolder.MeleeHandlePart) ? gearPartHolder.MeleeHandlePart.GetComponentInChildren<MeshFilter>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMesh))
			{
				log.LogWarning((object)"Inspect skipped: handle mesh unavailable.");
				return false;
			}
			MeshFilter val2 = val;
			if (!profile.IntegratedBlade)
			{
				val2 = (Object.op_Implicit((Object)(object)gearPartHolder.MeleeHeadPart) ? gearPartHolder.MeleeHeadPart.GetComponentInChildren<MeshFilter>() : null);
			}
			if (profile.IntegratedBlade && !val.sharedMesh.isReadable)
			{
				log.LogWarning((object)"Inspect skipped: integrated knife mesh is not readable.");
				return false;
			}
			PlayerFPSBody fPSArms = current.FPSArms;
			IKSolverLimb val3 = ((Object.op_Implicit((Object)(object)fPSArms) && Object.op_Implicit((Object)(object)fPSArms.m_rightHandIK)) ? fPSArms.m_rightHandIK.solver : null);
			object obj;
			if (val3 == null)
			{
				obj = null;
			}
			else
			{
				TrigonometricBone bone = ((IKSolverTrigonometric)val3).bone1;
				obj = ((bone != null) ? ((Point)bone).transform : null);
			}
			Transform val4 = (Transform)obj;
			object obj2;
			if (val3 == null)
			{
				obj2 = null;
			}
			else
			{
				TrigonometricBone bone2 = ((IKSolverTrigonometric)val3).bone2;
				obj2 = ((bone2 != null) ? ((Point)bone2).transform : null);
			}
			Transform val5 = (Transform)obj2;
			object obj3;
			if (val3 == null)
			{
				obj3 = null;
			}
			else
			{
				TrigonometricBone bone3 = ((IKSolverTrigonometric)val3).bone3;
				obj3 = ((bone3 != null) ? ((Point)bone3).transform : null);
			}
			Transform val6 = (Transform)obj3;
			if (Object.op_Implicit((Object)(object)val2) && val3 != null && ((IKSolver)val3).initiated && Object.op_Implicit((Object)(object)val4) && Object.op_Implicit((Object)(object)val5) && Object.op_Implicit((Object)(object)val6) && val5.IsChildOf(val4) && val6.IsChildOf(val5) && !val4.IsChildOf(((Component)item).transform) && !val5.IsChildOf(((Component)item).transform) && !val6.IsChildOf(((Component)item).transform))
			{
				Vector3 val7 = val6.position - val5.position;
				if (!(((Vector3)(ref val7)).sqrMagnitude < 0.0001f))
				{
					holder = current;
					weapon = item;
					root = ((Component)item).transform;
					shoulder = val4;
					forearm = val5;
					hand = val6;
					bladeHead = ((Component)val2).transform;
					knifeProfile = profile;
					rightSolver = val3;
					renderCamera = current.m_ItemLayerCamera;
					poseLogged = false;
					lastLoggedPose = 0;
					rollSign = InspectMotion.LiftRollSign(N(val6.position - val5.position), N(BladeForward), N(((Component)renderCamera).transform.up));
					faceSign = ((Vector3.Dot(BladeRight, ((Component)renderCamera).transform.position - bladeHead.position) >= 0f) ? 1 : (-1));
					FindThumbAxis();
					fingers.Clear();
					string[] array = new string[5] { "thumb", "index", "middle", "ring", "pinky" };
					for (int i = 0; i < array.Length; i++)
					{
						FingerChain fingerChain = FingerChain.Find(hand, array[i], i);
						if (fingerChain == null && i == 4)
						{
							fingerChain = FingerChain.Find(hand, "little", i);
						}
						if (fingerChain != null)
						{
							fingers.Add(fingerChain);
						}
					}
					Bounds bounds = val.sharedMesh.bounds;
					Vector3 val8 = ((Component)val).transform.TransformPoint(((Bounds)(ref bounds)).center);
					Vector3 val9 = (Object.op_Implicit((Object)(object)((Item)item).RightHandGripTrans) ? ((Item)item).RightHandGripTrans.position : hand.position);
					float num = ((Bounds)(ref bounds)).extents.x;
					if (profile.IntegratedBlade)
					{
						Il2CppStructArray<Vector3> vertices = val.sharedMesh.vertices;
						Vector3[] array2 = new Vector3[((Il2CppArrayBase<Vector3>)(object)vertices).Length];
						for (int j = 0; j < array2.Length; j++)
						{
							array2[j] = N(((Il2CppArrayBase<Vector3>)(object)vertices)[j]);
						}
						(Vector3, float) tuple = profile.MeasureGrip(array2, N(((Component)val).transform.InverseTransformPoint(val9)));
						val8 = ((Component)val).transform.TransformPoint(U(tuple.Item1));
						num = tuple.Item2;
					}
					gripSideLocal = root.InverseTransformDirection(((Component)val).transform.TransformDirection(U(profile.Right)));
					val7 = ((Component)val).transform.TransformVector(U(profile.Right) * num);
					gripHalfWidth = ((Vector3)(ref val7)).magnitude;
					Vector3 val10 = val8 + BladeForward * Vector3.Dot(val9 - val8, BladeForward);
					gripPivotLocal = root.InverseTransformPoint(val10);
					gripRollDegrees = float.NaN;
					if (!fingers.Exists((FingerChain f) => f.Kind == 0) || !fingers.Exists((FingerChain f) => f.Kind == 1))
					{
						log.LogWarning((object)"Inspect pinch: thumb/index chain unavailable; blade roll remains active.");
					}
					return true;
				}
			}
			log.LogWarning((object)"Inspect skipped: right-arm bone hierarchy was unavailable or unsuitable.");
			return false;
		}

		private void FindThumbAxis()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			thumbBase = (thumbNext = null);
			int num = int.MaxValue;
			foreach (Transform componentsInChild in ((Component)hand).GetComponentsInChildren<Transform>())
			{
				if (!Object.op_Implicit((Object)(object)componentsInChild) || componentsInChild.childCount == 0 || ((Object)componentsInChild).name.IndexOf("thumb", StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				int num2 = 0;
				Transform val = componentsInChild;
				while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)hand && num2 < 16)
				{
					num2++;
					val = val.parent;
				}
				if (!((Object)(object)val != (Object)(object)hand) && num2 < num)
				{
					Transform child = componentsInChild.GetChild(0);
					Vector3 val2 = child.position - componentsInChild.position;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 1E-08f))
					{
						num = num2;
						thumbBase = componentsInChild;
						thumbNext = child;
					}
				}
			}
		}

		internal void AfterHolderLateUpdate(FirstPersonItemHolder current)
		{
			//IL_01fe: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: 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_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Expected O, but got Unknown
			//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d7: Unknown result type (might be