Decompiled source of AbsoluteSolver v1.0.1

Mods/AbsoluteSolver.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AbsoluteSolver;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "AbsoluteSolver", "1.0.0", "CAitStudio", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AbsoluteSolver")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AbsoluteSolver")]
[assembly: AssemblyTitle("AbsoluteSolver")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AbsoluteSolver
{
	public class Core : MelonMod
	{
		private enum SolverMode
		{
			Classic,
			Advanced
		}

		private sealed class PendingDefenseCounter
		{
			public readonly GameObject SourceRoot;

			public readonly Collider SourceCollider;

			public readonly float ExecuteAt;

			public PendingDefenseCounter(GameObject sourceRoot, Collider sourceCollider, float executeAt)
			{
				SourceRoot = sourceRoot;
				SourceCollider = sourceCollider;
				ExecuteAt = executeAt;
			}

			public bool Matches(GameObject sourceRoot, Collider sourceCollider)
			{
				if ((Object)(object)SourceRoot != (Object)null && (Object)(object)sourceRoot != (Object)null)
				{
					return (Object)(object)SourceRoot == (Object)(object)sourceRoot;
				}
				if ((Object)(object)SourceCollider != (Object)null && (Object)(object)sourceCollider != (Object)null)
				{
					return (Object)(object)SourceCollider == (Object)(object)sourceCollider;
				}
				return false;
			}
		}

		private sealed class DefenseCounterGizmo
		{
			public readonly GameObject Object;

			public readonly SpriteRenderer Renderer;

			public readonly Rigidbody TargetBody;

			public readonly float Size;

			public readonly float VisibleUntil;

			public DefenseCounterGizmo(GameObject gizmoObject, SpriteRenderer renderer, Rigidbody targetBody, float size, float visibleUntil)
			{
				Object = gizmoObject;
				Renderer = renderer;
				TargetBody = targetBody;
				Size = size;
				VisibleUntil = visibleUntil;
			}
		}

		private sealed class ObjectGizmoIntro
		{
			public readonly Vector3 StartPosition;

			public float Time;

			public ObjectGizmoIntro(Vector3 startPosition)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				StartPosition = startPosition;
			}
		}

		private sealed class GizmoSpriteTransition
		{
			private const float TotalDuration = 0.5f;

			public Sprite CurrentSprite;

			public Sprite TargetSprite;

			public Sprite DisplaySprite;

			public float Time;

			public bool IsTransitioning;

			public GizmoSpriteTransition(Sprite sprite)
			{
				CurrentSprite = sprite;
				TargetSprite = sprite;
				DisplaySprite = sprite;
			}

			public void Start(Sprite currentSprite, Sprite targetSprite)
			{
				CurrentSprite = currentSprite;
				TargetSprite = targetSprite;
				DisplaySprite = currentSprite;
				Time = 0f;
				IsTransitioning = true;
			}

			public void Update(Sprite desiredSprite, ref float scale, ref float spinAngle)
			{
				if (!IsTransitioning)
				{
					CurrentSprite = desiredSprite;
					TargetSprite = desiredSprite;
					DisplaySprite = desiredSprite;
					return;
				}
				Time += Time.deltaTime;
				if (Time < 0.25f)
				{
					float num = Mathf.Clamp01(Time / 0.25f);
					DisplaySprite = CurrentSprite;
					scale *= 1f - Mathf.SmoothStep(0f, 1f, num);
					spinAngle = -520f * num;
				}
				else if (Time < 0.5f)
				{
					float num2 = Mathf.Clamp01((Time - 0.25f) / 0.25f);
					DisplaySprite = TargetSprite;
					scale *= Mathf.SmoothStep(0f, 1f, num2);
					spinAngle = 520f * num2;
				}
				else
				{
					CurrentSprite = TargetSprite;
					DisplaySprite = TargetSprite;
					Time = 0.5f;
					IsTransitioning = false;
				}
			}
		}

		private sealed class HandGizmo
		{
			public readonly GameObject Object;

			public readonly SpriteRenderer Renderer;

			public Hand Hand;

			public float TargetSize;

			public float AnimTime;

			public float SpinAngle;

			public bool IsClosing;

			public HandGizmo(GameObject gizmoObject, SpriteRenderer renderer, Hand hand)
			{
				Object = gizmoObject;
				Renderer = renderer;
				Hand = hand;
			}
		}

		private sealed class AdvancedForceDriver
		{
			private readonly Rigidbody _targetBody;

			private readonly CollisionDetectionMode _oldCollisionDetectionMode;

			private readonly int _oldSolverIterations;

			private readonly int _oldSolverVelocityIterations;

			private List<Vector3> _trajectoryOffsets;

			private Vector3 _trajectoryBaseTarget;

			private float _trajectoryCursor;

			public Vector3 TargetPosition;

			public Rigidbody TargetBody => _targetBody;

			public AdvancedForceDriver(Rigidbody targetBody, Vector3 targetPosition)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				_targetBody = targetBody;
				TargetPosition = targetPosition;
				if (!((Object)(object)_targetBody == (Object)null))
				{
					_oldCollisionDetectionMode = _targetBody.collisionDetectionMode;
					_oldSolverIterations = _targetBody.solverIterations;
					_oldSolverVelocityIterations = _targetBody.solverVelocityIterations;
					if (_targetBody.isKinematic)
					{
						_targetBody.isKinematic = false;
					}
					_targetBody.collisionDetectionMode = (CollisionDetectionMode)2;
					_targetBody.solverIterations = Mathf.Max(_targetBody.solverIterations, 12);
					_targetBody.solverVelocityIterations = Mathf.Max(_targetBody.solverVelocityIterations, 4);
					_targetBody.WakeUp();
				}
			}

			public bool Update()
			{
				//IL_0033: 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_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				if ((Object)(object)_targetBody == (Object)null || (Object)(object)((Component)_targetBody).gameObject == (Object)null)
				{
					return false;
				}
				UpdateTrajectoryPlayback();
				Vector3 val = TargetPosition - _targetBody.position;
				Vector3 val2 = val * 55f - _targetBody.velocity * 13f;
				val2 = Vector3.ClampMagnitude(val2, 85f);
				_targetBody.AddForce(val2, (ForceMode)5);
				_targetBody.WakeUp();
				return true;
			}

			public void PlayTrajectory(Vector3 baseTarget, List<Vector3> offsets)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				if (offsets != null && offsets.Count != 0)
				{
					_trajectoryBaseTarget = baseTarget;
					_trajectoryOffsets = new List<Vector3>(offsets);
					_trajectoryCursor = 0f;
					TargetPosition = _trajectoryBaseTarget + _trajectoryOffsets[0];
				}
			}

			private void UpdateTrajectoryPlayback()
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: 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)
				if (_trajectoryOffsets != null && _trajectoryOffsets.Count != 0)
				{
					_trajectoryCursor += 90f * Time.deltaTime;
					int num = Mathf.Clamp(Mathf.FloorToInt(_trajectoryCursor), 0, _trajectoryOffsets.Count - 1);
					TargetPosition = _trajectoryBaseTarget + _trajectoryOffsets[num];
					if (num >= _trajectoryOffsets.Count - 1)
					{
						TargetPosition = _trajectoryBaseTarget + _trajectoryOffsets[_trajectoryOffsets.Count - 1];
						_trajectoryOffsets = null;
						_trajectoryCursor = 0f;
					}
				}
			}

			public void Destroy()
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_targetBody == (Object)null))
				{
					_targetBody.collisionDetectionMode = _oldCollisionDetectionMode;
					_targetBody.solverIterations = _oldSolverIterations;
					_targetBody.solverVelocityIterations = _oldSolverVelocityIterations;
					_targetBody.WakeUp();
				}
			}
		}

		private sealed class AdvancedTrajectoryRecorder
		{
			private readonly Vector3 _startHandPosition;

			private readonly Vector3 _baseTarget;

			private readonly List<Vector3> _offsets = new List<Vector3>();

			private Vector3 _lastHandPosition;

			private Vector3 _lastOffset;

			private Vector3 _strongestVelocity;

			private float _lastSampleTime;

			public AdvancedTrajectoryRecorder(Vector3 startHandPosition, Vector3 baseTarget)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				_startHandPosition = startHandPosition;
				_baseTarget = baseTarget;
				_lastHandPosition = startHandPosition;
				_lastSampleTime = Time.realtimeSinceStartup;
				_offsets.Add(Vector3.zero);
			}

			public void Record(Vector3 handPosition, bool force = false)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: 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)
				if (_offsets.Count >= 180)
				{
					return;
				}
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				float num = Mathf.Max(0.001f, realtimeSinceStartup - _lastSampleTime);
				Vector3 strongestVelocity = (handPosition - _lastHandPosition) / num;
				float magnitude = ((Vector3)(ref strongestVelocity)).magnitude;
				float num2 = Mathf.Clamp(1f + magnitude * 0.55f, 1f, 4f);
				Vector3 val = (handPosition - _startHandPosition) * 2.5f * num2;
				if (!force)
				{
					Vector3 val2 = val - _lastOffset;
					if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
					{
						if (((Vector3)(ref strongestVelocity)).sqrMagnitude > ((Vector3)(ref _strongestVelocity)).sqrMagnitude)
						{
							_strongestVelocity = strongestVelocity;
						}
						_lastHandPosition = handPosition;
						_lastSampleTime = realtimeSinceStartup;
						return;
					}
				}
				_offsets.Add(val);
				_lastOffset = val;
				if (((Vector3)(ref strongestVelocity)).sqrMagnitude > ((Vector3)(ref _strongestVelocity)).sqrMagnitude)
				{
					_strongestVelocity = strongestVelocity;
				}
				_lastHandPosition = handPosition;
				_lastSampleTime = realtimeSinceStartup;
			}

			public bool TryCreateTrajectory(out List<Vector3> offsets, out Vector3 baseTarget)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				baseTarget = _baseTarget;
				offsets = null;
				if (_offsets.Count < 2)
				{
					return false;
				}
				offsets = new List<Vector3>(_offsets);
				return true;
			}

			public bool TryGetLaunchVelocity(float mass, out Vector3 launchVelocity)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = _lastHandPosition - _startHandPosition;
				Vector3 rawVelocity = _strongestVelocity;
				if (((Vector3)(ref rawVelocity)).sqrMagnitude < 36f && ((Vector3)(ref val)).sqrMagnitude > 0.0001f)
				{
					rawVelocity = ((Vector3)(ref val)).normalized * 24f;
				}
				launchVelocity = ScaleAdvancedLaunchVelocity(rawVelocity, mass);
				return ((Vector3)(ref launchVelocity)).sqrMagnitude > 0.0001f;
			}
		}

		[HarmonyPatch(typeof(Grip), "Awake")]
		private static class GripAwakePatch
		{
			[HarmonyPostfix]
			private static void Postfix(Grip __instance)
			{
				if (IsRuntimeAvailable())
				{
					QueueForcePullGripScan(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Player_Health), "TAKEDAMAGE")]
		private static class PlayerHealthTakeDamagePatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Player_Health __instance)
			{
				return !IsRuntimeAvailable() || !TryBlockDamageWithDefenseShield(__instance);
			}
		}

		[HarmonyPatch(typeof(Player_Health), "ApplyKillDamage")]
		private static class PlayerHealthApplyKillDamagePatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Player_Health __instance)
			{
				return !IsRuntimeAvailable() || !TryBlockDamageWithDefenseShield(__instance);
			}
		}

		[HarmonyPatch(typeof(Player_Health), "Death")]
		private static class PlayerHealthDeathPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Player_Health __instance)
			{
				return !IsRuntimeAvailable() || !TryBlockDamageWithDefenseShield(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")]
		private static class PlayerDamageReceiverReceiveAttackPatch
		{
			[HarmonyPrefix]
			private static void Prefix(PlayerDamageReceiver __instance, ref Attack attack)
			{
				if (!IsRuntimeAvailable())
				{
					return;
				}
				try
				{
					Player_Health val = (((Object)(object)((__instance != null) ? __instance.health : null) != (Object)null) ? ((Il2CppObjectBase)__instance.health).TryCast<Player_Health>() : null);
					if (!((Object)(object)val == (Object)null) && IsDefenseShieldActiveFor(val))
					{
						Instance?.ScheduleDefenseCounter(attack);
					}
				}
				catch (Exception ex)
				{
					Core instance = Instance;
					if (instance != null)
					{
						((MelonBase)instance).LoggerInstance.Warning("Defense counter scheduling failed: " + ex.Message);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Poolee), "OnSpawn")]
		private static class PooleeOnSpawnPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Poolee __instance)
			{
				if (IsRuntimeAvailable() && (Object)(object)__instance != (Object)null)
				{
					EnsureForcePullGripsIn(((Component)__instance).gameObject);
				}
			}
		}

		[HarmonyPatch(typeof(Poolee), "OnEnable")]
		private static class PooleeOnEnablePatch
		{
			[HarmonyPostfix]
			private static void Postfix(Poolee __instance)
			{
				if (IsRuntimeAvailable() && (Object)(object)__instance != (Object)null)
				{
					EnsureForcePullGripsIn(((Component)__instance).gameObject);
				}
			}
		}

		[HarmonyPatch(typeof(ForcePullGrip), "OnFarHandHoverUpdate")]
		private static class ForcePullGripHoverPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(ForcePullGrip __instance, Hand hand)
			{
				if (!IsRuntimeAvailable())
				{
					return true;
				}
				if (HasObjectInHand(hand))
				{
					return false;
				}
				Grip val = ((__instance != null) ? __instance._grip : null);
				if ((Object)(object)val != (Object)null)
				{
					Instance?.SelectGrip(val, hand);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(OpenController), "CheckMenuTap")]
		private static class OpenControllerCheckMenuTapPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(OpenController __instance)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetMenuTap")]
		private static class OpenControllerGetMenuTapPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetSecondaryMenuButton")]
		private static class OpenControllerGetSecondaryMenuButtonPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetSecondaryMenuButtonDown")]
		private static class OpenControllerGetSecondaryMenuButtonDownPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetSecondaryMenuButtonUp")]
		private static class OpenControllerGetSecondaryMenuButtonUpPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetBButtonDown")]
		private static class OpenControllerGetBButtonDownPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenController), "GetBButtonUp")]
		private static class OpenControllerGetBButtonUpPatch
		{
			[HarmonyPostfix]
			private static void Postfix(OpenController __instance, ref bool __result)
			{
				if (Instance != null && Instance.ShouldSuppressMenuFor((BaseController)(object)__instance))
				{
					__result = false;
				}
			}
		}

		private interface IForceGrabHandle
		{
			Rigidbody TargetBody { get; }

			bool IsRotating { get; }
		}

		private sealed class ClassicTelekinesisHandle : IForceGrabHandle
		{
			private readonly Hand _hand;

			private readonly Grip _targetGrip;

			private readonly Rigidbody _handBody;

			private readonly Rigidbody _targetBody;

			private readonly GameObject _tkGripObject;

			private readonly Rigidbody _tkGripBody;

			private readonly ConfigurableJoint _joint;

			private readonly int _oldSolverIterations;

			private readonly int _oldSolverVelocityIterations;

			private readonly CollisionDetectionMode _oldCollisionDetectionMode;

			private readonly float _oldDrag;

			private readonly float _oldAngularDrag;

			private readonly float _oldMaxAngularVelocity;

			private readonly Vector3 _connectedAnchor;

			private readonly float _catchTime;

			private Vector3 _lastHandPosition;

			private Vector3 _lastBodyPosition;

			private Vector3 _lastRelativeHandVelocity;

			private float _lastVelocitySampleTime;

			private float _gripDistance;

			private bool _spinMode;

			private float _spinStartTime;

			private float _spinVelocity;

			private bool _isRotating;

			public Rigidbody TargetBody => _targetBody;

			public bool IsRotating => _isRotating;

			public ClassicTelekinesisHandle(Hand hand, Grip targetGrip, Rigidbody handBody, Rigidbody targetBody)
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Expected O, but got Unknown
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				_hand = hand;
				_targetGrip = targetGrip;
				_handBody = handBody;
				_targetBody = targetBody;
				_oldSolverIterations = targetBody.solverIterations;
				_oldSolverVelocityIterations = targetBody.solverVelocityIterations;
				_oldCollisionDetectionMode = targetBody.collisionDetectionMode;
				_oldDrag = targetBody.drag;
				_oldAngularDrag = targetBody.angularDrag;
				_oldMaxAngularVelocity = targetBody.maxAngularVelocity;
				targetBody.solverIterations = Mathf.Max(targetBody.solverIterations, 12);
				targetBody.solverVelocityIterations = Mathf.Max(targetBody.solverVelocityIterations, 4);
				targetBody.collisionDetectionMode = (CollisionDetectionMode)2;
				targetBody.maxAngularVelocity = Mathf.Max(targetBody.maxAngularVelocity, 20f);
				Vector3 val = (((Object)(object)targetGrip != (Object)null) ? ((Component)targetGrip).transform.position : targetBody.worldCenterOfMass);
				_connectedAnchor = ((Component)targetBody).transform.InverseTransformPoint(val);
				Vector3 physicalHandPosition = GetPhysicalHandPosition(hand, handBody);
				_gripDistance = Mathf.Clamp(Vector3.Distance(physicalHandPosition, val), 0.25f, 12f);
				_catchTime = Time.time;
				_lastHandPosition = physicalHandPosition;
				_lastBodyPosition = GetPlayerBodyPosition(physicalHandPosition);
				_lastRelativeHandVelocity = Vector3.zero;
				_lastVelocitySampleTime = Time.realtimeSinceStartup;
				_tkGripObject = new GameObject("TkGrip");
				_tkGripObject.transform.position = val;
				_tkGripObject.transform.rotation = GetPhysicalHandRotation(hand, handBody);
				_tkGripBody = Core.AddIl2CppComponent<Rigidbody>(_tkGripObject);
				if ((Object)(object)_tkGripBody == (Object)null)
				{
					throw new InvalidOperationException("Could not create Classic TkGrip Rigidbody.");
				}
				_tkGripBody.isKinematic = true;
				_tkGripBody.detectCollisions = false;
				_tkGripBody.useGravity = false;
				_tkGripBody.interpolation = (RigidbodyInterpolation)1;
				_joint = Core.AddIl2CppComponent<ConfigurableJoint>(_tkGripObject);
				if ((Object)(object)_joint == (Object)null)
				{
					throw new InvalidOperationException("Could not create Classic ConfigurableJoint.");
				}
				CreateJoint();
				ApplyDrag(5f);
				targetBody.WakeUp();
			}

			private void CreateJoint()
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				((Joint)_joint).autoConfigureConnectedAnchor = false;
				((Joint)_joint).anchor = Vector3.zero;
				((Joint)_joint).connectedBody = _targetBody;
				((Joint)_joint).connectedAnchor = _connectedAnchor;
				_joint.rotationDriveMode = (RotationDriveMode)0;
				float classicMassCompensation = GetClassicMassCompensation(_targetBody.mass);
				JointDrive val = CreateDrive(100f, 10f, 1000f * classicMassCompensation);
				JointDrive val2 = CreateDrive(10f, 1f, 1000f * classicMassCompensation);
				_joint.xDrive = val;
				_joint.yDrive = val;
				_joint.zDrive = val;
				_joint.angularXDrive = val2;
				_joint.angularYZDrive = val2;
				_joint.xMotion = (ConfigurableJointMotion)2;
				_joint.yMotion = (ConfigurableJointMotion)2;
				_joint.zMotion = (ConfigurableJointMotion)2;
				_joint.angularXMotion = (ConfigurableJointMotion)2;
				_joint.angularYMotion = (ConfigurableJointMotion)2;
				_joint.angularZMotion = (ConfigurableJointMotion)2;
				((Joint)_joint).connectedMassScale = classicMassCompensation;
				((Joint)_joint).enableCollision = false;
				((Joint)_joint).enablePreprocessing = true;
			}

			private static JointDrive CreateDrive(float spring, float damper, float maximumForce)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: 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)
				JointDrive result = default(JointDrive);
				((JointDrive)(ref result)).positionSpring = spring;
				((JointDrive)(ref result)).positionDamper = damper;
				((JointDrive)(ref result)).maximumForce = maximumForce;
				return result;
			}

			public bool Update(float trigger = 0f, float pushAway = 0f)
			{
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: Unknown result type (might be due to invalid IL or missing references)
				//IL_0296: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_hand == (Object)null || (Object)(object)_targetGrip == (Object)null || (Object)(object)_handBody == (Object)null || (Object)(object)_targetBody == (Object)null || (Object)(object)_tkGripBody == (Object)null)
				{
					return false;
				}
				Vector3 physicalHandPosition = GetPhysicalHandPosition(_hand, _handBody);
				Quaternion physicalHandRotation = GetPhysicalHandRotation(_hand, _handBody);
				RecordRelativeHandVelocity(physicalHandPosition);
				bool flag = trigger > 0.9f;
				bool flag2 = pushAway > 0.9f;
				_isRotating = flag && flag2;
				if (flag2 && !flag)
				{
					ApplyDrag((pushAway > 0.8f) ? 0f : 5f);
					_gripDistance = Mathf.Clamp(_gripDistance + pushAway * 8f * Time.fixedDeltaTime, 0f, 12f);
				}
				else if (flag && !flag2)
				{
					ApplyDrag((trigger > 0.8f) ? 0f : 5f);
					_gripDistance = Mathf.Clamp(_gripDistance - trigger * 8f * Time.fixedDeltaTime, 0f, 12f);
				}
				else
				{
					ApplyDrag(5f);
				}
				Vector3 classicArmDirection = GetClassicArmDirection(_hand, physicalHandPosition, physicalHandRotation);
				Vector3 val = physicalHandPosition + classicArmDirection * _gripDistance;
				float num = Mathf.Clamp01((Time.time - _catchTime) / 1.25f);
				float num2 = Mathf.Lerp(2f, 14f, Mathf.SmoothStep(0f, 1f, num));
				Vector3 val2 = Vector3.MoveTowards(_tkGripBody.position, val, num2 * Time.fixedDeltaTime);
				_tkGripBody.MovePosition(val2);
				_tkGripBody.MoveRotation(physicalHandRotation);
				UpdateSpinMode(_isRotating);
				if (_spinMode && (Object)(object)_joint != (Object)null)
				{
					float num3 = Time.time - _spinStartTime;
					Keyframe val3 = ClassicSpinVelocityCurve[ClassicSpinVelocityCurve.length - 1];
					if (num3 < ((Keyframe)(ref val3)).time)
					{
						_spinVelocity = ClassicSpinVelocityCurve.Evaluate(num3) * GetClassicSpinMassFactor(_targetBody.mass);
						_joint.targetAngularVelocity = new Vector3(0f - _spinVelocity, 0f, 0f);
					}
				}
				ApplyGravityCompensation();
				_targetBody.WakeUp();
				return TryAutoAttach(physicalHandPosition);
			}

			private void UpdateSpinMode(bool active)
			{
				//IL_0040: 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_0086: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: 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)
				if (!((Object)(object)_joint == (Object)null) && !((Object)(object)_targetBody == (Object)null))
				{
					if (active && !_spinMode)
					{
						JointDrive angularXDrive = default(JointDrive);
						((JointDrive)(ref angularXDrive)).positionSpring = 0f;
						((JointDrive)(ref angularXDrive)).positionDamper = 1f;
						((JointDrive)(ref angularXDrive)).maximumForce = 1000f;
						_joint.angularXDrive = angularXDrive;
						((Joint)_joint).connectedAnchor = _targetBody.centerOfMass;
						_joint.targetAngularVelocity = Vector3.zero;
						_joint.angularYMotion = (ConfigurableJointMotion)0;
						_joint.angularZMotion = (ConfigurableJointMotion)0;
						_spinStartTime = Time.time;
						_spinVelocity = 0f;
						_spinMode = true;
					}
					else if (!active && _spinMode)
					{
						JointDrive angularXDrive2 = default(JointDrive);
						((JointDrive)(ref angularXDrive2)).positionSpring = 10f;
						((JointDrive)(ref angularXDrive2)).positionDamper = 1f;
						((JointDrive)(ref angularXDrive2)).maximumForce = 1000f;
						_joint.angularXDrive = angularXDrive2;
						((Joint)_joint).connectedAnchor = _connectedAnchor;
						_joint.targetAngularVelocity = Vector3.zero;
						_joint.angularYMotion = (ConfigurableJointMotion)2;
						_joint.angularZMotion = (ConfigurableJointMotion)2;
						_spinVelocity = 0f;
						_spinMode = false;
					}
				}
			}

			private static Vector3 GetClassicArmDirection(Hand hand, Vector3 handPosition, Quaternion handRotation)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Invalid comparison between Unknown and I4
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Vector3.zero;
				bool flag = false;
				try
				{
					if ((Object)(object)Player.PhysicsRig != (Object)null)
					{
						Rig physicsRig = (Rig)(object)Player.PhysicsRig;
						Transform val2 = (((Object)(object)hand != (Object)null && (int)hand.handedness == 1) ? physicsRig.m_shoulderLf : physicsRig.m_shoulderRt);
						if ((Object)(object)val2 != (Object)null)
						{
							val = val2.position;
							flag = true;
						}
					}
				}
				catch
				{
				}
				Vector3 val3 = (flag ? (handPosition - val) : (handRotation * Vector3.forward));
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					val3 = handRotation * Vector3.forward;
				}
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					val3 = Vector3.forward;
				}
				return ((Vector3)(ref val3)).normalized;
			}

			private static float GetClassicSpinMassFactor(float mass)
			{
				return Mathf.Clamp(1f / Mathf.Sqrt(Mathf.Max(0.05f, mass)), 0.15f, 3f);
			}

			private static float GetClassicMassCompensation(float mass)
			{
				return Mathf.Clamp(Mathf.Sqrt(Mathf.Max(1f, mass)), 1f, 5f);
			}

			private Vector3 RecordRelativeHandVelocity(Vector3 handPosition)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: 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_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: 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_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_0075: Unknown result type (might be due to invalid IL or missing references)
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				float num = Mathf.Max(0.001f, realtimeSinceStartup - _lastVelocitySampleTime);
				Vector3 playerBodyPosition = GetPlayerBodyPosition(handPosition);
				Vector3 val = (handPosition - _lastHandPosition) / num;
				Vector3 val2 = (playerBodyPosition - _lastBodyPosition) / num;
				_lastRelativeHandVelocity = val - val2;
				_lastHandPosition = handPosition;
				_lastBodyPosition = playerBodyPosition;
				_lastVelocitySampleTime = realtimeSinceStartup;
				return _lastRelativeHandVelocity;
			}

			private void ApplyDrag(float drag)
			{
				if (!((Object)(object)_targetBody == (Object)null))
				{
					_targetBody.drag = drag;
					_targetBody.angularDrag = ((drag <= 0f) ? 0f : 0.5f);
				}
			}

			private void ApplyGravityCompensation()
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_targetBody == (Object)null))
				{
					float num = Mathf.Min(_targetBody.mass, 35f);
					if (num > 0f)
					{
						_targetBody.AddForce(-Physics.gravity * num, (ForceMode)0);
					}
				}
			}

			private bool TryAutoAttach(Vector3 handPosition)
			{
				//IL_0045: 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)
				if (HasObjectInHand(_hand))
				{
					return true;
				}
				if ((Object)(object)_targetGrip == (Object)null || !((Behaviour)_targetGrip).isActiveAndEnabled || _targetGrip.IsInteractionDisabled)
				{
					return false;
				}
				if (Vector3.Distance(handPosition, ((Component)_targetGrip).transform.position) > 0.3f)
				{
					return false;
				}
				TryAttachGrip(_targetGrip, _hand);
				return true;
			}

			private static void TryAttachGrip(Grip grip, Hand hand)
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: 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)
				if (!((Object)(object)grip == (Object)null) && !((Object)(object)hand == (Object)null))
				{
					hand.GrabLock = false;
					InventoryHand component = ((Component)hand).gameObject.GetComponent<InventoryHand>();
					if ((Object)(object)component != (Object)null)
					{
						component.IgnoreUnlock();
					}
					hand.HoverLock();
					SimpleTransform val = SimpleTransform.Create(((Component)hand).transform);
					((HandReciever)grip).ValidateGripScore(hand, val);
					grip.OnHandHoverBegin(hand, true);
					((HandReciever)grip).ValidateGripScore(hand, val);
					hand._mHoveringReceiver = (HandReciever)(object)grip;
					grip.OnGrabConfirm(hand, false);
				}
			}

			public bool TryGetReleaseVelocity(out Rigidbody targetBody, out Vector3 releaseVelocity)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				targetBody = _targetBody;
				releaseVelocity = Vector3.zero;
				if ((Object)(object)_targetBody == (Object)null)
				{
					return false;
				}
				releaseVelocity = _lastRelativeHandVelocity * 2f;
				return ((Vector3)(ref releaseVelocity)).sqrMagnitude > 0.0001f;
			}

			public void Destroy()
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				UpdateSpinMode(active: false);
				if ((Object)(object)_targetBody != (Object)null)
				{
					_targetBody.solverIterations = _oldSolverIterations;
					_targetBody.solverVelocityIterations = _oldSolverVelocityIterations;
					_targetBody.collisionDetectionMode = _oldCollisionDetectionMode;
					_targetBody.drag = _oldDrag;
					_targetBody.angularDrag = _oldAngularDrag;
					_targetBody.maxAngularVelocity = _oldMaxAngularVelocity;
					_targetBody.WakeUp();
				}
				if ((Object)(object)_joint != (Object)null)
				{
					Object.Destroy((Object)(object)_joint);
				}
				if ((Object)(object)_tkGripObject != (Object)null)
				{
					Object.Destroy((Object)(object)_tkGripObject);
				}
			}
		}

		private static readonly Color DefaultGizmoColor = new Color(0.55f, 0.15f, 1f);

		private const float SelectionKeepAliveSeconds = 0.12f;

		private const float GripPressThreshold = 0.75f;

		private const float TriggerPullDeadzone = 0.9f;

		private const float MinPullDistance = 0.25f;

		private const float AutoAttachDistance = 0.3f;

		private const float SolverRotateMaxSpeed = 1800f;

		private const float ClassicPositionSpring = 100f;

		private const float ClassicPositionDamper = 10f;

		private const float ClassicPositionMaxForce = 1000f;

		private const float ClassicRotationSpring = 10f;

		private const float ClassicRotationDamper = 1f;

		private const float ClassicRotationMaxForce = 1000f;

		private const float ClassicDrag = 5f;

		private const float ClassicAngularDrag = 0.5f;

		private const float ClassicRepelMaxDistance = 12f;

		private const float ClassicPullAndRepelMaxSpeed = 8f;

		private const float ClassicPullAndRepelNoDragThreshold = 0.8f;

		private const float ClassicThrowMultiplier = 2f;

		private const float ClassicFollowStartSpeed = 2f;

		private const float ClassicFollowMaxSpeed = 14f;

		private const float ClassicFollowRampSeconds = 1.25f;

		private const float ClassicGravityCompensationMaxMass = 35f;

		private const float ClassicSpinReferenceMass = 1f;

		private const float ClassicSpinMinMassFactor = 0.15f;

		private const float ClassicSpinMaxMassFactor = 3f;

		private const float ClassicMassCompensationMaxMultiplier = 5f;

		private static readonly AnimationCurve ClassicSpinVelocityCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4]
		{
			new Keyframe(0f, 0f),
			new Keyframe(0.15f, 16f),
			new Keyframe(0.5f, 32f),
			new Keyframe(1f, 32f)
		});

		private const float AdvancedPositionSpring = 55f;

		private const float AdvancedPositionDamper = 13f;

		private const float AdvancedMaxAcceleration = 85f;

		private const float AdvancedTrajectoryMinSampleDistance = 0.01f;

		private const int AdvancedTrajectoryMaxSamples = 180;

		private const float AdvancedTrajectoryPlaybackStep = 90f;

		private const float AdvancedTrajectoryDistanceMultiplier = 2.5f;

		private const float AdvancedTrajectorySpeedMultiplierFactor = 0.55f;

		private const float AdvancedTrajectoryMaxSpeedMultiplier = 4f;

		private const float AdvancedLaunchVelocityMultiplier = 8f;

		private const float AdvancedLaunchMinVelocity = 6f;

		private const float AdvancedLaunchMaxVelocity = 55f;

		private const float AdvancedLaunchGestureFallbackSpeed = 24f;

		private const string SolverGizmoObjectName = "AbsoluteSolver_ForceGrabGizmo";

		private const string SolverGizmoMoveResourceName = "AbsoluteSolver.Assets.SolverGizmo_Move.png";

		private const string SolverGizmoRotatorResourceName = "AbsoluteSolver.Assets.SolverGizmo_Rotator.png";

		private const string HaltExeResourceName = "AbsoluteSolver.Assets.HALT_EXE_window_cutout_transparent_clean.png";

		private const float SolverGizmoSize = 0.5f;

		private const float ObjectGizmoPerpendicularAngle = 180f;

		private const float ObjectGizmoRandomDeviation = 15f;

		private const float GizmoLightRange = 1f;

		private const float GizmoLightIntensity = 0.67f;

		private const float HandGizmoLightRange = 0.5f;

		private const float HandGizmoLightIntensity = 0.02f;

		private const float GizmoSpriteSwitchPhaseDuration = 0.25f;

		private const float GizmoSpriteSwitchSpinDegrees = 520f;

		private const float ObjectGizmoMaxSize = 2.67f;

		private const float ObjectGizmoIntroDistance = 0.25f;

		private const float ObjectGizmoIntroDuration = 0.67f;

		private const float ObjectGizmoIntroSpinDegrees = 720f;

		private const float HandGizmoDistance = 0.1f;

		private const float HandGizmoAnimDuration = 1f;

		private const float HandGizmoSpinDegreesPerSecond = 1800f;

		private const float HandGizmoSizeMultiplier = 1.05f;

		private const float HandGizmoMinSize = 0.08f;

		private const float HandGizmoMaxSize = 0.22f;

		private const float HandGizmoFallbackSize = 0.14f;

		private const float HaltExeDisplaySeconds = 1.4f;

		private const float HaltExeChestForwardDistance = 0.867f;

		private const float HaltExeChestVerticalOffset = 0.12f;

		private const float HaltExeWorldWidth = 1.0125f;

		private const float HaltExeAnimSeconds = 0.167f;

		private const float DefenseCounterDelaySeconds = 2.567f;

		private const float DefenseCounterImpulse = 670f;

		private const float DefenseCounterUpImpulse = 670f;

		private const float DefenseCounterGizmoSeconds = 6.67f;

		private GameObject _leftSolverGizmoObject;

		private SpriteRenderer _leftSolverGizmoRenderer;

		private Grip _leftSolverGizmoGrip;

		private float _leftSolverGizmoSize = 0.5f;

		private float _leftSolverGizmoAngleOffset;

		private ObjectGizmoIntro _leftSolverGizmoIntro;

		private GameObject _rightSolverGizmoObject;

		private SpriteRenderer _rightSolverGizmoRenderer;

		private Grip _rightSolverGizmoGrip;

		private float _rightSolverGizmoSize = 0.5f;

		private float _rightSolverGizmoAngleOffset;

		private ObjectGizmoIntro _rightSolverGizmoIntro;

		private HandGizmo _leftHandGizmo;

		private HandGizmo _rightHandGizmo;

		private GameObject _selectedRoot;

		private Grip _selectedGrip;

		private Hand _selectedHand;

		private float _selectedUntil;

		private Grip _leftAdvancedCandidateGrip;

		private Hand _leftAdvancedCandidateHand;

		private float _leftAdvancedCandidateUntil;

		private Grip _rightAdvancedCandidateGrip;

		private Hand _rightAdvancedCandidateHand;

		private float _rightAdvancedCandidateUntil;

		private Grip _leftAdvancedSelectedGrip;

		private Grip _rightAdvancedSelectedGrip;

		private Hand _leftAdvancedSelectedHand;

		private Hand _rightAdvancedSelectedHand;

		private AdvancedForceDriver _leftAdvancedDriver;

		private AdvancedForceDriver _rightAdvancedDriver;

		private AdvancedTrajectoryRecorder _leftAdvancedTrajectory;

		private AdvancedTrajectoryRecorder _rightAdvancedTrajectory;

		private GameObject _haltExeObject;

		private SpriteRenderer _haltExeRenderer;

		private float _haltExeVisibleUntil;

		private float _haltExeIntroStartTime;

		private float _haltExeOutroStartTime;

		private bool _haltExeIsClosing;

		private readonly List<PendingDefenseCounter> _pendingDefenseCounters = new List<PendingDefenseCounter>();

		private readonly List<DefenseCounterGizmo> _defenseCounterGizmos = new List<DefenseCounterGizmo>();

		private Color _gizmoColor = DefaultGizmoColor;

		private SolverMode _solverMode = SolverMode.Classic;

		private bool _defenseShieldEnabled = true;

		private bool _modEnabled = true;

		private bool _allowGriplessObjectGrab = true;

		private MelonPreferences_Category _preferences;

		private MelonPreferences_Entry<string> _gizmoColorPreference;

		private MelonPreferences_Entry<string> _solverModePreference;

		private MelonPreferences_Entry<bool> _defenseShieldPreference;

		private MelonPreferences_Entry<bool> _modEnabledPreference;

		private MelonPreferences_Entry<bool> _allowGriplessObjectGrabPreference;

		private ClassicTelekinesisHandle _leftClassicHandle;

		private ClassicTelekinesisHandle _rightClassicHandle;

		private readonly Dictionary<SpriteRenderer, GizmoSpriteTransition> _gizmoSpriteTransitions = new Dictionary<SpriteRenderer, GizmoSpriteTransition>();

		private static readonly Dictionary<int, GameObject> PendingForcePullGripScans = new Dictionary<int, GameObject>();

		private readonly HashSet<ForcePullGrip> _autoCreatedForcePullGrips = new HashSet<ForcePullGrip>();

		private bool _leftGripWasPressed;

		private bool _rightGripWasPressed;

		private bool _runtimeSuspended;

		internal static Core Instance { get; private set; }

		internal static Texture2D SolverGizmoMoveTexture { get; private set; }

		internal static Sprite SolverGizmoMoveSprite { get; private set; }

		internal static Texture2D SolverGizmoRotatorTexture { get; private set; }

		internal static Sprite SolverGizmoRotatorSprite { get; private set; }

		internal static Texture2D HaltExeTexture { get; private set; }

		internal static Sprite HaltExeSprite { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			((MelonBase)this).HarmonyInstance.PatchAll(typeof(Core).Assembly);
			SolverGizmoMoveTexture = LoadEmbeddedTexture("AbsoluteSolver.Assets.SolverGizmo_Move.png", "SolverGizmo_Move");
			SolverGizmoMoveSprite = CreateSprite(SolverGizmoMoveTexture, "SolverGizmo_Move_Sprite");
			SolverGizmoRotatorTexture = LoadEmbeddedTexture("AbsoluteSolver.Assets.SolverGizmo_Rotator.png", "SolverGizmo_Rotator");
			SolverGizmoRotatorSprite = CreateSprite(SolverGizmoRotatorTexture, "SolverGizmo_Rotator_Sprite");
			HaltExeTexture = LoadEmbeddedTexture("AbsoluteSolver.Assets.HALT_EXE_window_cutout_transparent_clean.png", "HALT_EXE");
			HaltExeSprite = CreateSprite(HaltExeTexture, "HALT_EXE_Sprite");
			SetupPreferences();
			SetupBoneMenu();
			((MelonBase)this).LoggerInstance.Msg("Initialized.");
		}

		public override void OnUpdate()
		{
			if (EnsureRuntimeAvailable())
			{
				if (_solverMode == SolverMode.Classic && (Object)(object)_selectedRoot != (Object)null && Time.realtimeSinceStartup > _selectedUntil)
				{
					ClearSelection();
				}
				ProcessPendingForcePullGripScans();
				UpdateGripInput();
				UpdateAdvancedDrivers();
				UpdateHaltExeDisplay();
				UpdateDefenseCounters();
				UpdateSolverGizmos();
			}
		}

		public override void OnFixedUpdate()
		{
			if (EnsureRuntimeAvailable())
			{
				if (_leftClassicHandle != null && _leftClassicHandle.Update(GetTrigger(Player.LeftController), GetPushAway(Player.LeftController)))
				{
					DestroyClassicHandle(ref _leftClassicHandle);
				}
				if (_rightClassicHandle != null && _rightClassicHandle.Update(GetTrigger(Player.RightController), GetPushAway(Player.RightController)))
				{
					DestroyClassicHandle(ref _rightClassicHandle);
				}
			}
		}

		public override void OnDeinitializeMelon()
		{
			DestroyClassicHandle(ref _leftClassicHandle);
			DestroyClassicHandle(ref _rightClassicHandle);
			DestroyHandGizmo(ref _leftHandGizmo);
			DestroyHandGizmo(ref _rightHandGizmo);
			DestroyHaltExeDisplay();
			ClearDefenseCounters();
			_leftAdvancedDriver?.Destroy();
			_rightAdvancedDriver?.Destroy();
			_leftAdvancedDriver = null;
			_rightAdvancedDriver = null;
			ClearAdvancedSelection((Handedness)1);
			ClearAdvancedSelection((Handedness)2);
			ClearSelection();
			if (Instance == this)
			{
				Instance = null;
			}
		}

		private Texture2D LoadEmbeddedTexture(string resourceName, string textureName)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			using Stream stream = ((MelonBase)this).MelonAssembly.Assembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				((MelonBase)this).LoggerInstance.Warning("Embedded texture not found: " + resourceName);
				return null;
			}
			byte[] array = new byte[stream.Length];
			int num = stream.Read(array, 0, array.Length);
			if (num != array.Length)
			{
				((MelonBase)this).LoggerInstance.Warning($"Embedded texture read was short: {resourceName} ({num}/{array.Length})");
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = textureName,
				hideFlags = (HideFlags)32
			};
			if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array)))
			{
				((MelonBase)this).LoggerInstance.Warning("Failed to load embedded texture: " + resourceName);
				Object.Destroy((Object)(object)val);
				return null;
			}
			val.Apply(false, false);
			return val;
		}

		private Sprite CreateSprite(Texture2D texture, string spriteName)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)texture == (Object)null)
			{
				return null;
			}
			Sprite val = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), Vector2.one * 0.5f, (float)((Texture)texture).width);
			((Object)val).name = spriteName;
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}

		private void SetupPreferences()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			_preferences = MelonPreferences.CreateCategory("AbsoluteSolver");
			_gizmoColorPreference = _preferences.CreateEntry<string>("GizmoColor", "Purple", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_solverModePreference = _preferences.CreateEntry<string>("Mode", "Classic", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_defenseShieldPreference = _preferences.CreateEntry<bool>("DefenseShield", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_modEnabledPreference = _preferences.CreateEntry<bool>("ModEnabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_allowGriplessObjectGrabPreference = _preferences.CreateEntry<bool>("AllowGriplessObjectGrab", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_gizmoColor = GetColorByName(_gizmoColorPreference.Value);
			_solverMode = GetSolverModeByName(_solverModePreference.Value);
			_defenseShieldEnabled = _defenseShieldPreference.Value;
			_modEnabled = _modEnabledPreference.Value;
			_allowGriplessObjectGrab = _allowGriplessObjectGrabPreference.Value;
			_preferences.SaveToFile(false);
		}

		private void SetupBoneMenu()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			Color defaultGizmoColor = DefaultGizmoColor;
			Page val = Page.Root.CreatePage("Absolute Solver", defaultGizmoColor, 0, true);
			val.CreateBool("Mod Enabled", Color.white, _modEnabled, (Action<bool>)SetModEnabled);
			val.CreateBool("Allow Gripless Object Grab", Color.white, _allowGriplessObjectGrab, (Action<bool>)SetAllowGriplessObjectGrab);
			val.CreateEnum("Mode", defaultGizmoColor, (Enum)_solverMode, (Action<Enum>)delegate(Enum value)
			{
				SetSolverMode((SolverMode)(object)value);
			});
			val.CreateBool("Defense Shield", Color.cyan, _defenseShieldEnabled, (Action<bool>)SetDefenseShieldEnabled);
			val.CreateFunction("Mode Info", Color.white, (Action)SendModeInfoNotification);
			Page page = val.CreatePage("Color", defaultGizmoColor, 0, true);
			AddGizmoColorButton(page, "Red", Color.red, "Red");
			AddGizmoColorButton(page, "Orange", new Color(1f, 0.5f, 0f), "Orange");
			AddGizmoColorButton(page, "Yellow", Color.yellow, "Yellow");
			AddGizmoColorButton(page, "Green", Color.green, "Green");
			AddGizmoColorButton(page, "Cyan", Color.cyan, "Cyan");
			AddGizmoColorButton(page, "Blue", Color.blue, "Blue");
			AddGizmoColorButton(page, "Purple", defaultGizmoColor, "Purple");
			AddGizmoColorButton(page, "White", Color.white, "White");
		}

		private void SetDefenseShieldEnabled(bool enabled)
		{
			_defenseShieldEnabled = enabled;
			if (_defenseShieldPreference != null)
			{
				_defenseShieldPreference.Value = enabled;
				MelonPreferences_Category preferences = _preferences;
				if (preferences != null)
				{
					preferences.SaveToFile(false);
				}
				MelonPreferences.Save();
			}
		}

		private void SetModEnabled(bool enabled)
		{
			_modEnabled = enabled;
			if (_modEnabledPreference != null)
			{
				_modEnabledPreference.Value = enabled;
				MelonPreferences_Category preferences = _preferences;
				if (preferences != null)
				{
					preferences.SaveToFile(false);
				}
				MelonPreferences.Save();
			}
			if (!enabled)
			{
				SuspendRuntime();
			}
			else
			{
				_runtimeSuspended = false;
			}
		}

		private void SetAllowGriplessObjectGrab(bool enabled)
		{
			_allowGriplessObjectGrab = enabled;
			if (_allowGriplessObjectGrabPreference != null)
			{
				_allowGriplessObjectGrabPreference.Value = enabled;
				MelonPreferences_Category preferences = _preferences;
				if (preferences != null)
				{
					preferences.SaveToFile(false);
				}
				MelonPreferences.Save();
			}
			if (!enabled)
			{
				RemoveAutoCreatedForcePullGrips();
			}
		}

		private void RemoveAutoCreatedForcePullGrips()
		{
			foreach (ForcePullGrip autoCreatedForcePullGrip in _autoCreatedForcePullGrips)
			{
				if ((Object)(object)autoCreatedForcePullGrip != (Object)null)
				{
					Object.Destroy((Object)(object)autoCreatedForcePullGrip);
				}
			}
			_autoCreatedForcePullGrips.Clear();
		}

		private bool EnsureRuntimeAvailable()
		{
			if (!_modEnabled || IsFusionServerActive())
			{
				SuspendRuntime();
				return false;
			}
			_runtimeSuspended = false;
			return true;
		}

		private void SuspendRuntime()
		{
			if (!_runtimeSuspended)
			{
				_runtimeSuspended = true;
				DestroyClassicHandle(ref _leftClassicHandle);
				DestroyClassicHandle(ref _rightClassicHandle);
				DestroyHandGizmo(ref _leftHandGizmo);
				DestroyHandGizmo(ref _rightHandGizmo);
				DestroyHaltExeDisplay();
				ClearDefenseCounters();
				_leftAdvancedDriver?.Destroy();
				_rightAdvancedDriver?.Destroy();
				_leftAdvancedDriver = null;
				_rightAdvancedDriver = null;
				ClearAdvancedSelection((Handedness)1);
				ClearAdvancedSelection((Handedness)2);
				ClearSelection();
				ClearSolverGizmo((Handedness)1);
				ClearSolverGizmo((Handedness)2);
				PendingForcePullGripScans.Clear();
			}
		}

		private static bool IsFusionServerActive()
		{
			try
			{
				Type type = FindFusionType("LabFusion.Network.NetworkInfo");
				return type != null && ReadStaticBool(type, "HasServer");
			}
			catch
			{
				return false;
			}
		}

		private static bool IsRuntimeAvailable()
		{
			return Instance != null && Instance._modEnabled && !IsFusionServerActive();
		}

		private void AddGizmoColorButton(Page page, string name, Color color, string preferenceValue)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			page.CreateFunction(name, color, (Action)delegate
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				SetGizmoColor(color, preferenceValue);
			});
		}

		private void SetGizmoColor(Color color, string preferenceValue)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			_gizmoColor = color;
			if (_gizmoColorPreference != null)
			{
				_gizmoColorPreference.Value = preferenceValue;
				MelonPreferences_Category preferences = _preferences;
				if (preferences != null)
				{
					preferences.SaveToFile(false);
				}
				MelonPreferences.Save();
			}
			SetGizmoRendererColor(_leftSolverGizmoRenderer);
			SetGizmoRendererColor(_rightSolverGizmoRenderer);
			SetGizmoRendererColor(_leftHandGizmo?.Renderer);
			SetGizmoRendererColor(_rightHandGizmo?.Renderer);
		}

		private void SetSolverMode(SolverMode mode)
		{
			if (_solverMode == mode)
			{
				return;
			}
			_solverMode = mode;
			if (_solverModePreference != null)
			{
				_solverModePreference.Value = mode.ToString();
				MelonPreferences_Category preferences = _preferences;
				if (preferences != null)
				{
					preferences.SaveToFile(false);
				}
				MelonPreferences.Save();
			}
			ResetSolverRuntimeState();
		}

		private void ResetSolverRuntimeState()
		{
			DestroyClassicHandle(ref _leftClassicHandle);
			DestroyClassicHandle(ref _rightClassicHandle);
			ClearSelection();
			ClearAdvancedSelection((Handedness)1);
			ClearAdvancedSelection((Handedness)2);
			_leftGripWasPressed = (Object)(object)Player.LeftController != (Object)null && Player.LeftController._solvedGrip >= 0.75f;
			_rightGripWasPressed = (Object)(object)Player.RightController != (Object)null && Player.RightController._solvedGrip >= 0.75f;
		}

		private static SolverMode GetSolverModeByName(string modeName)
		{
			if (string.Equals(modeName, "BAS", StringComparison.OrdinalIgnoreCase) || string.Equals(modeName, "Traditional", StringComparison.OrdinalIgnoreCase) || string.Equals(modeName, "TEST", StringComparison.OrdinalIgnoreCase))
			{
				return SolverMode.Classic;
			}
			SolverMode result;
			return Enum.TryParse<SolverMode>(modeName, out result) ? result : SolverMode.Classic;
		}

		private void SendModeInfoNotification()
		{
			//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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (_solverMode == SolverMode.Classic)
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Classic"),
					Message = NotificationText.op_Implicit("If you have played Blade & Sorcery, this should feel familiar. Hold Grip to select an object, move your hand to move it, hold Trigger to pull it closer, hold B/Y to push it away, and hold Trigger plus B/Y to rotate it in place."),
					Type = (NotificationType)0,
					ShowTitleOnPopup = true,
					PopupLength = 8f
				});
			}
			else
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("N O N E"),
					Message = NotificationText.op_Implicit("N O N E"),
					Type = (NotificationType)0,
					ShowTitleOnPopup = true,
					PopupLength = 4f
				});
			}
		}

		private static Color GetColorByName(string colorName)
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			if (1 == 0)
			{
			}
			Color result = (Color)(colorName switch
			{
				"Red" => Color.red, 
				"Orange" => new Color(1f, 0.5f, 0f), 
				"Yellow" => Color.yellow, 
				"Green" => Color.green, 
				"Cyan" => Color.cyan, 
				"Blue" => Color.blue, 
				"Purple" => DefaultGizmoColor, 
				"White" => Color.white, 
				_ => DefaultGizmoColor, 
			});
			if (1 == 0)
			{
			}
			return result;
		}

		private static bool IsDefenseShieldActiveFor(Player_Health health)
		{
			if (!IsRuntimeAvailable() || Instance == null || !Instance._defenseShieldEnabled || (Object)(object)health == (Object)null)
			{
				return false;
			}
			try
			{
				return (Object)(object)Player.RigManager != (Object)null && (Object)(object)((Health)health)._rigManager == (Object)(object)Player.RigManager;
			}
			catch
			{
				return false;
			}
		}

		private static bool TryBlockDamageWithDefenseShield(Player_Health health)
		{
			if (!IsDefenseShieldActiveFor(health))
			{
				return false;
			}
			Instance?.ShowHaltExeDisplay();
			return true;
		}

		private void ScheduleDefenseCounter(Attack attack)
		{
			if (!_defenseShieldEnabled)
			{
				return;
			}
			GameObject attackSourceRoot = GetAttackSourceRoot(attack);
			Collider collider = attack.collider;
			if (((Object)(object)attackSourceRoot == (Object)null && (Object)(object)collider == (Object)null) || ((Object)(object)attackSourceRoot != (Object)null && IsLocalPlayerRoot(attackSourceRoot.transform)))
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			for (int i = 0; i < _pendingDefenseCounters.Count; i++)
			{
				PendingDefenseCounter pendingDefenseCounter = _pendingDefenseCounters[i];
				if (pendingDefenseCounter.Matches(attackSourceRoot, collider) && realtimeSinceStartup < pendingDefenseCounter.ExecuteAt)
				{
					return;
				}
			}
			_pendingDefenseCounters.Add(new PendingDefenseCounter(attackSourceRoot, collider, realtimeSinceStartup + 2.567f));
		}

		private static GameObject GetAttackSourceRoot(Attack attack)
		{
			try
			{
				if ((Object)(object)attack.proxy != (Object)null && (Object)(object)attack.proxy.root != (Object)null)
				{
					return attack.proxy.root.gameObject;
				}
			}
			catch
			{
			}
			try
			{
				Collider collider = attack.collider;
				if ((Object)(object)collider != (Object)null)
				{
					if ((Object)(object)collider.attachedRigidbody != (Object)null)
					{
						return ((Component)collider.attachedRigidbody).gameObject;
					}
					return ((Component)collider).gameObject;
				}
			}
			catch
			{
			}
			return null;
		}

		private static bool IsLocalPlayerRoot(Transform transform)
		{
			if ((Object)(object)transform == (Object)null || (Object)(object)Player.RigManager == (Object)null)
			{
				return false;
			}
			Transform transform2 = ((Component)Player.RigManager).transform;
			return (Object)(object)transform == (Object)(object)transform2 || transform.IsChildOf(transform2) || transform2.IsChildOf(transform);
		}

		private void UpdateDefenseCounters()
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			for (int num = _pendingDefenseCounters.Count - 1; num >= 0; num--)
			{
				PendingDefenseCounter pendingDefenseCounter = _pendingDefenseCounters[num];
				if (!(realtimeSinceStartup < pendingDefenseCounter.ExecuteAt))
				{
					_pendingDefenseCounters.RemoveAt(num);
					ExecuteDefenseCounter(pendingDefenseCounter);
				}
			}
			for (int num2 = _defenseCounterGizmos.Count - 1; num2 >= 0; num2--)
			{
				DefenseCounterGizmo defenseCounterGizmo = _defenseCounterGizmos[num2];
				if ((Object)(object)defenseCounterGizmo.Object == (Object)null || realtimeSinceStartup > defenseCounterGizmo.VisibleUntil)
				{
					if ((Object)(object)defenseCounterGizmo.Object != (Object)null)
					{
						Object.Destroy((Object)(object)defenseCounterGizmo.Object);
					}
					_defenseCounterGizmos.RemoveAt(num2);
				}
				else
				{
					UpdateDefenseCounterGizmo(defenseCounterGizmo);
				}
			}
		}

		private void ExecuteDefenseCounter(PendingDefenseCounter pending)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			//IL_00c9: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetDefenseCounterTarget(pending, out var pelvisBody, out var pelvisCollider))
			{
				Vector3 playerBodyPosition = GetPlayerBodyPosition(Vector3.zero);
				Vector3 val = pelvisBody.position - playerBodyPosition;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					Camera main = Camera.main;
					val = (((Object)(object)main != (Object)null) ? (-((Component)main).transform.forward) : Vector3.forward);
					val.y = 0f;
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					val = Vector3.forward;
				}
				Vector3 val2 = ((Vector3)(ref val)).normalized * 670f + Vector3.up * 670f;
				pelvisBody.WakeUp();
				pelvisBody.AddForce(val2, (ForceMode)1);
				CreateDefenseCounterGizmo(pelvisBody, pelvisCollider);
			}
		}

		private bool TryGetDefenseCounterTarget(PendingDefenseCounter pending, out Rigidbody pelvisBody, out Collider pelvisCollider)
		{
			pelvisBody = null;
			pelvisCollider = null;
			GameObject val = pending.SourceRoot;
			if ((Object)(object)val == (Object)null && (Object)(object)pending.SourceCollider != (Object)null)
			{
				val = (((Object)(object)pending.SourceCollider.attachedRigidbody != (Object)null) ? ((Component)pending.SourceCollider.attachedRigidbody).gameObject : ((Component)pending.SourceCollider).gameObject);
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			pelvisBody = FindNamedBody(val, "pelvis", "hip", "hips");
			if ((Object)(object)pelvisBody == (Object)null && (Object)(object)pending.SourceCollider != (Object)null)
			{
				pelvisBody = pending.SourceCollider.attachedRigidbody;
			}
			if ((Object)(object)pelvisBody == (Object)null)
			{
				return false;
			}
			pelvisCollider = FindBestPelvisCollider(pelvisBody);
			return true;
		}

		private static Rigidbody FindNamedBody(GameObject root, params string[] names)
		{
			Rigidbody val = null;
			int num = int.MaxValue;
			foreach (Rigidbody componentsInChild in root.GetComponentsInChildren<Rigidbody>(true))
			{
				if ((Object)(object)componentsInChild == (Object)null)
				{
					continue;
				}
				string text = ((Object)componentsInChild).name.ToLowerInvariant();
				int num2 = 1000;
				for (int i = 0; i < names.Length; i++)
				{
					if (text.Contains(names[i]))
					{
						num2 = i;
						break;
					}
				}
				if (num2 < num)
				{
					val = componentsInChild;
					num = num2;
				}
			}
			return (num < 1000) ? val : null;
		}

		private static Collider FindBestPelvisCollider(Rigidbody pelvisBody)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pelvisBody == (Object)null)
			{
				return null;
			}
			Collider result = null;
			float num = float.MaxValue;
			foreach (Collider componentsInChild in ((Component)pelvisBody).GetComponentsInChildren<Collider>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					string text = ((Object)componentsInChild).name.ToLowerInvariant();
					Bounds bounds = componentsInChild.bounds;
					float num2 = Vector3.SqrMagnitude(((Bounds)(ref bounds)).center - pelvisBody.position);
					if (text.Contains("pelvis"))
					{
						num2 -= 100f;
					}
					else if (text.Contains("hip"))
					{
						num2 -= 50f;
					}
					if (num2 < num)
					{
						result = componentsInChild;
						num = num2;
					}
				}
			}
			return result;
		}

		private void CreateDefenseCounterGizmo(Rigidbody pelvisBody, Collider pelvisCollider)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (!((Object)(object)pelvisBody == (Object)null) && !((Object)(object)SolverGizmoMoveSprite == (Object)null))
			{
				GameObject val = new GameObject("AbsoluteSolver_DefenseCounterGizmo");
				SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
				val2.sprite = SolverGizmoMoveSprite;
				((Renderer)val2).sortingOrder = 32766;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				SetGizmoRendererColor(val2);
				float size = CalculateDefenseCounterGizmoSize(pelvisBody, pelvisCollider);
				DefenseCounterGizmo defenseCounterGizmo = new DefenseCounterGizmo(val, val2, pelvisBody, size, Time.realtimeSinceStartup + 6.67f);
				_defenseCounterGizmos.Add(defenseCounterGizmo);
				UpdateDefenseCounterGizmo(defenseCounterGizmo);
			}
		}

		private static float CalculateDefenseCounterGizmoSize(Rigidbody pelvisBody, Collider pelvisCollider)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pelvisCollider != (Object)null)
			{
				Bounds bounds = pelvisCollider.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				return Mathf.Clamp(Mathf.Max(new float[3] { size.x, size.y, size.z }) * 1.2f, 0.5f, 2.67f);
			}
			return 0.5f;
		}

		private void UpdateDefenseCounterGizmo(DefenseCounterGizmo gizmo)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_0070: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)gizmo?.Object == (Object)null) && !((Object)(object)gizmo.TargetBody == (Object)null))
			{
				Camera main = Camera.main;
				gizmo.Object.transform.position = gizmo.TargetBody.position;
				if ((Object)(object)main != (Object)null)
				{
					Transform transform = gizmo.Object.transform;
					Vector3 val = gizmo.Object.transform.position - ((Component)main).transform.position;
					transform.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, ((Component)main).transform.up);
				}
				gizmo.Object.transform.localScale = Vector3.one * gizmo.Size;
				SetGizmoRendererColor(gizmo.Renderer);
			}
		}

		private void ClearDefenseCounters()
		{
			_pendingDefenseCounters.Clear();
			for (int i = 0; i < _defenseCounterGizmos.Count; i++)
			{
				if ((Object)(object)_defenseCounterGizmos[i].Object != (Object)null)
				{
					Object.Destroy((Object)(object)_defenseCounterGizmos[i].Object);
				}
			}
			_defenseCounterGizmos.Clear();
		}

		private void ShowHaltExeDisplay()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			_haltExeVisibleUntil = realtimeSinceStartup + 1.4f;
			_haltExeIntroStartTime = realtimeSinceStartup;
			_haltExeOutroStartTime = 0f;
			_haltExeIsClosing = false;
			if (!((Object)(object)HaltExeSprite == (Object)null))
			{
				if ((Object)(object)_haltExeObject == (Object)null)
				{
					_haltExeObject = new GameObject("AbsoluteSolver_HALT_EXE_Display");
					_haltExeRenderer = _haltExeObject.AddComponent<SpriteRenderer>();
					_haltExeRenderer.sprite = HaltExeSprite;
					((Renderer)_haltExeRenderer).sortingOrder = 32767;
					((Renderer)_haltExeRenderer).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)_haltExeRenderer).receiveShadows = false;
				}
				_haltExeObject.SetActive(true);
				UpdateHaltExeDisplay(forceVisible: true);
			}
		}

		private void UpdateHaltExeDisplay(bool forceVisible = false)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_0205: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_haltExeObject == (Object)null)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!forceVisible && realtimeSinceStartup > _haltExeVisibleUntil && !_haltExeIsClosing)
			{
				_haltExeIsClosing = true;
				_haltExeOutroStartTime = realtimeSinceStartup;
			}
			float num;
			if (_haltExeIsClosing)
			{
				num = 1f - Mathf.Clamp01((realtimeSinceStartup - _haltExeOutroStartTime) / 0.167f);
				if (num <= 0f)
				{
					_haltExeObject.SetActive(false);
					return;
				}
			}
			else
			{
				num = Mathf.Clamp01((realtimeSinceStartup - _haltExeIntroStartTime) / 0.167f);
			}
			num = Mathf.SmoothStep(0f, 1f, num);
			Camera main = Camera.main;
			Vector3 playerBodyPosition = GetPlayerBodyPosition(((Object)(object)main != (Object)null) ? ((Component)main).transform.position : Vector3.zero);
			Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : Vector3.forward);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.up : Vector3.up);
			Vector3 position = playerBodyPosition + ((Vector3)(ref val)).normalized * 0.867f + Vector3.up * 0.12f;
			_haltExeObject.transform.position = position;
			if ((Object)(object)main != (Object)null)
			{
				Transform transform = _haltExeObject.transform;
				Vector3 val3 = _haltExeObject.transform.position - ((Component)main).transform.position;
				transform.rotation = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, val2);
			}
			_haltExeObject.transform.localScale = Vector3.one * (1.0125f * num);
			if ((Object)(object)_haltExeRenderer != (Object)null)
			{
				_haltExeRenderer.color = Color.white;
			}
		}

		private void DestroyHaltExeDisplay()
		{
			if ((Object)(object)_haltExeObject != (Object)null)
			{
				Object.Destroy((Object)(object)_haltExeObject);
			}
			_haltExeObject = null;
			_haltExeRenderer = null;
			_haltExeVisibleUntil = 0f;
			_haltExeIntroStartTime = 0f;
			_haltExeOutroStartTime = 0f;
			_haltExeIsClosing = false;
		}

		internal void SelectGrip(Grip grip, Hand hand)
		{
			if (_solverMode == SolverMode.Advanced)
			{
				CacheAdvancedCandidate(grip, hand);
			}
			else
			{
				if (_solverMode != SolverMode.Classic || (Object)(object)grip == (Object)null || HasObjectInHand(hand))
				{
					return;
				}
				EnsureForcePullGrip(grip);
				GameObject highlightRoot = GetHighlightRoot(grip);
				if (!((Object)(object)highlightRoot == (Object)null))
				{
					_selectedGrip = grip;
					_selectedHand = hand;
					_selectedUntil = Time.realtimeSinceStartup + 0.12f;
					if (!((Object)(object)_selectedRoot == (Object)(object)highlightRoot))
					{
						ClearSelection();
						_selectedRoot = highlightRoot;
					}
				}
			}
		}

		private void UpdateGripInput()
		{
			bool flag = (Object)(object)Player.LeftController != (Object)null && Player.LeftController._solvedGrip >= 0.75f;
			bool flag2 = (Object)(object)Player.RightController != (Object)null && Player.RightController._solvedGrip >= 0.75f;
			try
			{
				if (_solverMode == SolverMode.Advanced)
				{
					UpdateAdvancedGripInput(flag, flag2);
				}
				else if (_solverMode == SolverMode.Classic)
				{
					if (flag && !_leftGripWasPressed)
					{
						TryStartClassicForceGrab((Handedness)1);
					}
					if (flag2 && !_rightGripWasPressed)
					{
						TryStartClassicForceGrab((Handedness)2);
					}
					if (!flag && _leftGripWasPressed)
					{
						StopClassicForceGrab((Handedness)1);
					}
					if (!flag2 && _rightGripWasPressed)
					{
						StopClassicForceGrab((Handedness)2);
					}
				}
			}
			finally
			{
				_leftGripWasPressed = flag;
				_rightGripWasPressed = flag2;
			}
		}

		private void UpdateAdvancedGripInput(bool leftPressed, bool rightPressed)
		{
			//IL_0049: 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)
			float trigger = GetTrigger(Player.LeftController);
			float trigger2 = GetTrigger(Player.RightController);
			if ((Object)(object)_leftAdvancedSelectedGrip != (Object)null && leftPressed && trigger > 0.9f)
			{
				_leftAdvancedTrajectory?.Record(GetHandPosition(_leftAdvancedSelectedHand), force: true);
				ClearAdvancedSelection((Handedness)1, applyHandVelocity: true, _leftAdvancedTrajectory);
			}
			else if ((Object)(object)_leftAdvancedSelectedGrip != (Object)null)
			{
				UpdateAdvancedTrajectoryInput((Handedness)1, leftPressed, _leftGripWasPressed);
			}
			else if (leftPressed && !_leftGripWasPressed)
			{
				TryAdvancedSelect((Handedness)1);
			}
			if ((Object)(object)_rightAdvancedSelectedGrip != (Object)null && rightPressed && trigger2 > 0.9f)
			{
				_rightAdvancedTrajectory?.Record(GetHandPosition(_rightAdvancedSelectedHand), force: true);
				ClearAdvancedSelection((Handedness)2, applyHandVelocity: true, _rightAdvancedTrajectory);
			}
			else if ((Object)(object)_rightAdvancedSelectedGrip != (Object)null)
			{
				UpdateAdvancedTrajectoryInput((Handedness)2, rightPressed, _rightGripWasPressed);
			}
			else if (rightPressed && !_rightGripWasPressed)
			{
				TryAdvancedSelect((Handedness)2);
			}
		}

		private void UpdateAdvancedTrajectoryInput(Handedness handedness, bool gripPressed, bool gripWasPressed)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0028: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			Hand val = (((int)handedness == 1) ? _leftAdvancedSelectedHand : _rightAdvancedSelectedHand);
			AdvancedForceDriver advancedForceDriver = (((int)handedness == 1) ? _leftAdvancedDriver : _rightAdvancedDriver);
			ref AdvancedTrajectoryRecorder advancedTrajectoryRecorder = ref GetAdvancedTrajectoryRecorder(handedness);
			if ((Object)(object)val == (Object)null || advancedForceDriver == null)
			{
				return;
			}
			if (gripPressed && !gripWasPressed)
			{
				advancedTrajectoryRecorder = new AdvancedTrajectoryRecorder(GetHandPosition(val), advancedForceDriver.TargetPosition);
			}
			else if (gripPressed)
			{
				advancedTrajectoryRecorder?.Record(GetHandPosition(val));
			}
			else if (!gripPressed && gripWasPressed)
			{
				advancedTrajectoryRecorder?.Record(GetHandPosition(val), force: true);
				if (advancedTrajectoryRecorder != null && advancedTrajectoryRecorder.TryCreateTrajectory(out var offsets, out var baseTarget))
				{
					advancedForceDriver.PlayTrajectory(baseTarget, offsets);
				}
				advancedTrajectoryRecorder = null;
			}
		}

		private ref AdvancedTrajectoryRecorder GetAdvancedTrajectoryRecorder(Handedness handedness)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)handedness == 1)
			{
				return ref _leftAdvancedTrajectory;
			}
			return ref _rightAdvancedTrajectory;
		}

		private void CacheAdvancedCandidate(Grip grip, Hand hand)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			if (!((Object)(object)grip == (Object)null) && !((Object)(object)hand == (Object)null) && !HasObjectInHand(hand))
			{
				EnsureForcePullGrip(grip);
				if ((int)hand.handedness == 1)
				{
					_leftAdvancedCandidateGrip = grip;
					_leftAdvancedCandidateHand = hand;
					_leftAdvancedCandidateUntil = Time.realtimeSinceStartup + 0.12f;
				}
				else if ((int)hand.handedness == 2)
				{
					_rightAdvancedCandidateGrip = grip;
					_rightAdvancedCandidateHand = hand;
					_rightAdvancedCandidateUntil = Time.realtimeSinceStartup + 0.12f;
				}
			}
		}

		private void TryAdvancedSelect(Handedness handedness)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison