Decompiled source of Rope Physics Rewrite v1.1.44

WhiteKnuckleRopeRewrite.dll

Decompiled 8 hours ago
using System;
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 UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WhiteKnuckleRopeRewrite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.44.0")]
[assembly: AssemblyInformationalVersion("1.1.44+7bf8b6fe6565386dee9f0cdcfa455bea071aa947")]
[assembly: AssemblyProduct("WhiteKnuckleRopeRewrite")]
[assembly: AssemblyTitle("WhiteKnuckleRopeRewrite")]
[assembly: AssemblyVersion("1.1.44.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 WhiteKnuckleRopeRewrite
{
	[HarmonyPatch(typeof(SteamManager), "UploadGamemodeResults")]
	internal static class Patch_LeaderboardUpload
	{
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(OfflineLeaderboard), "SubmitOfflineScore")]
	internal static class Patch_OfflineLeaderboardSubmission
	{
		private static bool Prefix()
		{
			return false;
		}
	}
	internal static class PluginInfo
	{
		internal const string Guid = "com.wk.ropephysicsrewrite";

		internal const string Name = "White Knuckle Rope Physics Rewrite";

		internal const string Version = "1.1.44";
	}
	internal static class RopeRebuild
	{
		private sealed class ReleasedCollisionState
		{
			internal Vector3[] Positions = Array.Empty<Vector3>();

			internal Vector3 AnchorPosition;

			internal Vector3 EndpointPosition;

			internal int SettledSteps;

			internal int ActiveSteps;

			internal float NextWakeCheckAt;

			internal bool Sleeping;
		}

		private sealed class RopeState
		{
			internal ENV_Rope Rope;

			internal ENT_Player Player;

			internal Rigidbody? Endpoint;

			internal bool EndpointWasKinematic;

			internal RigidbodyInterpolation EndpointInterpolation;

			internal Vector3 LastEndpointPosition;

			internal Vector3 EndpointReleaseVelocity;

			internal bool HasEndpointPosition;

			internal readonly Dictionary<int, GrabState> Grabs = new Dictionary<int, GrabState>();

			internal int GripIndex;

			internal float RopeLength;

			internal float ArmLength;

			internal float BodyLength;

			internal bool IsTaut;

			internal bool PinSlackHandsToGrip;

			internal bool TensionedFromSlack;

			internal bool DampenOnRelease;

			internal Vector3 SlackGripOffset;

			internal float SlackHandReach;

			internal Vector3 GroundGripVelocity;

			internal float LastSlackDistance;

			internal bool RequireSlackRadiusEntry;

			internal bool SlackHasEnteredRadius;

			internal float RetensionAllowedAt;

			internal Vector3 LastGripPosition;

			internal bool HasGripPosition;

			internal Vector3 GripDirection;

			internal bool HasGripDirection;

			internal Vector3 ClimbVelocity;

			internal bool TailNeedsReset;

			internal readonly List<RopeCollisionPivot> CollisionPivots = new List<RopeCollisionPivot>();

			internal bool HasCollisionPivot;

			internal Vector3 CollisionPivot;

			internal Vector3 CollisionNormal;

			internal float CollisionPathLength;

			internal int CollisionPivotNodeIndex;

			internal float CollisionRopeRadiusOffset;

			internal float CollisionBodyRadiusOffset;

			internal Vector3[] PreviousRenderPositions = Array.Empty<Vector3>();

			internal Vector3[] CurrentRenderPositions = Array.Empty<Vector3>();

			internal Vector3[] InterpolatedRenderPositions = Array.Empty<Vector3>();

			internal bool HasRenderSnapshot;
		}

		private sealed class RopeCollisionPivot
		{
			internal Vector3 Position;

			internal Vector3 Normal;

			internal Collider? Collider;

			internal int FramesWithoutContact;
		}

		private sealed class GrabState
		{
			internal CL_Handhold_Rope Handhold;

			internal Hand Hand;

			internal ENV_Rope_Node Node;

			internal int GripIndex;

			internal int SegmentIndex;

			internal float SegmentAmount;

			internal float OriginalHandDrag;

			internal Vector3 VisualAnchor;

			internal bool HasVisualAnchor;
		}

		private sealed class PlayerState
		{
			internal ENT_Player Player;

			internal readonly HashSet<int> RopeIds = new HashSet<int>();

			internal readonly List<RopeState> RopeBuffer = new List<RopeState>();

			internal readonly List<RopeState> ConstraintBuffer = new List<RopeState>();

			internal Vector3 Position;

			internal Vector3 Velocity;

			internal int PumpDirection;

			internal float PumpPower;

			internal int AttachmentWarmupSteps;

			internal Vector3 GrabMoveAxis;

			internal Vector3 GrabCorrection;

			internal bool NativeClimbThisFrame;

			internal bool SwingMode;

			internal float SwingChargeStartedAt;

			internal float WalkModeStartedAt;

			internal bool WasSolidHandhold;

			internal Vector3 SolidHandholdVelocity;

			internal bool PendingSolidHandholdJump;

			internal Vector3 PendingSolidHandholdJumpVelocity;

			internal float NextAttachedJumpAt;

			internal float NativeJumpUntil;

			internal bool SuppressJumpRelease;

			internal bool AllowJumpRelease;

			internal bool GroundWalkMode;

			internal bool WasGrounded;

			internal float LastGroundContactAt;
		}

		private sealed class ReleaseJumpState
		{
			internal float ExpiresAt;

			internal bool WaitingForButtonRelease;
		}

		private sealed class HandholdTuningState
		{
			internal CL_Handhold_Rope Handhold;

			internal int RefCount;

			internal float DragMult;

			internal float VelocityMult;

			internal float ClimbMult;

			internal float ClimbGrav;

			internal float SpeedMult;

			internal float HangVelAdjust;

			internal bool Swinging;
		}

		private sealed class CollisionRecoveryState
		{
			internal ENT_Player Player;

			internal float ExpiresAt;
		}

		private const float MinimumLength = 0.25f;

		private const float MaximumSwingAngle = 2.443461f;

		private const float PumpAngleLimit = (float)Math.PI / 2f;

		private const float AttachedJumpCooldown = 0.6f;

		private const float ImmediateGrabJumpWindow = 0.12f;

		private const float ReleaseJumpWindow = 0.35f;

		private const float GroundPoleVaultAngle = 1.3089969f;

		private const float LowAngleClimbReleaseAngle = (float)Math.PI / 4f;

		private const float MaximumClimbReleaseRopeSpeed = 1.5f;

		private const float ClimbReleaseRopeMomentumRetention = 0.25f;

		private const float MaximumEntrySpeed = 24f;

		private const float MaximumReleaseSpeed = 20f;

		private const float PlayerVelocityScale = 175f;

		private const float StandardHandholdDrag = 10f;

		private const float PumpRampUpRate = 2.5f;

		private const float PumpRampDownRate = 4f;

		private const float GripDirectionResponse = 35f;

		private const float ClimbEntryVelocityTransfer = 0.65f;

		private const float JumpBelowGrabCooldown = 0.75f;

		private const float BelowGrabHorizontalRadius = 1.25f;

		private const float BelowGrabVerticalTolerance = 0.1f;

		private const float ModeInputDeadzone = 0.15f;

		private const float SwingMomentumThreshold = 1.25f;

		private const float SwingChargeDuration = 0.35f;

		private const float SwingModeExitDelay = 0.18f;

		private const float TailVelocityDamping = 4f;

		private const float MaximumTailRelativeSpeed = 8f;

		private const float EndpointVelocityResponse = 25f;

		private const float RopeCollisionRadius = 0.12f;

		private const float RopeCollisionSkin = 0.025f;

		private const float GroundProbeDistance = 0.2f;

		private const float GroundRopeProbeHeight = 1.5f;

		private const float GroundContactTolerance = 0.03f;

		private const float MinimumRopeGroundNormal = 0.5f;

		private const float GroundGripSmoothTime = 0.12f;

		private const float GroundGripMaximumSpeed = 8f;

		private const float HandVisualAnchorResponse = 24f;

		private const float HandVisualSnapDistance = 2.5f;

		private const float SwingGripReachScale = 0.9f;

		private const int SwingGripBlendNodes = 2;

		private const int MaximumCollisionPivots = 8;

		private const float CollisionPivotMinimumSpacing = 0.15f;

		private const int CollisionPivotReleaseFrames = 3;

		private const float CollisionConstraintTransitionResponse = 12f;

		private const float CollisionPivotRebaseDistance = 0.08f;

		private const int CollisionEdgeSearchSteps = 7;

		private const float CollisionEdgeProbeLift = 0.08f;

		private const int RopeCollisionIterations = 2;

		private const int ReleasedCollisionIterations = 6;

		private const float ReleasedContactDamping = 14f;

		private const float ReleasedContactRestingSpeed = 0.3f;

		private const int ReleasedCollisionSleepSteps = 30;

		private const int ReleasedCollisionMaximumActiveSteps = 600;

		private const float ReleasedCollisionSleepMovement = 0.004f;

		private const float ReleasedCollisionWakeMovement = 0.02f;

		private const float ReleasedCollisionSleepEndpointSpeed = 0.15f;

		private const float ReleasedCollisionWakePollInterval = 0.2f;

		private const int RopeCollisionHitCapacity = 64;

		private const float SlackRetensionDelay = 0.12f;

		private const float SlackTensionTolerance = 0.05f;

		private const float SlackOutwardSpeedThreshold = 0.1f;

		private const float SlackHandReachPadding = 0.2f;

		private const float SlackHandReleasePadding = 0.25f;

		private const float RecentGroundContactWindow = 0.2f;

		private const float SlackNodeDamping = 1.5f;

		private const int SlackConstraintIterations = 12;

		private const int AttachmentWarmupSteps = 3;

		private const float PlayerCollisionRecoveryDuration = 2f;

		private const float LifecyclePruneInterval = 1f;

		private const float MaximumControllerCorrection = 3f;

		private const float MaximumControllerMoveStep = 0.35f;

		private static readonly Dictionary<int, RopeState> Ropes = new Dictionary<int, RopeState>();

		private static readonly Dictionary<int, PlayerState> Players = new Dictionary<int, PlayerState>();

		private static readonly Dictionary<int, ReleaseJumpState> ReleaseJumps = new Dictionary<int, ReleaseJumpState>();

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

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

		private static readonly Dictionary<int, HandholdTuningState> HandholdTuning = new Dictionary<int, HandholdTuningState>();

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

		private static readonly Dictionary<int, ReleasedCollisionState> ReleasedCollisionRopes = new Dictionary<int, ReleasedCollisionState>();

		private static readonly Dictionary<int, ENV_Rope> KnownRopes = new Dictionary<int, ENV_Rope>();

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

		private static readonly Dictionary<int, List<int>> KnownRopeEndpointObjectIds = new Dictionary<int, List<int>>();

		private static readonly Dictionary<int, CollisionRecoveryState> PlayerCollisionRecovery = new Dictionary<int, CollisionRecoveryState>();

		private static readonly RaycastHit[] RopeCollisionHits = (RaycastHit[])(object)new RaycastHit[64];

		private static readonly Vector3[] CollisionEdgeDirections = (Vector3[])(object)new Vector3[5];

		private static readonly FieldInfo? TargetRigidbodyField = AccessTools.Field(typeof(ENV_Rope), "targetRigidbody");

		private static readonly FieldInfo? PlayerVelocityField = AccessTools.Field(typeof(ENT_Player), "vel");

		private static readonly FieldInfo? PlayerNoclipField = AccessTools.Field(typeof(ENT_Player), "noclip");

		private static readonly FieldInfo? ForceJumpField = AccessTools.Field(typeof(ENT_Player), "forceJump");

		private static readonly FieldInfo? TimeSinceGroundedField = AccessTools.Field(typeof(ENT_Player), "timeSinceGrounded");

		private static readonly FieldInfo? ForceAirbornTimeField = AccessTools.Field(typeof(ENT_Player), "forceAirbornTime");

		private static readonly FieldInfo? CanJumpThisFrameField = AccessTools.Field(typeof(ENT_Player), "canJumpThisFrame");

		private static readonly FieldInfo? HoldDistanceField = AccessTools.Field(typeof(ENT_Player), "holdDistance");

		private static readonly FieldInfo? HandholdRopeField = AccessTools.Field(typeof(CL_Handhold_Rope), "rope");

		private static readonly FieldInfo? HandholdSwingingField = AccessTools.Field(typeof(CL_Handhold_Rope), "swinging");

		private static readonly FieldInfo? HandholdHandsField = AccessTools.Field(typeof(CL_Handhold), "hands");

		private static readonly FieldInfo? LastGrabTimeField = AccessTools.Field(typeof(ENV_Rope), "lastGrabTime");

		private static float NextLifecyclePruneAt;

		internal static void Grab(CL_Handhold_Rope handhold, ENV_Rope rope, ENV_Rope_Node node, ENT_Player player, Hand hand, Vector3 entryVelocity)
		{
			//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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			if (!RopeSettings.Enabled || (Object)(object)rope == (Object)null || node == null || (Object)(object)player == (Object)null || hand == null || rope.nodes == null || rope.nodes.Count < 2)
			{
				return;
			}
			bool flag = IsPlayerGrounded(player);
			if (flag)
			{
				entryVelocity = Vector3.zero;
			}
			int instanceID = ((Object)rope).GetInstanceID();
			RegisterRope(rope);
			ReleasedCollisionRopes.Remove(instanceID);
			WakeEndpoint(rope);
			LastGrabTimeField?.SetValue(rope, Time.time);
			if (!EnsureFiniteRopeGeometry(rope))
			{
				throw new InvalidOperationException("The grabbed rope has an invalid anchor or node layout.");
			}
			if (!Ropes.TryGetValue(instanceID, out RopeState value))
			{
				value = CreateRopeState(rope, player);
				value.TailNeedsReset = true;
				Ropes.Add(instanceID, value);
			}
			int key = GrabKey(handhold, hand);
			float num = hand.dragMult;
			if (value.Grabs.TryGetValue(key, out GrabState value2))
			{
				num = value2.OriginalHandDrag;
				if ((Object)(object)value2.Handhold != (Object)null)
				{
					RestoreHandholdTuning(value2.Handhold);
				}
				RestoreHandDrag(value2);
			}
			GrabState grabState = new GrabState
			{
				Handhold = handhold,
				Hand = hand,
				Node = node,
				GripIndex = FindGripIndex(rope, node),
				OriginalHandDrag = num
			};
			InitializeGrabAnchor(rope, grabState);
			value.Grabs[key] = grabState;
			ApplyStandardHandholdTuning(handhold, hand, flag ? num : 10f);
			ResolveGrip(value, ((Component)player).transform.position);
			InitializeGripDirection(value, flag);
			if (value.Grabs.Count == 1)
			{
				InitializeClimbMomentum(value, entryVelocity);
			}
			int instanceID2 = ((Object)player).GetInstanceID();
			PlayerCollisionRecovery.Remove(instanceID2);
			ReleaseJumps.Remove(instanceID2);
			if (!Players.TryGetValue(instanceID2, out PlayerState value3))
			{
				value3 = new PlayerState
				{
					Player = player,
					Position = ((Component)player).transform.position,
					Velocity = Vector3.ClampMagnitude(entryVelocity, 24f),
					SwingMode = false,
					SwingChargeStartedAt = float.NegativeInfinity,
					WalkModeStartedAt = float.NegativeInfinity,
					GroundWalkMode = flag,
					WasGrounded = flag,
					LastGroundContactAt = (flag ? Time.time : float.NegativeInfinity)
				};
				Players.Add(instanceID2, value3);
			}
			value3.RopeIds.Add(instanceID);
			if (NextRopeJumpAllowedAt.TryGetValue(instanceID2, out var value4))
			{
				value3.NextAttachedJumpAt = value4;
			}
			value3.NativeJumpUntil = Time.time + 0.12f;
			if (value.Grabs.Count == 1 && flag)
			{
				StabilizeGroundGrab(value.Rope);
				EnterSlack(value, player, 0f, requireRadiusEntry: false, pinHandsToGrip: true);
				value3.Velocity = Vector3.zero;
				SetPlayerVelocity(player, Vector3.zero);
			}
			value3.AttachmentWarmupSteps = (value.IsTaut ? 3 : 0);
			if (value3.RopeIds.Count == 1 && value.IsTaut)
			{
				InitializeEntryVelocity(value3, value);
				if (!value3.GroundWalkMode && player.IsSprinting() && HasSwingMomentum(player, value3))
				{
					value3.SwingMode = true;
				}
			}
			SetGroundWalkGrabDrag(value3, flag);
			rope.SetCollision(false);
			StandalonePlugin.Log.LogDebug((object)$"Fresh rope solver attached at node {value.GripIndex}.");
		}

		internal static void Release(CL_Handhold_Rope handhold, ENV_Rope rope, ENT_Player player, Hand hand, bool allowReleaseJump)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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)
			if ((Object)(object)rope == (Object)null || (Object)(object)player == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)rope).GetInstanceID();
			if (Ropes.TryGetValue(instanceID, out RopeState value))
			{
				int key = GrabKey(handhold, hand);
				if (value.Grabs.TryGetValue(key, out GrabState value2) && value.Grabs.Remove(key))
				{
					try
					{
						RestoreHandholdTuning(handhold);
					}
					catch
					{
					}
					try
					{
						RestoreHandDrag(value2);
					}
					catch
					{
					}
				}
				if (value.Grabs.Count == 0)
				{
					bool settleGroundDrop = !value.IsTaut && IsGroundDraggedRope(value);
					if (value.DampenOnRelease)
					{
						DampenClimbRelease(value);
					}
					RestoreManagedRopeState(value, restoreEndpoint: true, manageReleasedCollision: true, settleGroundDrop);
					Ropes.Remove(instanceID);
					if (Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value3))
					{
						value3.RopeIds.Remove(instanceID);
					}
				}
				else
				{
					ResolveGrip(value, ((Component)player).transform.position);
				}
			}
			if (Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value4))
			{
				SetReleaseVelocity(player, Vector3.ClampMagnitude(value4.Velocity, 20f));
				if (value4.RopeIds.Count == 0)
				{
					if (allowReleaseJump && CanStartRopeJump(player))
					{
						ReleaseJumps[((Object)player).GetInstanceID()] = new ReleaseJumpState
						{
							ExpiresAt = Time.time + 0.35f,
							WaitingForButtonRelease = InputManager.GetButton("Jump").Pressed
						};
					}
					Players.Remove(((Object)player).GetInstanceID());
				}
			}
			BeginPlayerCollisionRecovery(player);
			rope.SetCollision(false);
		}

		internal static bool IsControlled(ENV_Rope rope)
		{
			if (RopeSettings.Enabled && (Object)(object)rope != (Object)null)
			{
				return Ropes.ContainsKey(((Object)rope).GetInstanceID());
			}
			return false;
		}

		internal static bool ShouldRunNativeRopeFixedUpdate(ENV_Rope rope)
		{
			if (IsControlled(rope))
			{
				return false;
			}
			if ((Object)(object)rope == (Object)null || !ReleasedCollisionRopes.TryGetValue(((Object)rope).GetInstanceID(), out ReleasedCollisionState value) || !value.Sleeping)
			{
				return true;
			}
			if (Time.time < value.NextWakeCheckAt)
			{
				return false;
			}
			value.NextWakeCheckAt = Time.time + 0.2f;
			if (HasReleasedRopeWakeMotion(rope, value))
			{
				WakeReleasedRope(rope);
				return true;
			}
			return false;
		}

		internal static void WakeReleasedRope(ENV_Rope rope)
		{
			if (!((Object)(object)rope == (Object)null))
			{
				if (ReleasedCollisionRopes.TryGetValue(((Object)rope).GetInstanceID(), out ReleasedCollisionState value))
				{
					value.Sleeping = false;
					value.SettledSteps = 0;
					value.ActiveSteps = 0;
					value.NextWakeCheckAt = 0f;
				}
				WakeEndpoint(rope);
			}
		}

		internal static bool CanControl(ENV_Rope rope)
		{
			if ((Object)(object)rope != (Object)null)
			{
				return !DisabledRopes.Contains(((Object)rope).GetInstanceID());
			}
			return false;
		}

		internal static void RegisterRope(ENV_Rope rope)
		{
			if (!((Object)(object)rope == (Object)null))
			{
				int instanceID = ((Object)rope).GetInstanceID();
				KnownRopes[instanceID] = rope;
				RegisterRopeEndpointObjects(instanceID, rope);
			}
		}

		internal static void ForgetRope(ENV_Rope rope)
		{
			if ((Object)(object)rope == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)rope).GetInstanceID();
			if (Ropes.TryGetValue(instanceID, out RopeState value))
			{
				try
				{
					RestoreManagedRopeState(value, restoreEndpoint: true, manageReleasedCollision: false);
				}
				catch
				{
				}
			}
			RemoveRopeFromPlayers(instanceID);
			ReleasedCollisionRopes.Remove(instanceID);
			DisabledRopes.Remove(instanceID);
			KnownRopes.Remove(instanceID);
			RemoveRopeEndpointObjects(instanceID);
			Ropes.Remove(instanceID);
		}

		internal static void ResetAllState()
		{
			List<RopeState> list = new List<RopeState>(Ropes.Values);
			for (int i = 0; i < list.Count; i++)
			{
				try
				{
					RestoreManagedRopeState(list[i], restoreEndpoint: true, manageReleasedCollision: false);
				}
				catch
				{
				}
			}
			foreach (PlayerState value in Players.Values)
			{
				if ((Object)(object)value.Player != (Object)null)
				{
					try
					{
						RestorePlayerControllerCollision(value.Player);
					}
					catch
					{
					}
				}
			}
			foreach (CollisionRecoveryState value2 in PlayerCollisionRecovery.Values)
			{
				if ((Object)(object)value2.Player != (Object)null)
				{
					try
					{
						RestorePlayerControllerCollision(value2.Player);
					}
					catch
					{
					}
				}
			}
			ForceRestoreAllHandholdTuning();
			Ropes.Clear();
			Players.Clear();
			ReleaseJumps.Clear();
			BelowGrabBlockedUntil.Clear();
			NextRopeJumpAllowedAt.Clear();
			DisabledRopes.Clear();
			ReleasedCollisionRopes.Clear();
			KnownRopes.Clear();
			KnownRopeEndpointObjects.Clear();
			KnownRopeEndpointObjectIds.Clear();
			PlayerCollisionRecovery.Clear();
			NextLifecyclePruneAt = 0f;
		}

		internal static void RegisterLoadedRopes()
		{
			//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)
			ENV_Rope[] array = Resources.FindObjectsOfTypeAll<ENV_Rope>();
			foreach (ENV_Rope val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Scene scene = ((Component)val).gameObject.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						RegisterRope(val);
					}
				}
			}
		}

		internal static void MaintainPlayerSafety(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			PruneLifecycleState();
			int instanceID = ((Object)player).GetInstanceID();
			CollisionRecoveryState value;
			if (Players.ContainsKey(instanceID))
			{
				RestorePlayerControllerCollision(player);
			}
			else if (PlayerCollisionRecovery.TryGetValue(instanceID, out value))
			{
				if (Time.time > value.ExpiresAt)
				{
					PlayerCollisionRecovery.Remove(instanceID);
				}
				else
				{
					RestorePlayerControllerCollision(player);
				}
			}
		}

		private static void RestorePlayerControllerCollision(ENT_Player player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.cCon == (Object)null))
			{
				object obj = PlayerNoclipField?.GetValue(player);
				bool flag = default(bool);
				int num;
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) == 0)
				{
					player.cCon.detectCollisions = true;
					player.cCon.enableOverlapRecovery = true;
				}
			}
		}

		private static void BeginPlayerCollisionRecovery(ENT_Player player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				RestorePlayerControllerCollision(player);
				PlayerCollisionRecovery[((Object)player).GetInstanceID()] = new CollisionRecoveryState
				{
					Player = player,
					ExpiresAt = Time.time + 2f
				};
			}
		}

		private static void RestoreManagedRopeState(RopeState state, bool restoreEndpoint, bool manageReleasedCollision, bool settleGroundDrop = false)
		{
			List<GrabState> list = new List<GrabState>(state.Grabs.Values);
			for (int i = 0; i < list.Count; i++)
			{
				GrabState grabState = list[i];
				try
				{
					if ((Object)(object)grabState.Handhold != (Object)null)
					{
						RestoreHandholdTuning(grabState.Handhold);
					}
				}
				catch
				{
				}
				try
				{
					RestoreHandDrag(grabState);
				}
				catch
				{
				}
			}
			state.Grabs.Clear();
			if (!restoreEndpoint || (Object)(object)state.Rope == (Object)null)
			{
				return;
			}
			try
			{
				RestoreEndpoint(state, settleGroundDrop);
				if (manageReleasedCollision)
				{
					BeginReleasedCollisionManagement(state.Rope);
				}
			}
			catch
			{
			}
			finally
			{
				RestoreEndpointOwnership(state);
			}
		}

		private static void RestoreEndpointOwnership(RopeState state)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)state.Endpoint == (Object)null)
			{
				return;
			}
			try
			{
				state.Endpoint.interpolation = state.EndpointInterpolation;
			}
			catch
			{
			}
			try
			{
				state.Endpoint.isKinematic = state.EndpointWasKinematic;
			}
			catch
			{
			}
		}

		private static void RemoveRopeFromPlayers(int ropeId)
		{
			List<int> list = null;
			foreach (KeyValuePair<int, PlayerState> player in Players)
			{
				if (player.Value.RopeIds.Remove(ropeId) && player.Value.RopeIds.Count == 0)
				{
					if ((Object)(object)player.Value.Player != (Object)null)
					{
						BeginPlayerCollisionRecovery(player.Value.Player);
					}
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(player.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					Players.Remove(list[i]);
				}
			}
		}

		private static void RegisterRopeEndpointObjects(int ropeId, ENV_Rope rope)
		{
			RemoveRopeEndpointObjects(ropeId);
			List<int> list = new List<int>();
			RegisterRopeEndpointObject(ropeId, (Object?)(object)rope.target, list);
			object? obj = TargetRigidbodyField?.GetValue(rope);
			Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null);
			RegisterRopeEndpointObject(ropeId, (Object?)(object)val, list);
			RegisterRopeEndpointObject(ropeId, (Object?)(object)(((Object)(object)val != (Object)null) ? ((Component)val).transform : null), list);
			KnownRopeEndpointObjectIds[ropeId] = list;
		}

		private static void RegisterRopeEndpointObject(int ropeId, Object? endpointObject, List<int> objectIds)
		{
			if (!(endpointObject == (Object)null))
			{
				int instanceID = endpointObject.GetInstanceID();
				KnownRopeEndpointObjects[instanceID] = ropeId;
				if (!objectIds.Contains(instanceID))
				{
					objectIds.Add(instanceID);
				}
			}
		}

		private static void RemoveRopeEndpointObjects(int ropeId)
		{
			if (!KnownRopeEndpointObjectIds.TryGetValue(ropeId, out List<int> value))
			{
				return;
			}
			for (int i = 0; i < value.Count; i++)
			{
				int key = value[i];
				if (KnownRopeEndpointObjects.TryGetValue(key, out var value2) && value2 == ropeId)
				{
					KnownRopeEndpointObjects.Remove(key);
				}
			}
			KnownRopeEndpointObjectIds.Remove(ropeId);
		}

		private static void PruneLifecycleState()
		{
			if (Time.time < NextLifecyclePruneAt)
			{
				return;
			}
			NextLifecyclePruneAt = Time.time + 1f;
			List<int> list = null;
			foreach (KeyValuePair<int, RopeState> rope in Ropes)
			{
				RopeState value = rope.Value;
				PlayerState value2;
				bool flag = (Object)(object)value.Player != (Object)null && Players.TryGetValue(((Object)value.Player).GetInstanceID(), out value2) && value2.RopeIds.Contains(rope.Key);
				if (!((Object)(object)value.Rope != (Object)null && flag))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(rope.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					int num = list[i];
					if (Ropes.TryGetValue(num, out RopeState value3))
					{
						RestoreManagedRopeState(value3, (Object)(object)value3.Rope != (Object)null, manageReleasedCollision: false);
					}
					Ropes.Remove(num);
					RemoveRopeFromPlayers(num);
				}
			}
			List<int> list2 = null;
			foreach (KeyValuePair<int, ENV_Rope> knownRope in KnownRopes)
			{
				if (!((Object)(object)knownRope.Value != (Object)null))
				{
					if (list2 == null)
					{
						list2 = new List<int>();
					}
					list2.Add(knownRope.Key);
				}
			}
			if (list2 != null)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					int num2 = list2[j];
					KnownRopes.Remove(num2);
					ReleasedCollisionRopes.Remove(num2);
					DisabledRopes.Remove(num2);
					RemoveRopeEndpointObjects(num2);
				}
			}
			List<int> list3 = null;
			foreach (KeyValuePair<int, PlayerState> player in Players)
			{
				if (!((Object)(object)player.Value.Player != (Object)null) || player.Value.RopeIds.Count <= 0)
				{
					if ((Object)(object)player.Value.Player != (Object)null)
					{
						BeginPlayerCollisionRecovery(player.Value.Player);
					}
					if (list3 == null)
					{
						list3 = new List<int>();
					}
					list3.Add(player.Key);
				}
			}
			if (list3 != null)
			{
				for (int k = 0; k < list3.Count; k++)
				{
					Players.Remove(list3[k]);
				}
			}
			List<int> list4 = null;
			foreach (KeyValuePair<int, HandholdTuningState> item in HandholdTuning)
			{
				if (!((Object)(object)item.Value.Handhold != (Object)null))
				{
					if (list4 == null)
					{
						list4 = new List<int>();
					}
					list4.Add(item.Key);
				}
			}
			if (list4 != null)
			{
				for (int l = 0; l < list4.Count; l++)
				{
					HandholdTuning.Remove(list4[l]);
				}
			}
			PruneExpiredPlayerTimers();
		}

		private static void PruneExpiredPlayerTimers()
		{
			float time = Time.time;
			List<int> list = null;
			foreach (KeyValuePair<int, float> item in BelowGrabBlockedUntil)
			{
				if (!(item.Value > time))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(item.Key);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					BelowGrabBlockedUntil.Remove(list[i]);
				}
			}
			list = null;
			foreach (KeyValuePair<int, float> item2 in NextRopeJumpAllowedAt)
			{
				if (!(item2.Value > time))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(item2.Key);
				}
			}
			if (list != null)
			{
				for (int j = 0; j < list.Count; j++)
				{
					NextRopeJumpAllowedAt.Remove(list[j]);
				}
			}
			list = null;
			foreach (KeyValuePair<int, ReleaseJumpState> releaseJump in ReleaseJumps)
			{
				if (!(releaseJump.Value.ExpiresAt > time))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(releaseJump.Key);
				}
			}
			if (list != null)
			{
				for (int k = 0; k < list.Count; k++)
				{
					ReleaseJumps.Remove(list[k]);
				}
			}
			list = null;
			foreach (KeyValuePair<int, CollisionRecoveryState> item3 in PlayerCollisionRecovery)
			{
				if (!((Object)(object)item3.Value.Player != (Object)null) || !(item3.Value.ExpiresAt > time))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(item3.Key);
				}
			}
			if (list != null)
			{
				for (int l = 0; l < list.Count; l++)
				{
					PlayerCollisionRecovery.Remove(list[l]);
				}
			}
		}

		internal static bool IsAttached(ENT_Player player)
		{
			if (RopeSettings.Enabled && (Object)(object)player != (Object)null && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return value.RopeIds.Count > 0;
			}
			return false;
		}

		internal static bool HasTautConstraint(ENT_Player player)
		{
			if (!RopeSettings.Enabled || (Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return false;
			}
			foreach (int ropeId in value.RopeIds)
			{
				if (Ropes.TryGetValue(ropeId, out RopeState value2) && value2.IsTaut)
				{
					return true;
				}
			}
			return false;
		}

		internal static bool IsGroundWalkActive(ENT_Player player)
		{
			if ((Object)(object)player != (Object)null && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return IsRopeWalkMode(player, value);
			}
			return false;
		}

		internal static bool HasSolidHandholdOverride(ENT_Player player)
		{
			return HasSolidHandhold(player);
		}

		internal static bool HasSolidHandholdJumpContext(ENT_Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				if (!HasSolidHandhold(player))
				{
					if (Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
					{
						return value.WasSolidHandhold;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		internal static bool BeginAttachedJump(ENT_Player player)
		{
			//IL_003a: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return false;
			}
			List<RopeState> playerRopes = GetPlayerRopes(value);
			if (playerRopes.Count == 0 || !CanStartRopeJump(player))
			{
				return false;
			}
			SetReleaseVelocity(player, Vector3.ClampMagnitude(value.Velocity, 20f));
			ForceJumpField?.SetValue(player, true);
			StartRopeJumpCooldown(player, value);
			value.SuppressJumpRelease = true;
			value.GroundWalkMode = false;
			SetGroundWalkGrabDrag(value, groundWalk: false);
			bool flag = player.IsGrounded(false) || Time.time - value.LastGroundContactAt <= 0.2f;
			foreach (RopeState item in playerRopes)
			{
				bool requireRadiusEntry = flag && GetRopeAngle(item) >= 1.3089969f && !IsActivelyPullingRope(player, value, item);
				EnterSlack(item, player, 0.12f, requireRadiusEntry, pinHandsToGrip: true);
			}
			value.AttachmentWarmupSteps = 0;
			value.PumpDirection = 0;
			value.PumpPower = 0f;
			value.GrabMoveAxis = Vector3.zero;
			value.GrabCorrection = Vector3.zero;
			value.NativeClimbThisFrame = false;
			StandalonePlugin.Log.LogDebug((object)"Attached jump made the held rope slack.");
			return true;
		}

		private static bool IsActivelyPullingRope(ENT_Player player, PlayerState state, RopeState rope)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0020: 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_004e: 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_0059: 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_006f: 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_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_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)
			Vector3 val = Vector3.ProjectOnPlane(((Component)player).transform.position - GetConstraintAnchor(rope), Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			((Vector3)(ref val)).Normalize();
			Vector2 vector = InputManager.GetVector("Move").vector;
			Vector3 val2 = ((Component)player).transform.forward * vector.y + ((Component)player).transform.right * vector.x;
			val2.y = 0f;
			float num = ((((Vector3)(ref val2)).sqrMagnitude >= 0.0225f) ? Vector3.Dot(((Vector3)(ref val2)).normalized, val) : 0f);
			float num2 = Vector3.Dot(state.Velocity, val);
			if (!(num > 0.25f))
			{
				return num2 > 0.1f;
			}
			return true;
		}

		internal static bool BeginSolidHandholdJump(ENT_Player player)
		{
			//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)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value) || (!HasSolidHandhold(player) && !value.WasSolidHandhold))
			{
				return false;
			}
			StartRopeJumpCooldown(player, value);
			value.SuppressJumpRelease = true;
			value.AllowJumpRelease = false;
			value.GroundWalkMode = false;
			SetGroundWalkGrabDrag(value, groundWalk: false);
			value.PumpDirection = 0;
			value.PumpPower = 0f;
			value.GrabMoveAxis = Vector3.zero;
			value.GrabCorrection = Vector3.zero;
			value.NativeClimbThisFrame = false;
			return true;
		}

		internal static void CompleteAttachedJump(ENT_Player player)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0086: 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_0097: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			Vector3 val = Vector3.ClampMagnitude(GetNativeWorldVelocity(player), 24f);
			Vector3 val2 = Vector3.ClampMagnitude(value.Velocity, 24f);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val2.x, Mathf.Max(val2.y, val.y), val2.z);
			val3 = Vector3.ClampMagnitude(val3, 24f);
			float num = Vector3.Distance(new Vector3(val.x, 0f, val.z), new Vector3(val2.x, 0f, val2.z));
			value.Velocity = val3;
			SetReleaseVelocity(player, val3);
			float dt = Mathf.Max(Time.fixedDeltaTime, 0.001f);
			foreach (RopeState playerRope in GetPlayerRopes(value))
			{
				if (!playerRope.IsTaut)
				{
					ResetAttachedJumpSlackRope(playerRope, val3, dt);
				}
			}
			StandalonePlugin.Log.LogDebug((object)("Attached jump removed " + num.ToString("F2") + " m/s of native lateral impulse."));
		}

		internal static void CompleteSolidHandholdJump(ENT_Player player)
		{
			//IL_0042: 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_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)
			if (!((Object)(object)player == (Object)null) && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				if (HasSolidHandhold(player))
				{
					value.PendingSolidHandholdJump = false;
					value.PendingSolidHandholdJumpVelocity = Vector3.zero;
				}
				else
				{
					value.PendingSolidHandholdJump = true;
					value.PendingSolidHandholdJumpVelocity = Vector3.ClampMagnitude(GetNativeWorldVelocity(player), 24f);
					value.NativeClimbThisFrame = false;
				}
			}
		}

		internal static void NotifyGroundContact(ENT_Player player, Vector3 normal, Vector3 moveDirection)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null) && !(normal.y < Mathf.Cos(player.slopeLimit * ((float)Math.PI / 180f))) && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				value.LastGroundContactAt = Time.time;
				bool forceReset = !value.WasGrounded;
				value.WasGrounded = true;
				EnterGroundWalkMode(player, value, forceReset);
			}
		}

		internal static void EndAttachedJump(ENT_Player player)
		{
			if ((Object)(object)player != (Object)null && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				value.SuppressJumpRelease = false;
				ConsumeRopeJumpGroundWindow(player);
			}
		}

		internal static bool ShouldPreserveJumpGrab(ENT_Player player)
		{
			if ((Object)(object)player != (Object)null && Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value) && !value.AllowJumpRelease)
			{
				if (!value.SuppressJumpRelease)
				{
					return Time.time < value.NextAttachedJumpAt;
				}
				return true;
			}
			return false;
		}

		internal static bool ShouldKeepRopeOnJump(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return false;
			}
			if (Time.time <= value.NativeJumpUntil)
			{
				return false;
			}
			return IsRopeWalkMode(player, value);
		}

		internal static bool CanStartRopeJump(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)player).GetInstanceID();
			if (NextRopeJumpAllowedAt.TryGetValue(instanceID, out var value))
			{
				return Time.time >= value;
			}
			return true;
		}

		private static void ConsumeRopeJumpGroundWindow(ENT_Player player)
		{
			TimeSinceGroundedField?.SetValue(player, Mathf.Max(player.coyoteTime, 0.05f));
			float num = ((ForceAirbornTimeField?.GetValue(player) is float num2) ? num2 : 0f);
			ForceAirbornTimeField?.SetValue(player, Mathf.Max(num, 0.05f));
			CanJumpThisFrameField?.SetValue(player, false);
		}

		internal static void BeginNativeJumpRelease(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			value.AllowJumpRelease = true;
			bool flag = !value.SwingMode;
			List<RopeState> playerRopes = GetPlayerRopes(value);
			for (int i = 0; i < playerRopes.Count; i++)
			{
				RopeState ropeState = playerRopes[i];
				ropeState.DampenOnRelease = flag && GetRopeAngle(ropeState) <= (float)Math.PI / 4f;
			}
			if (HasTautConstraint(player) || player.hands == null)
			{
				return;
			}
			for (int j = 0; j < player.hands.Length; j++)
			{
				Hand val = player.hands[j];
				if (IsControlledRopeHand(val))
				{
					player.StopInteraction(val.id, "jump", true);
				}
			}
		}

		internal static void EndNativeJumpRelease(ENT_Player player)
		{
			if (!((Object)(object)player != (Object)null) || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			value.AllowJumpRelease = false;
			foreach (RopeState playerRope in GetPlayerRopes(value))
			{
				playerRope.DampenOnRelease = false;
			}
		}

		internal static void BeginJumpGrabCooldown(ENT_Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				BelowGrabBlockedUntil[((Object)player).GetInstanceID()] = Time.time + 0.75f;
			}
		}

		private static void StartRopeJumpCooldown(ENT_Player player, PlayerState? state = null)
		{
			if (!((Object)(object)player == (Object)null))
			{
				int instanceID = ((Object)player).GetInstanceID();
				float num = Time.time + 0.6f;
				NextRopeJumpAllowedAt[instanceID] = num;
				if (state != null)
				{
					state.NextAttachedJumpAt = num;
				}
				BeginJumpGrabCooldown(player);
			}
		}

		internal static bool CanGrabRope(ENT_Player player, Vector3 grabPosition)
		{
			//IL_003a: 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_004b: 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 ((Object)(object)player == (Object)null || !BelowGrabBlockedUntil.TryGetValue(((Object)player).GetInstanceID(), out var value))
			{
				return true;
			}
			if (Time.time >= value)
			{
				BelowGrabBlockedUntil.Remove(((Object)player).GetInstanceID());
				return true;
			}
			Vector3 val = grabPosition - ((Component)player).transform.position;
			if (val.y >= -0.1f)
			{
				return true;
			}
			val.y = 0f;
			return ((Vector3)(ref val)).sqrMagnitude > 1.5625f;
		}

		internal static void PreparePlayerMovement(ENT_Player player)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (IsAttached(player))
			{
				SetPlayerVelocity(player, Vector3.zero);
			}
		}

		internal static void QueueReleaseJump(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null || !ReleaseJumps.TryGetValue(((Object)player).GetInstanceID(), out ReleaseJumpState value))
			{
				return;
			}
			if (Time.time > value.ExpiresAt)
			{
				ReleaseJumps.Remove(((Object)player).GetInstanceID());
				return;
			}
			bool pressed = InputManager.GetButton("Jump").Pressed;
			if (value.WaitingForButtonRelease)
			{
				if (!pressed)
				{
					value.WaitingForButtonRelease = false;
				}
			}
			else if (pressed)
			{
				ForceJumpField?.SetValue(player, true);
				ReleaseJumps.Remove(((Object)player).GetInstanceID());
			}
		}

		internal static void PrepareGroundedRopeWalk(ENT_Player player)
		{
			//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_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_005e: 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_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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_00ee: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value) || !IsPlayerGrounded(player) || HasSolidHandhold(player))
			{
				return;
			}
			Vector2 vector = InputManager.GetVector("Move").vector;
			if (((Vector2)(ref vector)).sqrMagnitude < 0.0225f)
			{
				return;
			}
			Vector3 val = ((Component)player).transform.forward * vector.y + ((Component)player).transform.right * vector.x;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return;
			}
			((Vector3)(ref val)).Normalize();
			foreach (int ropeId in value.RopeIds)
			{
				if (Ropes.TryGetValue(ropeId, out RopeState value2) && value2.IsTaut)
				{
					Vector3 val2 = GetConstraintAnchor(value2) - ((Component)player).transform.position;
					val2.y = 0f;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f) && !(Vector3.Dot(val, ((Vector3)(ref val2)).normalized) < 0.1f))
					{
						EnterSlack(value2, player, 0f, requireRadiusEntry: false, pinHandsToGrip: true);
						value.PumpDirection = 0;
						value.PumpPower = 0f;
						value.SwingMode = false;
						value.SwingChargeStartedAt = float.NegativeInfinity;
					}
				}
			}
		}

		internal static bool ShouldUseNativeClimb(ENT_Player player)
		{
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return false;
			}
			if (HasSolidHandhold(player))
			{
				return true;
			}
			TransferSolidHandholdReleaseVelocity(player, value);
			if (!HasTautConstraint(player))
			{
				return false;
			}
			if (IsRopeWalkMode(player, value))
			{
				return false;
			}
			UpdateSwingMode(player, value);
			return !value.SwingMode;
		}

		private static void TransferSolidHandholdReleaseVelocity(ENT_Player player, PlayerState state)
		{
			//IL_0017: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!state.WasSolidHandhold)
			{
				return;
			}
			state.WasSolidHandhold = false;
			state.Position = ((Component)player).transform.position;
			state.Velocity = Vector3.ClampMagnitude(state.SolidHandholdVelocity, 24f);
			foreach (int ropeId in state.RopeIds)
			{
				if (Ropes.TryGetValue(ropeId, out RopeState value) && value.IsTaut)
				{
					InitializeEntryVelocity(state, value);
					break;
				}
			}
			if (player.IsSprinting() && ((Vector3)(ref state.Velocity)).magnitude >= 1.25f)
			{
				state.SwingMode = true;
				state.SwingChargeStartedAt = float.NegativeInfinity;
				state.WalkModeStartedAt = float.NegativeInfinity;
			}
		}

		private static bool HasSolidHandhold(ENT_Player player)
		{
			if (player?.hands == null)
			{
				return false;
			}
			for (int i = 0; i < player.hands.Length; i++)
			{
				Hand val = player.hands[i];
				if (val != null && val.currentInteract != null)
				{
					CL_Handhold val2 = (CL_Handhold)(((object)val.handhold) ?? ((object)/*isinst with value type is only supported in some contexts*/));
					if ((Object)(object)val2 != (Object)null && !(val2 is CL_Handhold_Rope))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static bool IsControlledRopeHand(Hand hand)
		{
			if (hand != null)
			{
				CL_Handhold handhold = hand.handhold;
				CL_Handhold_Rope val = (CL_Handhold_Rope)(object)((handhold is CL_Handhold_Rope) ? handhold : null);
				if (val != null)
				{
					object? obj = HandholdRopeField?.GetValue(val);
					ENV_Rope val2 = (ENV_Rope)((obj is ENV_Rope) ? obj : null);
					if ((Object)(object)val2 != (Object)null)
					{
						return IsControlled(val2);
					}
					return false;
				}
			}
			return false;
		}

		internal static Vector3 GetEntryVelocity(ENT_Player player)
		{
			//IL_001f: 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)(object)player != (Object)null) || IsPlayerGrounded(player) || !((Object)(object)player.cCon != (Object)null))
			{
				return Vector3.zero;
			}
			return player.cCon.velocity;
		}

		private static Vector3 GetNativeWorldVelocity(ENT_Player player)
		{
			//IL_0057: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player != (Object)null && PlayerVelocityField?.GetValue(player) is Vector3 val)
			{
				return val * 175f;
			}
			if (!((Object)(object)player?.cCon != (Object)null))
			{
				return Vector3.zero;
			}
			return player.cCon.velocity;
		}

		private static void MovePlayerWithCollisions(ENT_Player player, Vector3 displacement)
		{
			//IL_0000: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (!IsFinite(displacement))
			{
				throw new InvalidOperationException("The rope solver produced a non-finite player correction.");
			}
			float magnitude = ((Vector3)(ref displacement)).magnitude;
			if (!(magnitude < 0.0001f))
			{
				if (magnitude > 3f)
				{
					throw new InvalidOperationException("The rope solver rejected an unsafe " + magnitude.ToString("F2") + " metre player correction.");
				}
				CharacterController cCon = player.cCon;
				if ((Object)(object)cCon == (Object)null || !((Collider)cCon).enabled)
				{
					throw new InvalidOperationException("The player collision controller is unavailable.");
				}
				int num = Mathf.Max(1, Mathf.CeilToInt(magnitude / 0.35f));
				Vector3 val = displacement / (float)num;
				for (int i = 0; i < num; i++)
				{
					cCon.Move(val);
				}
			}
		}

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

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (IsFinite(value.x) && IsFinite(value.y))
			{
				return IsFinite(value.z);
			}
			return false;
		}

		private static void ValidateManagedState(PlayerState playerState, List<RopeState> ropes, Vector3 playerPosition, Vector3 nativeVelocity)
		{
			//IL_0000: 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_0021: 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_0036: 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_003b: 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_0092: 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)
			if (!IsFinite(playerPosition))
			{
				throw new InvalidOperationException("The player position became non-finite.");
			}
			if (!IsFinite(playerState.Velocity))
			{
				playerState.Velocity = (IsFinite(nativeVelocity) ? Vector3.ClampMagnitude(nativeVelocity, 24f) : Vector3.zero);
			}
			for (int i = 0; i < ropes.Count; i++)
			{
				RopeState ropeState = ropes[i];
				if (!EnsureFiniteRopeGeometry(ropeState.Rope))
				{
					throw new InvalidOperationException("A controlled rope has an invalid anchor.");
				}
				for (int num = ropeState.CollisionPivots.Count - 1; num >= 0; num--)
				{
					RopeCollisionPivot ropeCollisionPivot = ropeState.CollisionPivots[num];
					if (!IsFinite(ropeCollisionPivot.Position) || !IsFinite(ropeCollisionPivot.Normal))
					{
						ropeState.CollisionPivots.RemoveAt(num);
					}
				}
				if (!IsFinite(ropeState.RopeLength) || !IsFinite(ropeState.BodyLength) || !IsFinite(ropeState.ArmLength) || !(ropeState.RopeLength >= 0.25f) || !(ropeState.BodyLength >= 0.25f))
				{
					ResolveGrip(ropeState, playerPosition);
					ropeState.HasGripDirection = false;
					InitializeGripDirection(ropeState, preserveCurrentGripPosition: true);
				}
			}
		}

		private static bool EnsureFiniteRopeGeometry(ENV_Rope rope)
		{
			//IL_0025: 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_009a: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_010e: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rope == (Object)null || rope.nodes == null || rope.nodes.Count < 2 || !IsFinite(((Component)rope).transform.position))
			{
				return false;
			}
			float num = ((IsFinite(rope.nodeDistance) && rope.nodeDistance > 0.001f) ? rope.nodeDistance : 0.25f);
			float num2 = num * (float)rope.nodes.Count * 8f + 10f;
			Vector3 position = ((Component)rope).transform.position;
			bool flag = false;
			for (int i = 0; i < rope.nodes.Count; i++)
			{
				ENV_Rope_Node val = rope.nodes[i];
				if (!IsFinite(val.position) || !IsFinite(val.previousPosition) || !IsFinite(val.velocity) || Vector3.Distance(position, val.position) > num2)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return true;
			}
			for (int j = 0; j < rope.nodes.Count; j++)
			{
				ENV_Rope_Node obj = rope.nodes[j];
				obj.position = position + Vector3.down * (num * (float)j);
				obj.previousPosition = obj.position;
				obj.velocity = Vector3.zero;
				obj.locked = j == 0;
				obj.colliding = false;
			}
			if ((Object)(object)rope.target != (Object)null)
			{
				rope.target.position = rope.nodes[rope.nodes.Count - 1].position;
			}
			object? obj2 = TargetRigidbodyField?.GetValue(rope);
			Rigidbody val2 = (Rigidbody)((obj2 is Rigidbody) ? obj2 : null);
			if ((Object)(object)val2 != (Object)null && !val2.isKinematic)
			{
				val2.velocity = Vector3.zero;
				val2.angularVelocity = Vector3.zero;
			}
			StandalonePlugin.Log.LogWarning((object)"Recovered an invalid rope node layout before it could propagate into player movement.");
			return true;
		}

		internal static bool ShouldSuppressHandVelocity(Hand hand)
		{
			return IsControlledRopeHand(hand);
		}

		internal static void RestorePhysicsTransforms(ENT_Player player)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			foreach (int ropeId in value.RopeIds)
			{
				if (Ropes.TryGetValue(ropeId, out RopeState value2))
				{
					if (!EnsureFiniteRopeGeometry(value2.Rope))
					{
						throw new InvalidOperationException("A controlled rope has an invalid anchor.");
					}
					if ((Object)(object)value2.Endpoint != (Object)null && value2.Rope.nodes != null && value2.Rope.nodes.Count > 0)
					{
						value2.Endpoint.position = value2.Rope.nodes[value2.Rope.nodes.Count - 1].position;
					}
					RenderRope(value2.Rope);
					StabilizeGrabAnchors(value2);
				}
			}
		}

		internal static void RestorePhysicsTransformsSafely(ENT_Player player)
		{
			try
			{
				RestorePhysicsTransforms(player);
			}
			catch (Exception ex)
			{
				StandalonePlugin.Log.LogError((object)("Rope physics synchronization failed and was safely detached: " + ex));
				DisableControlAfterRuntimeFailure(player, "physics synchronization");
			}
		}

		internal static void RenderInterpolatedVisuals(ENT_Player player)
		{
			//IL_00b3: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_01a2: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || !Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			float num = Mathf.Clamp01((Time.time - Time.fixedTime) / Mathf.Max(Time.fixedDeltaTime, 0.001f));
			foreach (int ropeId in value.RopeIds)
			{
				if (!Ropes.TryGetValue(ropeId, out RopeState value2) || !value2.HasRenderSnapshot)
				{
					continue;
				}
				int num2 = value2.CurrentRenderPositions.Length;
				if (value2.InterpolatedRenderPositions.Length != num2)
				{
					value2.InterpolatedRenderPositions = (Vector3[])(object)new Vector3[num2];
				}
				for (int i = 0; i < num2; i++)
				{
					value2.InterpolatedRenderPositions[i] = Vector3.Lerp(value2.PreviousRenderPositions[i], value2.CurrentRenderPositions[i], num);
				}
				RenderRope(value2.Rope, value2.InterpolatedRenderPositions);
				if ((Object)(object)value2.Endpoint != (Object)null && num2 > 0)
				{
					((Component)value2.Endpoint).transform.position = value2.InterpolatedRenderPositions[num2 - 1];
				}
				foreach (GrabState value3 in value2.Grabs.Values)
				{
					if (IsGrabActive(value3) && !((Object)(object)value3.Hand.handModel == (Object)null) && TryGetGrabAnchor(value2, value3, value2.InterpolatedRenderPositions, out var anchor))
					{
						if (!value3.HasVisualAnchor || Vector3.Distance(value3.VisualAnchor, anchor) > 2.5f)
						{
							value3.VisualAnchor = anchor;
							value3.HasVisualAnchor = true;
						}
						else
						{
							float num3 = 1f - Mathf.Exp(-24f * Mathf.Max(Time.deltaTime, 0.001f));
							value3.VisualAnchor = Vector3.Lerp(value3.VisualAnchor, anchor, num3);
						}
						value3.Hand.handModel.position = value3.VisualAnchor;
					}
				}
			}
		}

		internal static void RenderInterpolatedVisualsSafely(ENT_Player player)
		{
			try
			{
				RenderInterpolatedVisuals(player);
			}
			catch (Exception ex)
			{
				StandalonePlugin.Log.LogError((object)("Rope visual synchronization failed and was safely detached: " + ex));
				DisableControlAfterRuntimeFailure(player, "visual synchronization");
			}
		}

		internal static void StepPlayer(ENT_Player player, Vector3 movementStart)
		{
			//IL_00f9: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_0194: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: 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_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06db: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0700: Unknown result type (might be due to invalid IL or missing references)
			//IL_0707: Unknown result type (might be due to invalid IL or missing references)
			//IL_070c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0715: Unknown result type (might be due to invalid IL or missing references)
			//IL_072b: Unknown result type (might be due to invalid IL or missing references)
			//IL_072f: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0740: Unknown result type (might be due to invalid IL or missing references)
			//IL_0742: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_074c: Unknown result type (might be due to invalid IL or missing references)
			//IL_07dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_080f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0800: Unknown result type (might be due to invalid IL or missing references)
			//IL_0807: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0814: Unknown result type (might be due to invalid IL or missing references)
			//IL_0833: Unknown result type (might be due to invalid IL or missing references)
			//IL_0837: Unknown result type (might be due to invalid IL or missing references)
			//IL_083c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0852: Unknown result type (might be due to invalid IL or missing references)
			//IL_0856: Unknown result type (might be due to invalid IL or missing references)
			//IL_085b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0860: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_0772: Unknown result type (might be due to invalid IL or missing references)
			//IL_0774: Unknown result type (might be due to invalid IL or missing references)
			//IL_0776: Unknown result type (might be due to invalid IL or missing references)
			//IL_077b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0870: Unknown result type (might be due to invalid IL or missing references)
			//IL_0874: Unknown result type (might be due to invalid IL or missing references)
			//IL_0879: Unknown result type (might be due to invalid IL or missing references)
			//IL_087e: Unknown result type (might be due to invalid IL or missing references)
			//IL_079c: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0910: Unknown result type (might be due to invalid IL or missing references)
			//IL_0902: Unknown result type (might be due to invalid IL or missing references)
			if (!Players.TryGetValue(((Object)player).GetInstanceID(), out PlayerState value))
			{
				return;
			}
			RestorePlayerControllerCollision(player);
			DropOverstretchedHands(player, value);
			if (!Players.TryGetValue(((Object)player).GetInstanceID(), out value))
			{
				return;
			}
			RemoveInvalidRopes(value);
			if (value.RopeIds.Count == 0)
			{
				Players.Remove(((Object)player).GetInstanceID());
				BeginPlayerCollisionRecovery(player);
				return;
			}
			bool flag = HasSolidHandhold(player);
			bool flag2 = IsPlayerGrounded(player);
			bool forceReset = flag2 && !value.WasGrounded;
			if (flag2)
			{
				value.WasGrounded = true;
				value.LastGroundContactAt = Time.time;
				if (flag)
				{
					value.GroundWalkMode = false;
					SetGroundWalkGrabDrag(value, groundWalk: false);
				}
				else
				{
					EnterGroundWalkMode(player, value, forceReset);
				}
			}
			else
			{
				if (value.GroundWalkMode)
				{
					value.GroundWalkMode = false;
					SetGroundWalkGrabDrag(value, groundWalk: false);
				}
				if (Time.time - value.LastGroundContactAt > 0.2f)
				{
					value.WasGrounded = false;
				}
			}
			float num = Mathf.Max(Time.fixedDeltaTime, 0.001f);
			Vector3 position = ((Component)player).transform.position;
			Vector3 val = (position - movementStart) / num;
			value.Position = position;
			List<RopeState> list = FillPlayerRopeBuffer(value);
			ValidateManagedState(value, list, position, val);
			AdvanceCollisionConstraintTransitions(list, num);
			UpdateCollisionPivots(list);
			UpdateGroundHeldGripTargets(value, list, position, num);
			bool flag3 = UpdateSlackTransitions(value, list, position, val);
			DropUnsupportedTension(player, value, list, position, val);
			flag = HasSolidHandhold(player);
			bool flag4 = value.PendingSolidHandholdJump && !flag;
			Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.0025f) ? val : value.PendingSolidHandholdJumpVelocity);
			if (flag4)
			{
				value.PendingSolidHandholdJump = false;
				value.PendingSolidHandholdJumpVelocity = Vector3.zero;
				value.WasSolidHandhold = false;
				value.SolidHandholdVelocity = Vector3.zero;
				value.NativeClimbThisFrame = false;
			}
			if (flag || flag4)
			{
				if (flag)
				{
					value.GroundWalkMode = false;
					SetGroundWalkGrabDrag(value, groundWalk: false);
				}
				ReleaseInwardSolidHandholdTension(player, list, position);
			}
			List<RopeState> list2 = FillTautRopeBuffer(value, list);
			if (list2.Count == 0)
			{
				value.PumpPower = Mathf.MoveTowards(value.PumpPower, 0f, 4f * num);
				value.PumpDirection = 0;
				value.Velocity = Vector3.ClampMagnitude(flag4 ? val2 : val, 24f);
				value.Position = position;
				value.GrabMoveAxis = Vector3.zero;
				value.GrabCorrection = Vector3.zero;
				value.NativeClimbThisFrame = false;
				{
					foreach (RopeState item in list)
					{
						UpdateSlackRope(item, position, num);
					}
					return;
				}
			}
			if (flag)
			{
				StepSolidHandholdTether(player, value, list, list2, movementStart, position, val, num);
				return;
			}
			if (flag4)
			{
				value.Velocity = Vector3.ClampMagnitude(val2, 24f);
				if (list2.Count == 1)
				{
					Vector3 val3 = position - GetConstraintAnchor(list2[0]);
					if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f)
					{
						value.Velocity = Vector3.ProjectOnPlane(value.Velocity, ((Vector3)(ref val3)).normalized);
					}
				}
				value.SwingMode = ((Vector3)(ref value.Velocity)).magnitude >= 0.15f;
				value.SwingChargeStartedAt = float.NegativeInfinity;
				value.WalkModeStartedAt = float.NegativeInfinity;
				value.AttachmentWarmupSteps = 0;
				for (int i = 0; i < list2.Count; i++)
				{
					SynchronizeRopeWithPlayerMomentum(list2[i], position, value.Velocity, num);
				}
				flag3 = true;
				StandalonePlugin.Log.LogDebug((object)("Ledge jump transferred " + ((Vector3)(ref value.Velocity)).magnitude.ToString("F2") + " m/s into the held rope."));
			}
			else if (flag3)
			{
				value.Velocity = Vector3.ClampMagnitude(val, 24f);
				if (list2.Count == 1)
				{
					InitializeEntryVelocity(value, list2[0]);
				}
			}
			if (flag2 && value.GroundWalkMode)
			{
				Vector3 val4 = position;
				Vector3 val6 = default(Vector3);
				for (int j = 0; j < 4; j++)
				{
					foreach (RopeState item2 in list2)
					{
						Vector3 constraintAnchor = GetConstraintAnchor(item2);
						Vector3 val5 = val4 - constraintAnchor;
						float remainingBodyLength = GetRemainingBodyLength(item2);
						float y = val5.y;
						float num2 = remainingBodyLength * remainingBodyLength - y * y;
						((Vector3)(ref val6))..ctor(val5.x, 0f, val5.z);
						float sqrMagnitude = ((Vector3)(ref val6)).sqrMagnitude;
						if (num2 >= 0f && sqrMagnitude > num2 && sqrMagnitude > 0.0001f)
						{
							float y2 = val4.y;
							float num3 = Mathf.Sqrt(num2);
							val4 = constraintAnchor + ((Vector3)(ref val6)).normalized * num3;
							val4.y = y2;
						}
					}
				}
				MovePlayerWithCollisions(player, val4 - position);
				Vector3 playerPosition = (value.Position = ((Component)player).transform.position);
				value.Velocity = Vector3.ClampMagnitude(val, 24f);
				value.PumpPower = 0f;
				value.PumpDirection = 0;
				value.GrabMoveAxis = Vector3.zero;
				value.GrabCorrection = Vector3.zero;
				value.NativeClimbThisFrame = false;
				{
					foreach (RopeState item3 in list)
					{
						if (item3.IsTaut)
						{
							UpdateRope(item3, playerPosition, num, followPlayer: true);
						}
						else
						{
							UpdateSlackRope(item3, playerPosition, num);
						}
					}
					return;
				}
			}
			if (value.NativeClimbThisFrame)
			{
				SyncConstraintLengths(list2, position);
				Vector3 val7 = (position - movementStart) / num;
				if (list2.Count == 1)
				{
					Vector3 val8 = position - GetConstraintAnchor(list2[0]);
					if (((Vector3)(ref val8)).sqrMagnitude > 0.0001f)
					{
						val7 = Vector3.ProjectOnPlane(val7, ((Vector3)(ref val8)).normalized);
					}
				}
				value.PumpPower = Mathf.MoveTowards(value.PumpPower, 0f, 4f * num);
				value.PumpDirection = 0;
				value.Velocity = Vector3.ClampMagnitude(val7, 24f);
				value.Position = position;
				value.GrabMoveAxis = Vector3.zero;
				value.GrabCorrection = Vector3.zero;
				value.NativeClimbThisFrame = false;
				{
					foreach (RopeState item4 in list)
					{
						if (item4.IsTaut)
						{
							AdvanceClimbMomentum(item4, num);
							UpdateRope(item4, position, num, followPlayer: false);
						}
						else
						{
							UpdateSlackRope(item4, position, num);
						}
					}
					return;
				}
			}
			if (((Vector3)(ref value.GrabCorrection)).sqrMagnitude > 0.0001f)
			{
				AdjustConstraintLengthsFromHands(list2, movementStart, position);
			}
			WarmUpConstraints(value, list2, position);
			float num4 = Mathf.Max(0.1f, RopeSettings.Gravity);
			PlayerState playerState = value;
			playerState.Velocity += Vector3.down * num4 * num;
			ApplyPump(value, list2);
			Vector3 val9 = (flag3 ? position : (position + value.Velocity * num));
			if (list2.Count == 1)
			{
				RopeState ropeState = list2[0];
				val9 = ProjectToSphere(val9, GetConstraintAnchor(ropeState), GetRemainingBodyLength(ropeState));
				val9 = ApplyArcLimit(val9, value, ropeState);
			}
			else
			{
				for (int k = 0; k < 8; k++)
				{
					foreach (RopeState item5 in list2)
					{
						Vector3 constraintAnchor2 = GetConstraintAnchor(item5);
						Vector3 val10 = val9 - constraintAnchor2;
						float magnitude = ((Vector3)(ref val10)).magnitude;
						float remainingBodyLength2 = GetRemainingBodyLength(item5);
						if (magnitude > remainingBodyLength2 && magnitude > 0.0001f)
						{
							val9 = constraintAnchor2 + val10 / magnitude * remainingBodyLength2;
						}
					}
				}
			}
			MovePlayerWithCollisions(player, val9 - position);
			Vector3 position2 = ((Component)player).transform.position;
			Vector3 val11 = (flag3 ? value.Velocity : ((position2 - position) / num));
			float num5 = Mathf.Max(2f, ((Vector3)(ref value.Velocity)).magnitude + 0.75f);
			val11 = Vector3.ClampMagnitude(val11, num5);
			if (list2.Count == 1)
			{
				RopeState state = list2[0];
				Vector3 val12 = position2 - GetConstraintAnchor(state);
				if (((Vector3)(ref val12)).sqrMagnitude > 0.0001f)
				{
					val11 = Vector3.ProjectOnPlane(val11, ((Vector3)(ref val12)).normalized);
				}
			}
			float num6 = Mathf.Max(0f, RopeSettings.Damping);
			value.Velocity = val11 * Mathf.Max(0f, 1f - num6 * num);
			value.Position = position2;
			value.GrabMoveAxis = Vector3.zero;
			value.GrabCorrection = Vector3.zero;
			value.NativeClimbThisFrame = false;
			SetPlayerVelocity(player, Vector3.zero);
			foreach (RopeState item6 in list)
			{
				if (item6.IsTaut)
				{
					UpdateRope(item6, position2, num, followPlayer: true);
				}
				else
				{
					UpdateSlackRope(item6, position2, num);
				}
			}
		}

		private static void ReleaseInwardSolidHandholdTension(ENT_Player player, List<RopeState> ropes, Vector3 playerPosition)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < ropes.Count; i++)
			{
				RopeState ropeState = ropes[i];
				if (ropeState.IsTaut && !(GetBodyPathLength(ropeState, playerPosition) >= ropeState.BodyLength - 0.05f))
				{
					EnterSlack(ropeState, player, 0f, requireRadiusEntry: false, pinHandsToGrip: true);
				}
			}
		}

		private static void StepSolidHandholdTether(ENT_Player player, PlayerState state, List<RopeState> ropes, List<RopeState> constraints, Vector3 movementStart, Vector3 nativePosition, Vector3 nativeVelocity, float dt)
		{
			//IL_0000: 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_0071: 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_0074: 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_0089: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_011d: 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_012d: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0045: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = nativePosition;
			for (int i = 0; i < 8; i++)
			{
				for (int j = 0; j < constraints.Count; j++)
				{
					RopeState state2 = constraints[j];
					Vector3 constraintAnchor = GetConstraintAnchor(state2);
					Vector3 val2 = val - constraintAnchor;
					float magnitude = ((Vector3)(ref val2)).magnitude;
					float remainingBodyLength = GetRemainingBodyLength(state2);
					if (magnitude > remainingBodyLength && magnitude > 0.0001f)
					{
						val = constraintAnchor + val2 / magnitude * remainingBodyLength;
					}
				}
			}
			MovePlayerWithCollisions(player, val - nativePosition);
			Vector3 val3 = (state.Position = ((Component)player).transform.position);
			state.WasSolidHandhold = true;
			state.SolidHandholdVelocity = Vector3.ClampMagnitude(nativeVelocity, 24f);
			state.Velocity = Vector3.ClampMagnitude((val3 - movementStart) / dt, 24f);
			if (((Vector3)(ref state.Velocity)).sqrMagnitude < 0.0001f)
			{
				state.Velocity = Vector3.ClampMagnitude(nativeVelocity, 24f);
			}
			state.PumpPower = 0f;
			state.PumpDirection = 0;
			state.SwingMode = false;
			state.SwingChargeStartedAt = float.NegativeInfinity;
			state.WalkModeStartedAt = float.NegativeInfinity;
			state.GrabMoveAxis = Vector3.zero;
			state.GrabCorrection = Vector3.zero;
			state.NativeClimbThisFrame = false;
			for (int k = 0; k < ropes.Count; k++)
			{
				RopeState ropeState = ropes[k];
				if (ropeState.IsTaut)
				{
					UpdateRope(ropeState, val3, dt, followPlayer: true);
				}
				else
				{
					UpdateSlackRope(ropeState, val3, dt);
				}
			}
		}

		internal static void StepPlayerSafely(ENT_Player player, Vector3 movementStart)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				StepPlayer(player, movementStart);
			}
			catch (Exception ex)
			{
				StandalonePlugin.Log.LogError((object)("Rope movement failed and was safely detached: " + ex));
				DisableControlAfterRuntimeFailure(player, "player movement");
			}
		}

		private static bool UpdateSlackTransitions(PlayerState playerState, List<RopeState> ropes, Vector3 playerPosition, Vector3 nativeVelocity)
		{
			//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_0041: 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_0049: 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_0052: 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_0076: 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_007b: 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_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_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_00a9: 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_00b1: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing r