Decompiled source of Multigrasp v1.0.1

Multigrasp.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Multigrasp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+beb441afe3bfba81768632e6b8c827ea6dc0490f")]
[assembly: AssemblyProduct("Multigrasp")]
[assembly: AssemblyTitle("Multigrasp")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 Multigrasp
{
	internal sealed class BeamRenderer
	{
		private static readonly Color VanillaOrangeStart = new Color(1f, 0.1856f, 0f, 0.95f);

		private static readonly Color VanillaOrangeEnd = new Color(1f, 0.1856f, 0f, 0.65f);

		private readonly string _name;

		private GameObject _beamObject;

		private LineRenderer _beam;

		private Material _ownedMaterial;

		private float _textureOffset;

		internal BeamRenderer(string name)
		{
			_name = name;
		}

		internal void Tick(PhysGrabber primary, Transform fallbackCamera, Vector3 end)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Ensure(primary);
			if (!((Object)_beam == (Object)null))
			{
				Vector3 beamStart = GetBeamStart(primary, fallbackCamera);
				Draw(beamStart, end);
			}
		}

		private void Draw(Vector3 start, Vector3 end)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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)
			float num = Vector3.Distance(start, end);
			Vector3 val = Vector3.Lerp(start, end, 0.5f) + Vector3.down * Mathf.Min(0.45f, num * 0.06f);
			_beamObject.SetActive(true);
			((Renderer)_beam).enabled = true;
			_beam.positionCount = 16;
			for (int i = 0; i < _beam.positionCount; i++)
			{
				float num2 = ((_beam.positionCount <= 1) ? 1f : ((float)i / (float)(_beam.positionCount - 1)));
				Vector3 val2 = Vector3.Lerp(start, val, num2);
				Vector3 val3 = Vector3.Lerp(val, end, num2);
				_beam.SetPosition(i, Vector3.Lerp(val2, val3, num2));
			}
			Material val4 = _ownedMaterial ?? ((Renderer)_beam).material;
			if ((Object)val4 != (Object)null)
			{
				_textureOffset -= Time.deltaTime * 2.5f;
				val4.mainTextureOffset = new Vector2(_textureOffset, 0f);
			}
		}

		internal void Destroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if ((Object)_beamObject != (Object)null)
			{
				Object.Destroy((Object)_beamObject);
			}
			if ((Object)_ownedMaterial != (Object)null)
			{
				Object.Destroy((Object)_ownedMaterial);
			}
			_beamObject = null;
			_beam = null;
			_ownedMaterial = null;
		}

		private void Ensure(PhysGrabber primary)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if (!((Object)_beamObject != (Object)null) || !((Object)_beam != (Object)null))
			{
				Destroy();
				_beamObject = new GameObject(_name);
				Object.DontDestroyOnLoad((Object)_beamObject);
				_beamObject.SetActive(true);
				_beam = _beamObject.AddComponent<LineRenderer>();
				_beam.useWorldSpace = true;
				_beam.positionCount = 16;
				_beam.numCapVertices = 4;
				_beam.numCornerVertices = 4;
				ApplyVanillaLikeStyle(primary);
				((Renderer)_beam).enabled = false;
			}
		}

		private void ApplyVanillaLikeStyle(PhysGrabber primary)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			LineRenderer sourceLine = GetSourceLine(primary);
			if ((Object)sourceLine != (Object)null)
			{
				if ((Object)((Renderer)sourceLine).sharedMaterial != (Object)null)
				{
					SetOwnedMaterial(new Material(((Renderer)sourceLine).sharedMaterial));
				}
				if (sourceLine.startWidth > 0.001f && sourceLine.startWidth < 0.25f)
				{
					_beam.startWidth = sourceLine.startWidth;
					_beam.endWidth = ((sourceLine.endWidth > 0.001f && sourceLine.endWidth < 0.25f) ? sourceLine.endWidth : (sourceLine.startWidth * 0.55f));
				}
			}
			if ((Object)_ownedMaterial == (Object)null)
			{
				Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Legacy Shaders/Particles/Additive");
				if ((Object)val != (Object)null)
				{
					SetOwnedMaterial(new Material(val));
				}
			}
			if (_beam.startWidth <= 0.001f || _beam.startWidth > 0.25f)
			{
				_beam.startWidth = 0.035f;
			}
			if (_beam.endWidth <= 0.001f || _beam.endWidth > 0.25f)
			{
				_beam.endWidth = 0.018f;
			}
			_beam.startColor = VanillaOrangeStart;
			_beam.endColor = VanillaOrangeEnd;
			if ((Object)_ownedMaterial != (Object)null)
			{
				if (_ownedMaterial.HasProperty("_Color"))
				{
					_ownedMaterial.SetColor("_Color", VanillaOrangeStart);
				}
				if (_ownedMaterial.HasProperty("_EmissionColor"))
				{
					_ownedMaterial.SetColor("_EmissionColor", VanillaOrangeStart);
				}
				_beam.textureMode = (LineTextureMode)1;
			}
		}

		private void SetOwnedMaterial(Material material)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_002a: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			if ((Object)_ownedMaterial != (Object)null && (Object)_ownedMaterial != (Object)material)
			{
				Object.Destroy((Object)_ownedMaterial);
			}
			_ownedMaterial = material;
			if ((Object)_beam != (Object)null)
			{
				((Renderer)_beam).sharedMaterial = _ownedMaterial;
			}
		}

		private static LineRenderer GetSourceLine(PhysGrabber primary)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if ((Object)(primary?.physGrabBeam) == (Object)null)
			{
				return null;
			}
			return primary.physGrabBeam.GetComponent<LineRenderer>() ?? primary.physGrabBeam.GetComponentInChildren<LineRenderer>();
		}

		private static Vector3 GetBeamStart(PhysGrabber primary, Transform fallbackCamera)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//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_00e2: 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_004e: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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)
			Transform val = primary?.physGrabBeamComponent?.PhysGrabPointOrigin;
			if ((Object)val != (Object)null)
			{
				return val.position;
			}
			PhysGrabBeam val2 = (((Object)(primary?.physGrabBeam) != (Object)null) ? primary.physGrabBeam.GetComponent<PhysGrabBeam>() : null);
			val = val2?.PhysGrabPointOrigin ?? val2?.PhysGrabPointOriginLocal;
			if ((Object)val != (Object)null)
			{
				return val.position;
			}
			if ((Object)(primary?.physGrabPoint) != (Object)null)
			{
				return primary.physGrabPoint.position;
			}
			return ((Object)fallbackCamera != (Object)null) ? fallbackCamera.position : Vector3.zero;
		}
	}
	internal static class HudNotifier
	{
		private const float VisibleSeconds = 2f;

		private static readonly Vector2 HiddenPosition = new Vector2(24f, -36f);

		private static readonly Vector2 VisiblePosition = new Vector2(24f, 80f);

		private static GameObject _canvasObject;

		private static TextMeshProUGUI _text;

		private static float _hideAt;

		private static float _showStartedAt;

		internal static void Show(string message, Color color)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_004d: 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)
			try
			{
				EnsureOverlay();
				if ((Object)_text == (Object)null)
				{
					MultigraspPlugin.LogWarning("HUD unavailable for message: " + message);
					return;
				}
				_canvasObject.SetActive(true);
				((TMP_Text)_text).text = message;
				((Graphic)_text).color = color;
				((Behaviour)_text).enabled = true;
				((TMP_Text)_text).rectTransform.anchoredPosition = HiddenPosition;
				_showStartedAt = Time.unscaledTime;
				_hideAt = Time.unscaledTime + 2f;
			}
			catch (Exception ex)
			{
				MultigraspPlugin.LogError("HUD message failed", ex);
			}
		}

		internal static void Tick()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)_text == (Object)null) && ((Behaviour)_text).enabled)
			{
				float num = Mathf.Clamp01((Time.unscaledTime - _showStartedAt) / 0.28f);
				num = 1f - Mathf.Pow(1f - num, 3f);
				((TMP_Text)_text).rectTransform.anchoredPosition = Vector2.LerpUnclamped(HiddenPosition, VisiblePosition, num);
				if (Time.unscaledTime >= _hideAt)
				{
					((Behaviour)_text).enabled = false;
				}
			}
		}

		internal static void DestroyOwnedObjects()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if ((Object)_canvasObject != (Object)null)
			{
				Object.Destroy((Object)_canvasObject);
			}
			_canvasObject = null;
			_text = null;
		}

		private static void EnsureOverlay()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00c1: 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_00e2: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if (!((Object)_canvasObject != (Object)null) || !((Object)_text != (Object)null))
			{
				if ((Object)_canvasObject != (Object)null)
				{
					Object.Destroy((Object)_canvasObject);
				}
				_canvasObject = null;
				_text = null;
				_canvasObject = new GameObject("Multigrasp HUD");
				Object.DontDestroyOnLoad((Object)_canvasObject);
				Canvas val = _canvasObject.AddComponent<Canvas>();
				val.renderMode = (RenderMode)0;
				val.sortingOrder = 32760;
				CanvasScaler val2 = _canvasObject.AddComponent<CanvasScaler>();
				val2.uiScaleMode = (ScaleMode)1;
				val2.referenceResolution = new Vector2(1920f, 1080f);
				_canvasObject.AddComponent<GraphicRaycaster>();
				GameObject val3 = new GameObject("Multigrasp HUD Text");
				val3.transform.SetParent(_canvasObject.transform, false);
				_text = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)_text).fontSize = 28f;
				((TMP_Text)_text).alignment = (TextAlignmentOptions)513;
				((Graphic)_text).raycastTarget = false;
				((TMP_Text)_text).text = string.Empty;
				((Behaviour)_text).enabled = false;
				RectTransform rectTransform = ((TMP_Text)_text).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.zero;
				rectTransform.pivot = Vector2.zero;
				rectTransform.anchoredPosition = HiddenPosition;
				rectTransform.sizeDelta = new Vector2(700f, 80f);
			}
		}
	}
	internal sealed class MultigraspManager : MonoBehaviour
	{
		internal sealed class PendingAnchorData
		{
			internal readonly PhysGrabObject PhysGrabObject;

			internal readonly Rigidbody Body;

			internal readonly Transform TargetTransform;

			internal readonly Vector3 LocalGrabPosition;

			internal readonly Vector3 PlayerLocalBodyPosition;

			internal readonly Quaternion PlayerLocalBodyRotation;

			internal bool IsValid => (Object)PhysGrabObject != (Object)null && (Object)Body != (Object)null && (Object)TargetTransform != (Object)null && ((Behaviour)PhysGrabObject).enabled && !PhysGrabObject.dead && !Body.isKinematic && ((Component)Body).gameObject.activeInHierarchy;

			internal PendingAnchorData(PhysGrabObject physGrabObject, Rigidbody body, Transform targetTransform, Vector3 localGrabPosition, Vector3 playerLocalBodyPosition, Quaternion playerLocalBodyRotation)
			{
				//IL_001e: 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_0026: 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_0030: Unknown result type (might be due to invalid IL or missing references)
				PhysGrabObject = physGrabObject;
				Body = body;
				TargetTransform = targetTransform;
				LocalGrabPosition = localGrabPosition;
				PlayerLocalBodyPosition = playerLocalBodyPosition;
				PlayerLocalBodyRotation = playerLocalBodyRotation;
			}
		}

		private sealed class Anchor
		{
			private const float MaxVelocityChange = 10f;

			private const float MaxAngularVelocityChange = 30f;

			private const float AnchoredMaxAngularVelocity = 50f;

			internal readonly PhysGrabObject PhysGrabObject;

			internal readonly Transform TargetTransform;

			private readonly Rigidbody _body;

			private readonly Vector3 _localGrabPosition;

			private readonly Vector3 _localBodyGrabPosition;

			private Vector3 _playerLocalBodyPosition;

			private Quaternion _playerLocalBodyRotation;

			private Vector3 _worldBodyPosition;

			private Quaternion _worldBodyRotation;

			private bool _followPlayer;

			private readonly float _originalMaxAngularVelocity;

			private readonly bool _changedMaxAngularVelocity;

			private readonly bool _originalDetectCollisions;

			private bool _changedDetectCollisions;

			private readonly BeamRenderer _beam;

			private bool _loggedGrabPause;

			internal bool IsValid => (Object)PhysGrabObject != (Object)null && (Object)_body != (Object)null && (Object)TargetTransform != (Object)null && ((Behaviour)PhysGrabObject).enabled && !PhysGrabObject.dead && !_body.isKinematic && ((Component)_body).gameObject.activeInHierarchy;

			internal string TargetName => ((Object)TargetTransform != (Object)null) ? ((Object)TargetTransform).name : "<missing>";

			internal Anchor(PhysGrabObject physGrabObject, Rigidbody body, Transform targetTransform, Vector3 localGrabPosition, Vector3 playerLocalBodyPosition, Quaternion playerLocalBodyRotation, bool followPlayer, bool passthrough, string beamName)
			{
				//IL_001e: 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_002d: 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_0039: 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_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_0049: 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_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				PhysGrabObject = physGrabObject;
				_body = body;
				TargetTransform = targetTransform;
				_localGrabPosition = localGrabPosition;
				_localBodyGrabPosition = ((Component)body).transform.InverseTransformPoint(targetTransform.TransformPoint(localGrabPosition));
				_playerLocalBodyPosition = playerLocalBodyPosition;
				_playerLocalBodyRotation = playerLocalBodyRotation;
				_worldBodyPosition = body.position;
				_worldBodyRotation = body.rotation;
				_followPlayer = followPlayer;
				_originalMaxAngularVelocity = body.maxAngularVelocity;
				_originalDetectCollisions = body.detectCollisions;
				if (IsFinite(_originalMaxAngularVelocity) && body.maxAngularVelocity < 50f)
				{
					body.maxAngularVelocity = 50f;
					_changedMaxAngularVelocity = true;
				}
				_beam = new BeamRenderer(beamName);
				MaintainHeldByLocalPlayer();
				SetPassthroughMode(passthrough);
			}

			internal bool Matches(PhysGrabObject physGrabObject, Transform targetTransform)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				//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_0025: Expected O, but got Unknown
				//IL_0025: Expected O, but got Unknown
				//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_004b: Expected O, but got Unknown
				//IL_004b: Expected O, but got Unknown
				return ((Object)physGrabObject != (Object)null && (Object)PhysGrabObject == (Object)physGrabObject) || ((Object)targetTransform != (Object)null && (Object)TargetTransform == (Object)targetTransform);
			}

			internal bool SetFollowPlayer(bool followPlayer, Transform player)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0053: 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_005d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)player == (Object)null || !IsValid)
				{
					return false;
				}
				if (followPlayer)
				{
					_playerLocalBodyPosition = player.InverseTransformPoint(_body.position);
					_playerLocalBodyRotation = Quaternion.Inverse(player.rotation) * _body.rotation;
				}
				else
				{
					_worldBodyPosition = _body.position;
					_worldBodyRotation = _body.rotation;
				}
				_followPlayer = followPlayer;
				return true;
			}

			internal bool TickBeam(PhysGrabber primary, Transform fallbackCamera, Transform player)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)player == (Object)null || !IsValid)
				{
					return false;
				}
				MaintainHeldByLocalPlayer();
				_beam.Tick(primary, fallbackCamera, GetBeamEnd(player));
				return true;
			}

			internal bool SetPassthroughMode(bool passthrough)
			{
				if (!IsValid)
				{
					return false;
				}
				if (passthrough)
				{
					if (_body.detectCollisions)
					{
						_body.detectCollisions = false;
					}
					_changedDetectCollisions = true;
					return true;
				}
				if (_changedDetectCollisions)
				{
					_body.detectCollisions = _originalDetectCollisions;
					_changedDetectCollisions = false;
				}
				return true;
			}

			private Vector3 GetBeamEnd(Transform player)
			{
				//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_001e: 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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: 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_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: 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_0063: 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_0092: 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_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_00a4: 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_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				if (IsGrabbedByBlockingPlayer(blockLocalActiveGrabber: false))
				{
					return TargetTransform.TransformPoint(_localGrabPosition);
				}
				Vector3 val = (_followPlayer ? player.TransformPoint(_playerLocalBodyPosition) : _worldBodyPosition);
				Quaternion val2 = (_followPlayer ? (player.rotation * _playerLocalBodyRotation) : _worldBodyRotation);
				if (!IsFinite(val) || !IsFinite(val2))
				{
					return TargetTransform.TransformPoint(_localGrabPosition);
				}
				return val + val2 * _localBodyGrabPosition;
			}

			internal bool ApplyForce(Transform player)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				if ((Object)player == (Object)null || !IsValid)
				{
					MultigraspPlugin.LogVerbose("Removing local anchor: invalid state target=" + TargetName);
					return false;
				}
				if (IsGrabbedByBlockingPlayer(blockLocalActiveGrabber: true))
				{
					if (!_loggedGrabPause)
					{
						MultigraspPlugin.LogVerbose("Paused local anchor force while grabbed target=" + TargetName);
						_loggedGrabPause = true;
					}
					return true;
				}
				if (_loggedGrabPause)
				{
					MultigraspPlugin.LogVerbose("Resumed local anchor force target=" + TargetName);
					_loggedGrabPause = false;
				}
				MaintainHeldByLocalPlayer();
				ApplyVelocityCorrection(player);
				return true;
			}

			private void ApplyVelocityCorrection(Transform player)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: 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_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: 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_00dd: 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_008c: 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)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: 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_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				float fixedDeltaTime = Time.fixedDeltaTime;
				if (!IsFinite(fixedDeltaTime) || fixedDeltaTime <= 0f)
				{
					return;
				}
				Vector3 val = (_followPlayer ? player.TransformPoint(_playerLocalBodyPosition) : _worldBodyPosition);
				if (IsFinite(val))
				{
					Vector3 val2 = (val - _body.position) / fixedDeltaTime;
					Vector3 val3 = val2 - _body.velocity;
					if (IsFinite(val3))
					{
						val3 = Vector3.ClampMagnitude(val3, 10f);
						if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f)
						{
							_body.AddForce(val3, (ForceMode)2);
						}
					}
				}
				Quaternion val4 = (_followPlayer ? (player.rotation * _playerLocalBodyRotation) : _worldBodyRotation);
				if (!IsFinite(val4))
				{
					return;
				}
				Quaternion val5 = val4 * Quaternion.Inverse(_body.rotation);
				float num = default(float);
				Vector3 val6 = default(Vector3);
				((Quaternion)(ref val5)).ToAngleAxis(ref num, ref val6);
				if (num > 180f)
				{
					num -= 360f;
				}
				if (!IsFinite(num) || !IsFinite(val6) || !(((Vector3)(ref val6)).sqrMagnitude > 0.0001f))
				{
					return;
				}
				((Vector3)(ref val6)).Normalize();
				Vector3 val7 = val6 * (num * (MathF.PI / 180f) / fixedDeltaTime);
				Vector3 val8 = val7 - _body.angularVelocity;
				if (IsFinite(val8))
				{
					val8 = Vector3.ClampMagnitude(val8, 30f);
					if (((Vector3)(ref val8)).sqrMagnitude > 0.0001f)
					{
						_body.AddTorque(val8, (ForceMode)2);
					}
				}
			}

			internal void DestroyOwnedObjects()
			{
				RestoreDetectCollisions();
				RestoreMaxAngularVelocity();
				RestoreHeldByLocalPlayer();
				_beam.Destroy();
			}

			private void RestoreDetectCollisions()
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				if (_changedDetectCollisions && (Object)_body != (Object)null)
				{
					_body.detectCollisions = _originalDetectCollisions;
					_changedDetectCollisions = false;
				}
			}

			private void RestoreMaxAngularVelocity()
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				if (_changedMaxAngularVelocity && (Object)_body != (Object)null && IsFinite(_originalMaxAngularVelocity) && Mathf.Approximately(_body.maxAngularVelocity, 50f))
				{
					_body.maxAngularVelocity = _originalMaxAngularVelocity;
				}
			}

			private void MaintainHeldByLocalPlayer()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Expected O, but got Unknown
				if ((Object)PhysGrabObject != (Object)null)
				{
					ReflectionCache.SetField(PhysGrabObject, "heldByLocalPlayer", value: true);
				}
			}

			private void RestoreHeldByLocalPlayer()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Expected O, but got Unknown
				if (!((Object)PhysGrabObject == (Object)null) && !IsVanillaCurrentLocalGrab(PhysGrabObject))
				{
					ReflectionCache.SetField(PhysGrabObject, "heldByLocalPlayer", value: false);
				}
			}

			private bool IsGrabbedByBlockingPlayer(bool blockLocalActiveGrabber)
			{
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Expected O, but got Unknown
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Expected O, but got Unknown
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Expected O, but got Unknown
				object field = ReflectionCache.GetField<object>(PhysGrabObject, "playerGrabbing");
				if (!(field is IEnumerable enumerable) || field is string)
				{
					return false;
				}
				foreach (object item in enumerable)
				{
					Object val = (Object)((item is Object) ? item : null);
					if (val != null)
					{
						if (val == (Object)null)
						{
							continue;
						}
					}
					else if (item == null)
					{
						continue;
					}
					PhysGrabber val2 = (PhysGrabber)((item is PhysGrabber) ? item : null);
					if ((Object)val2 != (Object)null)
					{
						if (IsActiveGrabberForObject(val2, PhysGrabObject))
						{
							if (!IsLocalGrabEntry(val2))
							{
								return true;
							}
							if (blockLocalActiveGrabber)
							{
								return true;
							}
						}
					}
					else
					{
						if (!IsLocalGrabEntry(item))
						{
							return true;
						}
						if (blockLocalActiveGrabber)
						{
							return true;
						}
					}
				}
				return false;
			}

			private static bool IsActiveGrabberForObject(PhysGrabber grabber, PhysGrabObject physGrabObject)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_003d: 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_004d: Expected O, but got Unknown
				//IL_004d: Expected O, but got Unknown
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				//IL_008a: 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_009a: Expected O, but got Unknown
				//IL_009a: Expected O, but got Unknown
				if ((Object)grabber == (Object)null || !grabber.grabbed || (Object)physGrabObject == (Object)null)
				{
					return false;
				}
				PhysGrabObject field = ReflectionCache.GetField<PhysGrabObject>(grabber, "grabbedPhysGrabObject");
				if ((Object)field == (Object)physGrabObject)
				{
					return true;
				}
				Transform grabbedObjectTransform = grabber.grabbedObjectTransform;
				if ((Object)grabbedObjectTransform == (Object)null)
				{
					return false;
				}
				PhysGrabObject val = ((Component)grabbedObjectTransform).GetComponent<PhysGrabObject>() ?? ((Component)grabbedObjectTransform).GetComponentInParent<PhysGrabObject>();
				return (Object)val == (Object)physGrabObject;
			}

			private static bool IsLocalGrabEntry(object entry)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected O, but got Unknown
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected O, but got Unknown
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Expected O, but got Unknown
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Expected O, but got Unknown
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Expected O, but got Unknown
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Expected O, but got Unknown
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Expected O, but got Unknown
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Expected O, but got Unknown
				PhysGrabber val = (PhysGrabber)((entry is PhysGrabber) ? entry : null);
				if ((Object)val != (Object)null)
				{
					return IsLocalAvatar(val.playerAvatar) || IsLocalComponent((Component)val);
				}
				PlayerAvatar val2 = (PlayerAvatar)((entry is PlayerAvatar) ? entry : null);
				if ((Object)val2 != (Object)null)
				{
					return IsLocalAvatar(val2);
				}
				Component val3 = (Component)((entry is Component) ? entry : null);
				if ((Object)val3 != (Object)null)
				{
					return IsLocalComponent(val3) || IsLocalAvatar(val3.GetComponent<PlayerAvatar>() ?? val3.GetComponentInParent<PlayerAvatar>());
				}
				GameObject val4 = (GameObject)((entry is GameObject) ? entry : null);
				return (Object)val4 != (Object)null && IsLocalAvatar(val4.GetComponent<PlayerAvatar>() ?? val4.GetComponentInParent<PlayerAvatar>());
			}

			private static bool IsLocalAvatar(PlayerAvatar avatar)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				return (Object)avatar != (Object)null && IsLocalComponent((Component)avatar);
			}

			private static bool IsLocalComponent(Component component)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected O, but got Unknown
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_0029: 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_003e: Expected O, but got Unknown
				//IL_003e: Expected O, but got Unknown
				PlayerController instance = PlayerController.instance;
				return (Object)component != (Object)null && (Object)instance != (Object)null && ((Object)component.gameObject == (Object)((Component)instance).gameObject || component.transform.IsChildOf(((Component)instance).transform));
			}

			private static bool IsVanillaCurrentLocalGrab(PhysGrabObject physGrabObject)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected O, but got Unknown
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				//IL_0064: 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_0074: Expected O, but got Unknown
				//IL_0074: Expected O, but got Unknown
				PlayerController instance = PlayerController.instance;
				if ((Object)instance == (Object)null || (Object)physGrabObject == (Object)null)
				{
					return false;
				}
				GameObject field = ReflectionCache.GetField<GameObject>(instance, "physGrabObject");
				if ((Object)field == (Object)null)
				{
					return false;
				}
				PhysGrabObject val = field.GetComponent<PhysGrabObject>() ?? field.GetComponentInParent<PhysGrabObject>();
				return (Object)val == (Object)physGrabObject;
			}
		}

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

		private static readonly Color ReleaseOrangeRed = new Color(1f, 0.32f, 0f, 1f);

		private static readonly Color RejectOrange = new Color(1f, 0.55f, 0f, 1f);

		private const float HoldReleaseSeconds = 0.7f;

		private readonly List<Anchor> _anchors = new List<Anchor>();

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

		private PhysGrabber _primary;

		private PendingAnchorData _pendingAnchorData;

		private bool _fHeld;

		private bool _fConsumed;

		private float _fDownAt;

		private bool _anchorFollowPlayer = true;

		private bool _anchorPassthroughMode;

		private void CapturePendingAnchor()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			MultigraspPlugin.LogVerbose("CapturePendingAnchor attempt primary=" + ObjectName((Object)_primary));
			if (IsPrimaryHolding(_primary))
			{
				Transform val = ResolveAnchorPlayerTransform(_primary);
				PendingAnchorData pendingAnchorData;
				if ((Object)val == (Object)null)
				{
					MultigraspPlugin.LogVerbose("CapturePendingAnchor failed: player transform unavailable");
				}
				else if (TryCaptureCurrentAnchorData(val, out pendingAnchorData))
				{
					_pendingAnchorData = pendingAnchorData;
					MultigraspPlugin.LogVerbose("CapturePendingAnchor success target=" + ObjectName(pendingAnchorData.TargetTransform));
					LogAnchorDiagnostic($"capture target={ObjectName(pendingAnchorData.TargetTransform)} body={DescribeBody(pendingAnchorData.Body)} grabbedAny={IsGrabbedByAnyPlayer(pendingAnchorData.PhysGrabObject)} object={ObjectName(pendingAnchorData.TargetTransform)}");
				}
				else
				{
					MultigraspPlugin.LogVerbose("CapturePendingAnchor failed: current grabbed object could not be captured");
				}
			}
			else
			{
				MultigraspPlugin.LogVerbose("CapturePendingAnchor skipped: primary is not holding an object");
			}
		}

		private void ClearPendingAnchorData()
		{
			_pendingAnchorData = null;
		}

		private bool TryCaptureCurrentAnchorData(Transform player, out PendingAnchorData pendingAnchorData)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			pendingAnchorData = null;
			if (!TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var body))
			{
				MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData failed: current grabbed object unresolved");
				return false;
			}
			Vector3 val = _primary.localGrabPosition;
			Vector3 currentTargetPoint = GetCurrentTargetPoint(_primary, targetTransform, val);
			if (val == Vector3.zero)
			{
				val = targetTransform.InverseTransformPoint(currentTargetPoint);
			}
			Vector3 val2 = player.InverseTransformPoint(body.position);
			Quaternion val3 = Quaternion.Inverse(player.rotation) * body.rotation;
			if (!IsFinite(val) || !IsFinite(val2) || !IsFinite(val3))
			{
				MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData failed: computed anchor data not finite target=" + ObjectName(targetTransform));
				return false;
			}
			pendingAnchorData = new PendingAnchorData(physGrabObject, body, targetTransform, val, val2, val3);
			MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData success target=" + ObjectName(targetTransform) + " body=" + ObjectName((Object)body));
			return true;
		}

		private static bool TryResolveCurrentGrabbed(PhysGrabber primary, out PhysGrabObject physGrabObject, out Transform targetTransform, out Rigidbody body)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			physGrabObject = null;
			targetTransform = null;
			body = null;
			if (!IsPrimaryHolding(primary))
			{
				MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: primary not holding");
				return false;
			}
			physGrabObject = ReflectionCache.GetField<PhysGrabObject>(primary, "grabbedPhysGrabObject");
			targetTransform = primary.grabbedObjectTransform;
			if ((Object)physGrabObject == (Object)null && (Object)targetTransform != (Object)null)
			{
				physGrabObject = ((Component)targetTransform).GetComponent<PhysGrabObject>() ?? ((Component)targetTransform).GetComponentInParent<PhysGrabObject>();
			}
			body = ReflectionCache.GetField<Rigidbody>(primary, "grabbedObject");
			if ((Object)body == (Object)null)
			{
				PhysGrabObject val = physGrabObject;
				object obj = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Rigidbody>() : null);
				if (obj == null)
				{
					Transform val2 = targetTransform;
					obj = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Rigidbody>() : null);
					if (obj == null)
					{
						Transform val3 = targetTransform;
						obj = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponentInParent<Rigidbody>() : null);
					}
				}
				body = (Rigidbody)obj;
			}
			if ((Object)targetTransform == (Object)null && (Object)body != (Object)null)
			{
				targetTransform = ((Component)body).transform;
			}
			if ((Object)physGrabObject == (Object)null)
			{
				MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing PhysGrabObject");
				return false;
			}
			if ((Object)body == (Object)null)
			{
				MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing Rigidbody target=" + ObjectName(targetTransform));
				return false;
			}
			if ((Object)targetTransform == (Object)null)
			{
				MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing target transform body=" + ObjectName((Object)body));
				return false;
			}
			return true;
		}

		private static bool IsPendingAnchorDataValid(PendingAnchorData pendingAnchorData)
		{
			if (pendingAnchorData == null || !pendingAnchorData.IsValid)
			{
				MultigraspPlugin.LogVerbose("Pending anchor invalid: " + GetPendingAnchorInvalidReason(pendingAnchorData));
				return false;
			}
			if ((MultigraspPlugin.AllowEnemyAnchors == null || !MultigraspPlugin.AllowEnemyAnchors.Value) && IsEnemyObject(pendingAnchorData.PhysGrabObject, pendingAnchorData.TargetTransform, pendingAnchorData.Body))
			{
				MultigraspPlugin.LogVerbose("Refused to fix enemy/monster object: " + ((Object)pendingAnchorData.TargetTransform).name);
				return false;
			}
			return true;
		}

		private void CommitAnchor(PendingAnchorData pendingAnchorData)
		{
			//IL_0046: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			int num = FindAnchorIndex(pendingAnchorData.PhysGrabObject, pendingAnchorData.TargetTransform);
			if (num >= 0)
			{
				_anchors[num].DestroyOwnedObjects();
			}
			Anchor anchor = new Anchor(pendingAnchorData.PhysGrabObject, pendingAnchorData.Body, pendingAnchorData.TargetTransform, pendingAnchorData.LocalGrabPosition, pendingAnchorData.PlayerLocalBodyPosition, pendingAnchorData.PlayerLocalBodyRotation, _anchorFollowPlayer, _anchorPassthroughMode, $"Multigrasp Anchor Beam {_anchors.Count + 1}");
			LogAnchorDiagnostic($"commit target={ObjectName(pendingAnchorData.TargetTransform)} body={DescribeBody(pendingAnchorData.Body)} grabbedAny={IsGrabbedByAnyPlayer(pendingAnchorData.PhysGrabObject)} object={ObjectName(pendingAnchorData.TargetTransform)}");
			if (num >= 0)
			{
				_anchors[num] = anchor;
				MultigraspPlugin.LogVerbose("Updated fixed object anchor target=" + ObjectName(pendingAnchorData.TargetTransform));
			}
			else
			{
				_anchors.Add(anchor);
				MultigraspPlugin.LogVerbose("Fixed object anchor added target=" + ObjectName(pendingAnchorData.TargetTransform));
			}
			HudNotifier.Show("Object fixed", AnchorGreen);
		}

		private int FindAnchorIndex(PhysGrabObject physGrabObject, Transform targetTransform)
		{
			for (int i = 0; i < _anchors.Count; i++)
			{
				if (_anchors[i].Matches(physGrabObject, targetTransform))
				{
					return i;
				}
			}
			return -1;
		}

		private void TickBeams()
		{
			Transform player = ResolveAnchorPlayerTransform(_primary);
			Transform cameraTransform = GetCameraTransform(_primary);
			for (int num = _anchors.Count - 1; num >= 0; num--)
			{
				if (!_anchors[num].TickBeam(_primary, cameraTransform, player))
				{
					RemoveAnchorAt(num);
				}
			}
		}

		private void ApplyAnchorForces()
		{
			Transform player = ResolveAnchorPlayerTransform(_primary);
			for (int num = _anchors.Count - 1; num >= 0; num--)
			{
				if (!_anchors[num].ApplyForce(player))
				{
					RemoveAnchorAt(num);
				}
			}
		}

		private void RemoveAnchorAt(int index)
		{
			string arg = ((index >= 0 && index < _anchors.Count) ? _anchors[index].TargetName : "<bad-index>");
			MultigraspPlugin.LogVerbose($"Removing anchor at index={index} target={arg} countBefore={_anchors.Count}");
			_anchors[index].DestroyOwnedObjects();
			_anchors.RemoveAt(index);
		}

		internal static bool IsGrabbedByAnyPlayer(PhysGrabObject physGrabObject)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			object field = ReflectionCache.GetField<object>(physGrabObject, "playerGrabbing");
			if (!(field is IEnumerable enumerable) || field is string)
			{
				return false;
			}
			foreach (object item in enumerable)
			{
				Object val = (Object)((item is Object) ? item : null);
				if (val != null)
				{
					if (val != (Object)null)
					{
						return true;
					}
				}
				else if (item != null)
				{
					return true;
				}
			}
			return false;
		}

		private void Update()
		{
			try
			{
				HudNotifier.Tick();
				ResolvePrimary();
				if (!IsUsablePrimary(_primary))
				{
					ReleaseAllAnchors("primary unavailable");
					ResetFState();
					return;
				}
				if (IsLocalPlayerInvalid(_primary))
				{
					ReleaseAllAnchors("player dead/disabled");
					ResetFState();
					return;
				}
				TickFollowToggleInput();
				TickPassthroughToggleInput();
				TickReleaseCurrentFixedInput();
				TickAnchorInput();
				TickBeams();
				LogHeldFixedObjectDiagnostics();
			}
			catch (Exception ex)
			{
				MultigraspPlugin.LogError("Manager update failed", ex);
			}
		}

		private void FixedUpdate()
		{
			try
			{
				ApplyAnchorForces();
			}
			catch (Exception ex)
			{
				MultigraspPlugin.LogError("Anchor force failed", ex);
			}
		}

		internal void RegisterPrimary(PhysGrabber grabber)
		{
			if (IsUsablePrimary(grabber))
			{
				_primary = grabber;
				MultigraspPlugin.LogVerbose("Registered primary " + ((Object)grabber).name);
			}
		}

		internal void ReleaseAllAnchors(string reason)
		{
			ClearPendingAnchorData();
			if (_anchors.Count > 0)
			{
				MultigraspPlugin.LogVerbose("Released all anchors: " + reason);
			}
			for (int i = 0; i < _anchors.Count; i++)
			{
				_anchors[i].DestroyOwnedObjects();
			}
			_anchors.Clear();
		}

		internal void DestroyOwnedObjects()
		{
			ClearPendingAnchorData();
			ReleaseAllAnchors("destroy owned objects");
			HudNotifier.DestroyOwnedObjects();
		}

		private void ResolvePrimary()
		{
			if (IsUsablePrimary(_primary))
			{
				return;
			}
			if (IsUsablePrimary(PhysGrabber.instance))
			{
				_primary = PhysGrabber.instance;
				return;
			}
			PhysGrabber[] array = Object.FindObjectsOfType<PhysGrabber>();
			PhysGrabber[] array2 = array;
			foreach (PhysGrabber val in array2)
			{
				if (IsUsablePrimary(val))
				{
					_primary = val;
					MultigraspPlugin.LogVerbose("Fallback selected primary " + ((Object)val).name);
					break;
				}
			}
		}

		internal static void LogAnchorDiagnostic(string message)
		{
			MultigraspPlugin.LogVerbose("[anchor] " + message);
		}

		internal static string DescribeBody(Rigidbody body)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0020: 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)
			if ((Object)body == (Object)null)
			{
				return "body=none";
			}
			return $"bodyPos={FormatVector(body.position)} bodyVel={FormatVector(body.velocity)} bodyKinematic={body.isKinematic}";
		}

		private static string FormatVector(Vector3 value)
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			return $"({value.x:0.000},{value.y:0.000},{value.z:0.000})";
		}

		private void LogHeldFixedObjectDiagnostics()
		{
			//IL_00d3: 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_00db: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0126: 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)
			if (MultigraspPlugin.VerboseLogs == null || !MultigraspPlugin.VerboseLogs.Value || !IsPrimaryHolding(_primary) || !TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var body))
			{
				return;
			}
			int num = FindAnchorIndex(physGrabObject, targetTransform);
			if (num < 0)
			{
				return;
			}
			int instanceID = ((Object)physGrabObject).GetInstanceID();
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!_lastHeldObjectDiagnosticAt.TryGetValue(instanceID, out var value) || !(realtimeSinceStartup - value < 0.75f))
			{
				_lastHeldObjectDiagnosticAt[instanceID] = realtimeSinceStartup;
				PruneBoundedDiagnostics(_lastHeldObjectDiagnosticAt, 64, realtimeSinceStartup, 10f);
				Vector3 localGrabPosition = _primary.localGrabPosition;
				Vector3 val = targetTransform.TransformPoint(localGrabPosition);
				string text = "desired=unavailable reason=no reliable PhysGrabber.physGrabPoint";
				if ((Object)_primary.physGrabPoint != (Object)null)
				{
					Vector3 position = _primary.physGrabPoint.position;
					text = $"desiredSource=physGrabPoint desired={FormatVector(position)} error={Vector3.Distance(val, position):0.000}";
				}
				LogAnchorDiagnostic($"held-fixed-object actualGrab={FormatVector(val)} {text} body={DescribeBody(body)} grabbedAny={IsGrabbedByAnyPlayer(physGrabObject)} object={ObjectName(targetTransform)}");
			}
		}

		private static void PruneBoundedDiagnostics(Dictionary<int, float> values, int maxCount, float now, float maxAgeSeconds)
		{
			if (values.Count <= maxCount)
			{
				return;
			}
			foreach (int item in new List<int>(values.Keys))
			{
				if (now - values[item] > maxAgeSeconds)
				{
					values.Remove(item);
				}
			}
			while (values.Count > maxCount)
			{
				int key = 0;
				float num = float.MaxValue;
				foreach (KeyValuePair<int, float> value in values)
				{
					if (value.Value < num)
					{
						key = value.Key;
						num = value.Value;
					}
				}
				values.Remove(key);
			}
		}

		private static string GetPendingAnchorInvalidReason(PendingAnchorData data)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if (data == null)
			{
				return "data is null";
			}
			if ((Object)data.PhysGrabObject == (Object)null)
			{
				return "missing PhysGrabObject";
			}
			if ((Object)data.Body == (Object)null)
			{
				return "missing Rigidbody";
			}
			if ((Object)data.TargetTransform == (Object)null)
			{
				return "missing target transform";
			}
			if (!((Behaviour)data.PhysGrabObject).enabled || data.PhysGrabObject.dead)
			{
				return "PhysGrabObject disabled/dead target=" + ObjectName(data.TargetTransform);
			}
			if (data.Body.isKinematic || !((Component)data.Body).gameObject.activeInHierarchy)
			{
				return "Rigidbody kinematic/inactive target=" + ObjectName(data.TargetTransform);
			}
			return "unknown target=" + ObjectName(data.TargetTransform);
		}

		private static string ObjectName(Transform transform)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return ((Object)transform != (Object)null) ? ((Object)transform).name : "<null>";
		}

		private static string ObjectName(Object unityObject)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return (unityObject != (Object)null) ? unityObject.name : "<null>";
		}

		private static Transform ResolveAnchorPlayerTransform(PhysGrabber primary)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0063: 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_0074: Expected O, but got Unknown
			//IL_0074: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0097: Expected O, but got Unknown
			if ((Object)primary == (Object)null || (Object)primary.playerAvatar == (Object)null)
			{
				return null;
			}
			PlayerController instance = PlayerController.instance;
			if ((Object)instance != (Object)null)
			{
				PlayerAvatar playerAvatarScript = instance.playerAvatarScript;
				if ((Object)playerAvatarScript != (Object)null && ((Object)primary.playerAvatar == (Object)playerAvatarScript || (Object)((Component)primary.playerAvatar).gameObject == (Object)((Component)playerAvatarScript).gameObject))
				{
					return ((Component)instance).transform;
				}
			}
			return ((Component)primary.playerAvatar).transform;
		}

		private static bool IsUsablePrimary(PhysGrabber grabber)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			return (Object)grabber != (Object)null && grabber.isLocal && (Object)grabber.playerAvatar != (Object)null && (Object)grabber.playerAvatar.localCamera != (Object)null;
		}

		private static bool IsLocalPlayerInvalid(PhysGrabber grabber)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			if ((Object)grabber == (Object)null || !grabber.isLocal)
			{
				return true;
			}
			PlayerAvatar playerAvatar = grabber.playerAvatar;
			if ((Object)playerAvatar == (Object)null)
			{
				return true;
			}
			GameObject gameObject = ((Component)playerAvatar).gameObject;
			if ((Object)gameObject == (Object)null || !gameObject.activeInHierarchy)
			{
				return true;
			}
			return ReflectionCache.GetField<bool>(playerAvatar, "deadSet") || ReflectionCache.GetField<bool>(playerAvatar, "isDisabled");
		}

		internal static bool IsEnemyObject(PhysGrabObject physGrabObject, Transform targetTransform, Rigidbody body)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			if (HasEnemyComponent(((Object)physGrabObject != (Object)null) ? ((Component)physGrabObject).transform : null) || HasEnemyComponent(targetTransform) || HasEnemyComponent(((Object)body != (Object)null) ? ((Component)body).transform : null))
			{
				return true;
			}
			return HasEnemyName(((Object)physGrabObject != (Object)null) ? ((Object)physGrabObject).name : null) || HasEnemyName(((Object)targetTransform != (Object)null) ? ((Object)targetTransform).name : null) || HasEnemyName(((Object)targetTransform != (Object)null && (Object)targetTransform.root != (Object)null) ? ((Object)targetTransform.root).name : null) || HasEnemyName(((Object)body != (Object)null) ? ((Object)body).name : null);
		}

		private static bool HasEnemyComponent(Transform transform)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			if ((Object)transform == (Object)null)
			{
				return false;
			}
			return (Object)((Component)transform).GetComponentInParent<EnemyRigidbody>(true) != (Object)null || (Object)((Component)transform).GetComponentInChildren<EnemyRigidbody>(true) != (Object)null || (Object)((Component)transform).GetComponentInParent<Enemy>(true) != (Object)null || (Object)((Component)transform).GetComponentInChildren<Enemy>(true) != (Object)null || (Object)((Component)transform).GetComponentInParent<EnemyParent>(true) != (Object)null;
		}

		private static bool HasEnemyName(string objectName)
		{
			return objectName != null && (objectName.IndexOf("Enemy", StringComparison.OrdinalIgnoreCase) >= 0 || objectName.IndexOf("Monster", StringComparison.OrdinalIgnoreCase) >= 0);
		}

		private static bool IsPrimaryHolding(PhysGrabber primary)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			return (Object)primary != (Object)null && primary.grabbed && (Object)primary.grabbedObjectTransform != (Object)null;
		}

		private static Transform GetCameraTransform(PhysGrabber primary)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			try
			{
				object obj;
				if ((Object)(object)primary == (Object)null)
				{
					obj = null;
				}
				else
				{
					PlayerAvatar playerAvatar = primary.playerAvatar;
					if ((Object)(object)playerAvatar == (Object)null)
					{
						obj = null;
					}
					else
					{
						PlayerLocalCamera localCamera = playerAvatar.localCamera;
						obj = (((Object)(object)localCamera != (Object)null) ? localCamera.GetOverrideTransform() : null);
					}
				}
				return (Transform)obj;
			}
			catch
			{
				object obj3;
				if ((Object)(object)primary == (Object)null)
				{
					obj3 = null;
				}
				else
				{
					PlayerAvatar playerAvatar2 = primary.playerAvatar;
					if ((Object)(object)playerAvatar2 == (Object)null)
					{
						obj3 = null;
					}
					else
					{
						PlayerLocalCamera localCamera2 = playerAvatar2.localCamera;
						obj3 = (((Object)(object)localCamera2 != (Object)null) ? ((Component)localCamera2).transform : null);
					}
				}
				return (Transform)obj3;
			}
		}

		private static Vector3 GetCurrentTargetPoint(PhysGrabber primary, Transform targetTransform, Vector3 localGrabPosition)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)primary.physGrabPoint != (Object)null)
			{
				return primary.physGrabPoint.position;
			}
			return targetTransform.TransformPoint(localGrabPosition);
		}

		internal static bool IsFinite(float value)
		{
			return !float.IsNaN(value) && !float.IsInfinity(value);
		}

		internal static bool IsFinite(Vector3 value)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z);
		}

		internal static bool IsFinite(Quaternion value)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			return IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z) && IsFinite(value.w);
		}

		private void TickAnchorInput()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)102))
			{
				ResetFState();
				_fHeld = true;
				_fConsumed = false;
				_fDownAt = Time.unscaledTime;
				CapturePendingAnchor();
			}
			if (_fHeld && !_fConsumed && Input.GetKey((KeyCode)102) && Time.unscaledTime - _fDownAt >= 0.7f)
			{
				ClearPendingAnchorData();
				ReleaseAllAnchors("F held");
				HudNotifier.Show("All fixed objects released", ReleaseOrangeRed);
				_fConsumed = true;
			}
			if (!Input.GetKeyUp((KeyCode)102))
			{
				return;
			}
			if (!_fConsumed && _pendingAnchorData != null)
			{
				PendingAnchorData pendingAnchorData = _pendingAnchorData;
				ClearPendingAnchorData();
				if (IsPendingAnchorDataValid(pendingAnchorData))
				{
					CommitAnchor(pendingAnchorData);
				}
				else
				{
					HudNotifier.Show("Cannot fix object", RejectOrange);
				}
			}
			ResetFState();
		}

		private void ResetFState()
		{
			ClearPendingAnchorData();
			_fHeld = false;
			_fConsumed = false;
			_fDownAt = 0f;
		}

		private void TickFollowToggleInput()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKeyDown((KeyCode)114))
			{
				return;
			}
			Transform val = ResolveAnchorPlayerTransform(_primary);
			if ((Object)val == (Object)null)
			{
				return;
			}
			bool anchorFollowPlayer = !_anchorFollowPlayer;
			_anchorFollowPlayer = anchorFollowPlayer;
			for (int num = _anchors.Count - 1; num >= 0; num--)
			{
				if (!_anchors[num].SetFollowPlayer(_anchorFollowPlayer, val))
				{
					RemoveAnchorAt(num);
				}
			}
			HudNotifier.Show(_anchorFollowPlayer ? "Fixed objects follow player" : "Fixed objects stay in world", AnchorGreen);
			MultigraspPlugin.LogVerbose(_anchorFollowPlayer ? "Fixed object follow enabled" : "Fixed object follow disabled");
		}

		private void TickPassthroughToggleInput()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKeyDown((KeyCode)118))
			{
				return;
			}
			_anchorPassthroughMode = !_anchorPassthroughMode;
			for (int num = _anchors.Count - 1; num >= 0; num--)
			{
				if (!_anchors[num].SetPassthroughMode(_anchorPassthroughMode))
				{
					RemoveAnchorAt(num);
				}
			}
			HudNotifier.Show(_anchorPassthroughMode ? "Fixed objects ignore obstacles" : "Fixed objects collide normally", AnchorGreen);
			MultigraspPlugin.LogVerbose(_anchorPassthroughMode ? "Fixed object passthrough enabled" : "Fixed object passthrough disabled");
		}

		private void TickReleaseCurrentFixedInput()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)99) && TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var _))
			{
				int num = FindAnchorIndex(physGrabObject, targetTransform);
				if (num >= 0)
				{
					RemoveAnchorAt(num);
					HudNotifier.Show("Object released", ReleaseOrangeRed);
					MultigraspPlugin.LogVerbose("Released current fixed object anchor");
				}
			}
		}
	}
	[BepInPlugin("com.zhuanban.repo.multigrasp", "Multigrasp", "1.0.0")]
	public sealed class MultigraspPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.zhuanban.repo.multigrasp";

		public const string PluginName = "Multigrasp";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		private MultigraspManager _manager;

		internal static MultigraspPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> VerboseLogs { get; private set; }

		internal static ConfigEntry<bool> EnableScrollDistanceOverride { get; private set; }

		internal static ConfigEntry<bool> AllowEnemyAnchors { get; private set; }

		private void Awake()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			VerboseLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "VerboseLogs", false, "When true, console receives verbose logs for Multigrasp debugging.");
			EnableScrollDistanceOverride = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "EnableScrollDistanceOverride", true, "When true, objects that force grab distance every frame can still be adjusted with push/pull or mouse scroll while held locally.");
			AllowEnemyAnchors = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "AllowEnemyAnchors", false, "When true, Multigrasp allows fixing enemy/monster PhysGrabObjects locally.");
			LogVerbose($"Startup config: VerboseLogs={VerboseLogs.Value}, EnableScrollDistanceOverride={EnableScrollDistanceOverride.Value}, AllowEnemyAnchors={AllowEnemyAnchors.Value}");
			ReflectionCache.Initialize();
			_harmony = new Harmony("com.zhuanban.repo.multigrasp");
			_harmony.PatchAll();
			_manager = ((Component)this).gameObject.AddComponent<MultigraspManager>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Multigrasp loaded. Safe local-only anchors active by default.");
		}

		private void OnDestroy()
		{
			_manager?.DestroyOwnedObjects();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Instance = null;
		}

		internal static void LogInfo(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("[Multigrasp] " + message));
			}
		}

		internal static void LogVerbose(string message)
		{
			ConfigEntry<bool> verboseLogs = VerboseLogs;
			if (verboseLogs != null && verboseLogs.Value)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("[Multigrasp verbose] " + message));
				}
			}
		}

		internal static void LogWarning(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("[Multigrasp] " + message));
			}
		}

		internal static void LogError(string message, Exception ex = null)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)((ex == null) ? ("[Multigrasp] " + message) : $"[Multigrasp] {message}: {ex}"));
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabber), "OverrideGrabDistance")]
	internal static class PhysGrabberOverrideGrabDistancePatch
	{
		private sealed class OffsetState
		{
			internal Transform TargetTransform;

			internal float LastForcedDistance;

			internal float Offset;
		}

		private const float PullPushDistanceStep = 0.2f;

		private static readonly Dictionary<PhysGrabber, OffsetState> OffsetStates = new Dictionary<PhysGrabber, OffsetState>();

		private static void Prefix(PhysGrabber __instance, ref float dist)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			PruneDestroyedStates();
			ConfigEntry<bool> enableScrollDistanceOverride = MultigraspPlugin.EnableScrollDistanceOverride;
			if (enableScrollDistanceOverride == null || !enableScrollDistanceOverride.Value)
			{
				return;
			}
			if (!IsLocalGrabActive(__instance, out var targetTransform))
			{
				if ((Object)__instance != (Object)null)
				{
					OffsetStates.Remove(__instance);
				}
				return;
			}
			OffsetState state = GetState(__instance, targetTransform, dist);
			float pullPushInput = GetPullPushInput();
			if (IsFinite(pullPushInput) && Mathf.Abs(pullPushInput) > 0.0001f)
			{
				state.Offset += Mathf.Sign(pullPushInput) * 0.2f;
			}
			float num = dist + state.Offset;
			if (TryGetDistanceBounds(__instance, out var minimumDistance, out var maximumDistance))
			{
				num = Mathf.Clamp(num, minimumDistance, maximumDistance);
				state.Offset = num - dist;
			}
			if (IsFinite(num))
			{
				dist = num;
			}
		}

		private static void PruneDestroyedStates()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			foreach (PhysGrabber item in new List<PhysGrabber>(OffsetStates.Keys))
			{
				if ((Object)item == (Object)null)
				{
					OffsetStates.Remove(item);
				}
			}
		}

		private static bool IsLocalGrabActive(PhysGrabber grabber, out Transform targetTransform)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			targetTransform = null;
			if ((Object)grabber == (Object)null || !grabber.isLocal || !grabber.grabbed || (Object)grabber.grabbedObjectTransform == (Object)null)
			{
				return false;
			}
			targetTransform = grabber.grabbedObjectTransform;
			return true;
		}

		private static OffsetState GetState(PhysGrabber grabber, Transform targetTransform, float forcedDistance)
		{
			//IL_0030: 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_0040: Expected O, but got Unknown
			//IL_0040: Expected O, but got Unknown
			if (!OffsetStates.TryGetValue(grabber, out var value))
			{
				value = new OffsetState();
				OffsetStates[grabber] = value;
			}
			if ((Object)value.TargetTransform != (Object)targetTransform || !Mathf.Approximately(value.LastForcedDistance, forcedDistance))
			{
				value.TargetTransform = targetTransform;
				value.Offset = 0f;
			}
			value.LastForcedDistance = forcedDistance;
			return value;
		}

		private static float GetPullPushInput()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				return ((Object)InputManager.instance != (Object)null) ? InputManager.instance.KeyPullAndPush() : 0f;
			}
			catch
			{
				return 0f;
			}
		}

		private static bool TryGetDistanceBounds(PhysGrabber grabber, out float minimumDistance, out float maximumDistance)
		{
			minimumDistance = ReflectionCache.GetField<float>(grabber, "minDistanceFromPlayer");
			float field = ReflectionCache.GetField<float>(grabber, "grabRange");
			float field2 = ReflectionCache.GetField<float>(grabber, "maxDistanceFromPlayer");
			maximumDistance = ((field2 > 0f) ? field2 : field);
			if (field > 0f && maximumDistance > 0f)
			{
				maximumDistance = Mathf.Min(field, maximumDistance);
			}
			return IsFinite(minimumDistance) && IsFinite(maximumDistance) && maximumDistance > minimumDistance;
		}

		private static bool IsFinite(float value)
		{
			return !float.IsNaN(value) && !float.IsInfinity(value);
		}
	}
	[HarmonyPatch(typeof(PhysGrabber), "Start")]
	internal static class PhysGrabberStartPatch
	{
		private static void Postfix(PhysGrabber __instance)
		{
			MultigraspPlugin instance = MultigraspPlugin.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				((Component)instance).GetComponent<MultigraspManager>()?.RegisterPrimary(__instance);
			}
		}
	}
	internal static class ReflectionCache
	{
		private struct FieldKey : IEquatable<FieldKey>
		{
			private readonly Type _type;

			private readonly string _name;

			internal FieldKey(Type type, string name)
			{
				_type = type;
				_name = name;
			}

			public bool Equals(FieldKey other)
			{
				return _type == other._type && _name == other._name;
			}

			public override bool Equals(object obj)
			{
				return obj is FieldKey other && Equals(other);
			}

			public override int GetHashCode()
			{
				return (((_type != null) ? _type.GetHashCode() : 0) * 397) ^ ((_name != null) ? _name.GetHashCode() : 0);
			}
		}

		private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly HashSet<string> WarnedMissingMembers = new HashSet<string>();

		private static readonly Dictionary<FieldKey, FieldInfo> CachedFields = new Dictionary<FieldKey, FieldInfo>();

		internal static void Initialize()
		{
			WarnedMissingMembers.Clear();
			CachedFields.Clear();
		}

		internal static T GetField<T>(object target, string name)
		{
			FieldInfo fieldInfo = GetFieldInfo(target, name);
			if (fieldInfo == null)
			{
				return default(T);
			}
			try
			{
				return (fieldInfo.GetValue(target) is T val) ? val : default(T);
			}
			catch (Exception ex)
			{
				MultigraspPlugin.LogError("Reflection get failed for " + target.GetType().Name + "." + name, ex);
				return default(T);
			}
		}

		internal static bool SetField<T>(object target, string name, T value)
		{
			FieldInfo fieldInfo = GetFieldInfo(target, name);
			if (fieldInfo == null)
			{
				return false;
			}
			try
			{
				fieldInfo.SetValue(target, value);
				return true;
			}
			catch (Exception ex)
			{
				MultigraspPlugin.LogError("Reflection set failed for " + target.GetType().Name + "." + name, ex);
				return false;
			}
		}

		private static FieldInfo GetFieldInfo(object target, string name)
		{
			if (target == null)
			{
				return null;
			}
			Type type = target.GetType();
			FieldKey key = new FieldKey(type, name);
			if (CachedFields.TryGetValue(key, out var value))
			{
				return value;
			}
			FieldInfo field = type.GetField(name, Flags);
			CachedFields[key] = field;
			if (field == null)
			{
				WarnMissing(type.Name + "." + name);
			}
			return field;
		}

		private static void WarnMissing(string member)
		{
			if (WarnedMissingMembers.Add(member))
			{
				MultigraspPlugin.LogVerbose("Optional reflection member unavailable: " + member);
			}
		}
	}
}