Decompiled source of Grappling v0.1.8

BepInEx/plugins/Zephyrfit-Grappling/ZephyrfitGrappling.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ZephyrfitGrappling")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.8.0")]
[assembly: AssemblyInformationalVersion("0.1.8")]
[assembly: AssemblyProduct("ZephyrfitGrappling")]
[assembly: AssemblyTitle("ZephyrfitGrappling")]
[assembly: AssemblyVersion("0.1.8.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 Zephyrfit.Grappling
{
	public static class Ballistics
	{
		public static double Drop(double gravity, double step, double time)
		{
			int num = (int)Math.Floor(time / step);
			double num2 = time - (double)num * step;
			return gravity * (step * step * (double)num * (double)(num + 1) / 2.0 + step * (double)(num + 1) * num2);
		}

		public static bool Solve(float x, float y, float z, float speed, float gravity, float step, float lifetime, out float vx, out float vy, out float vz)
		{
			vx = (vy = (vz = 0f));
			if (speed <= 0f || step <= 0f || lifetime <= 0f || x * x + y * y + z * z < 0.0001f)
			{
				return false;
			}
			double num = 1E-05;
			double num2 = num;
			bool flag = false;
			for (int i = 1; i <= 256; i++)
			{
				num2 = (double)(lifetime * (float)i) / 256.0;
				if (Required(num2) <= 0.0)
				{
					flag = true;
					break;
				}
				num = num2;
			}
			if (!flag)
			{
				return false;
			}
			for (int j = 0; j < 32; j++)
			{
				double num3 = (num + num2) / 2.0;
				if (Required(num3) > 0.0)
				{
					num = num3;
				}
				else
				{
					num2 = num3;
				}
			}
			double num4 = (num + num2) / 2.0;
			vx = (float)((double)x / num4);
			vz = (float)((double)z / num4);
			vy = (float)(((double)y + Drop(gravity, step, num4)) / num4);
			return true;
			double Required(double t)
			{
				double num5 = (double)y + Drop(gravity, step, t);
				return ((double)(x * x + z * z) + num5 * num5) / (t * t) - (double)(speed * speed);
			}
		}
	}
	internal static class GrappleAim
	{
		internal static Ray ReticleRay(Player player)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Camera mainCamera = Utils.GetMainCamera();
			if (!Object.op_Implicit((Object)(object)mainCamera))
			{
				return new Ray(((Character)player).GetEyePoint(), ((Character)player).GetLookDir());
			}
			Image val = (Object.op_Implicit((Object)(object)Hud.instance) ? Hud.instance.m_crosshair : null);
			if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy)
			{
				Canvas canvas = ((Graphic)val).canvas;
				Camera obj = ((Object.op_Implicit((Object)(object)canvas) && (int)canvas.renderMode != 0) ? canvas.worldCamera : null);
				RectTransform rectTransform = ((Graphic)val).rectTransform;
				Rect rect = ((Graphic)val).rectTransform.rect;
				Vector3 val2 = ((Transform)rectTransform).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center));
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(obj, val2);
				return mainCamera.ScreenPointToRay(Vector2.op_Implicit(val3));
			}
			return mainCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
		}

		internal static bool Plan(Player player, Vector3 origin, Projectile projectile, float speed, float lifetime, float range, float ropeRange, int mask, out Vector3 velocity, out float distance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_005e: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0117: 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_011d: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: 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 references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: 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_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			Ray val = ReticleRay(player);
			float num = range + Vector3.Distance(((Ray)(ref val)).origin, origin);
			RaycastHit? val2 = null;
			foreach (RaycastHit item in from h in Physics.RaycastAll(val, num, mask, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player))
				{
					val2 = current;
					break;
				}
			}
			Vector3 point;
			RaycastHit value;
			if (!val2.HasValue)
			{
				point = ((Ray)(ref val)).GetPoint(num);
			}
			else
			{
				value = val2.Value;
				point = ((RaycastHit)(ref value)).point;
			}
			Vector3 val3 = point;
			Vector3 val4 = val3 - origin;
			velocity = ((Vector3)(ref val4)).normalized * speed;
			distance = Vector3.Distance(((Component)player).transform.position, val3);
			if (!val2.HasValue)
			{
				float num2 = Vector3.Dot(origin - ((Ray)(ref val)).origin, ((Ray)(ref val)).direction);
				Vector3 val5 = ((Ray)(ref val)).GetPoint(num2) - origin;
				float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude;
				float num3 = range * 0.75f;
				val3 = ((Ray)(ref val)).GetPoint(num2 + Mathf.Sqrt(Mathf.Max(0f, num3 * num3 - sqrMagnitude)));
				val4 = val3 - origin;
			}
			if (projectile.m_drag != 0f || ((Vector3)(ref val4)).magnitude > range + 0.001f || (distance > ropeRange && val2.HasValue))
			{
				return false;
			}
			if (!Ballistics.Solve(val4.x, val4.y, val4.z, speed, projectile.m_gravity, Time.fixedDeltaTime, lifetime, out var vx, out var vy, out var vz))
			{
				return false;
			}
			velocity = new Vector3(vx, vy, vz);
			if (!val2.HasValue)
			{
				return false;
			}
			Vector3 val6 = origin;
			Vector3 val7 = velocity;
			float fixedDeltaTime = Time.fixedDeltaTime;
			for (float num4 = 0f; num4 < lifetime; num4 += fixedDeltaTime)
			{
				val7 += Vector3.down * (projectile.m_gravity * fixedDeltaTime);
				Vector3 val8 = val6 + val7 * fixedDeltaTime;
				Vector3 val9 = val8 - val6;
				Vector3 val10 = val6 - val9 * 0.5f;
				foreach (RaycastHit item2 in ((projectile.m_rayRadius > 0f) ? Physics.SphereCastAll(val10, projectile.m_rayRadius, ((Vector3)(ref val9)).normalized, ((Vector3)(ref val9)).magnitude, mask, (QueryTriggerInteraction)1) : Physics.RaycastAll(val10, ((Vector3)(ref val9)).normalized, ((Vector3)(ref val9)).magnitude * 1.5f, mask, (QueryTriggerInteraction)1)).OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance))
				{
					RaycastHit current2 = item2;
					if (!((Object)(object)((Component)((RaycastHit)(ref current2)).collider).GetComponentInParent<Player>() == (Object)(object)player))
					{
						Collider collider = ((RaycastHit)(ref current2)).collider;
						value = val2.Value;
						return (Object)(object)collider == (Object)(object)((RaycastHit)(ref value)).collider && Vector3.Distance(((RaycastHit)(ref current2)).point, val3) < 0.3f && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current2)).collider).GetComponentInParent<Character>()) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current2)).collider).GetComponentInParent<GrapplingBlocker>()) && projectile.m_spawnOnHit.GetComponent<GrapplingPoint>().CanAttach(((Component)((RaycastHit)(ref current2)).collider).gameObject);
					}
				}
				if (Vector3.Distance(origin, val8) > range)
				{
					break;
				}
				val6 = val8;
			}
			return false;
		}
	}
	internal sealed class GrappleSession
	{
		internal sealed class Impact
		{
			internal Collider Support;

			internal long Token;

			internal bool Accepted;

			internal bool Activated;

			internal Vector3 Position;

			internal Vector3 Normal;

			internal GrapplingPoint? PreviousLocal;

			internal GrapplingPoint? Candidate;
		}

		internal sealed class Hit
		{
			internal Projectile Projectile;

			internal Vector3 Position;

			internal Vector3 Normal;
		}

		private readonly Plugin plugin;

		internal readonly RopeState State = new RopeState();

		internal bool Conflict;

		private Player? player;

		private ItemData? equipped;

		private GrapplingPoint? point;

		private SE_Stats? attachedEffect;

		private Collider? support;

		private Vector3 supportOffset;

		private Projectile? flight;

		private long flightToken;

		private float shotRange;

		private float shotRopeMaximum;

		private float anchorRange;

		private float ropeLength;

		private float nativeDrain;

		private float shotDeadline;

		private bool fireHeld;

		private bool releaseHeld;

		private bool ropeHeld;

		private bool aimHeld;

		private bool armed;

		private float attachmentDistance;

		private float descentGoal;

		private long handledDescentRequest;

		private bool ownsAimPose;

		private bool savedAimBool;

		private Animator? aimAnimator;

		private float aimWeight;

		private bool fireQueued;

		private Animator? ikAnimator;

		private Transform? aimWeaponVisual;

		private Quaternion savedWeaponRotation;

		private Quaternion weaponToBarrel;

		private Quaternion wristToWeapon;

		private Quaternion rightWristToWeapon;

		private bool aimCalibrated;

		private readonly RopeAssist departureAssist = new RopeAssist();

		private float lastGroundedAt = -100f;

		private float lastJumpAt = -100f;

		private readonly RopePath ropePath = new RopePath();

		private bool reloadLogged = true;

		private bool cleaning;

		private Vector3 shotOrigin;

		private Vector3 previousPlayerPosition;

		private RopeMode previousMode;

		private int mask;

		internal Impact? CurrentImpact;

		private Hit? currentHit;

		private Projectile? deferredDestroy;

		private static readonly FieldInfo pointCharacter = AccessTools.Field(typeof(GrapplingPoint), "m_character");

		private static readonly FieldInfo pointEffect = AccessTools.Field(typeof(GrapplingPoint), "m_se");

		private static readonly FieldInfo pointSound = AccessTools.Field(typeof(GrapplingPoint), "m_instanceSound");

		private static readonly FieldInfo leftItemVisual = AccessTools.Field(typeof(VisEquipment), "m_leftItemInstance");

		private Settings C => plugin.Options;

		internal bool Aiming
		{
			get
			{
				if (aimHeld && armed)
				{
					return ValidPlayer();
				}
				return false;
			}
		}

		private bool French
		{
			get
			{
				if (C.Language.Value != "Auto")
				{
					return C.Language.Value == "French";
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "GetSelectedLanguage", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					return string.Equals(methodInfo.Invoke(Localization.instance, null) as string, "French", StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
		}

		internal GrappleSession(Plugin plugin)
		{
			this.plugin = plugin;
			mask = LayerMask.GetMask(new string[12]
			{
				"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
				"character_noenv", "vehicle"
			});
		}

		internal bool IsPlayer(Player p)
		{
			if (Object.op_Implicit((Object)(object)player) && (Object)(object)p == (Object)(object)player)
			{
				return LocalAuthority(p);
			}
			return false;
		}

		private static bool LocalAuthority(Player p)
		{
			ZNetView component = ((Component)p).GetComponent<ZNetView>();
			if ((Object)(object)p == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				return component.IsOwner();
			}
			return false;
		}

		internal bool Controls(Player p)
		{
			if (C.Enabled.Value && !Conflict && LocalAuthority(p))
			{
				return Hook(((Humanoid)p).GetCurrentWeapon());
			}
			return false;
		}

		private static bool Hook(ItemData? item)
		{
			if (Object.op_Implicit((Object)(object)item?.m_dropPrefab) && ((Object)item.m_dropPrefab).name == "GrapplingHook" && Object.op_Implicit((Object)(object)item.m_shared.m_attack.m_attackProjectile))
			{
				Projectile component = item.m_shared.m_attack.m_attackProjectile.GetComponent<Projectile>();
				object obj;
				if (component == null)
				{
					obj = null;
				}
				else
				{
					GameObject spawnOnHit = component.m_spawnOnHit;
					obj = ((spawnOnHit != null) ? spawnOnHit.GetComponent<GrapplingPoint>() : null);
				}
				return Object.op_Implicit((Object)obj);
			}
			return false;
		}

		internal bool Owns(GrapplingPoint p)
		{
			if (Object.op_Implicit((Object)(object)point) && (Object)(object)p == (Object)(object)point && Object.op_Implicit((Object)(object)player))
			{
				return LocalAuthority(player);
			}
			return false;
		}

		private bool AnchorAuthority()
		{
			ZNetView val = (Object.op_Implicit((Object)(object)point) ? ((Component)point).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsValid())
			{
				return val.IsOwner();
			}
			return false;
		}

		private bool ValidPlayer()
		{
			if (Object.op_Implicit((Object)(object)player) && LocalAuthority(player) && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).InIntro() && !((Character)player).IsDebugFlying() && C.Enabled.Value && !Conflict && Hook(((Humanoid)player).GetCurrentWeapon()) && ((Humanoid)player).GetCurrentWeapon() == equipped)
			{
				return ((Humanoid)player).GetInventory().ContainsItem(equipped);
			}
			return false;
		}

		private bool InputAllowed()
		{
			if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)Hud.instance))
			{
				return false;
			}
			PlayerController component = ((Component)player).GetComponent<PlayerController>();
			if (!Object.op_Implicit((Object)(object)component) || PlayerController.HasInputDelay)
			{
				return false;
			}
			if ((bool)AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null).Invoke(component, new object[1] { false }) && !(bool)AccessTools.Method(typeof(PlayerController), "InInventoryEtc", (Type[])null, (Type[])null).Invoke(component, null))
			{
				return !Hud.InRadial();
			}
			return false;
		}

		internal void Tick()
		{
			//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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			ItemData val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetCurrentWeapon() : null);
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Controls(localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InIntro() || ((Character)localPlayer).IsDebugFlying())
			{
				if (player != null)
				{
					Cleanup("player unavailable / unequipped");
				}
				return;
			}
			if ((Object)(object)player != (Object)(object)localPlayer || equipped != val)
			{
				Cleanup("equipment changed");
				player = localPlayer;
				equipped = val;
				nativeDrain = localPlayer.m_grapplingStaminaDrain;
				previousPlayerPosition = ((Component)localPlayer).transform.position;
				armed = false;
				plugin.Trace("equipped vanilla GrapplingHook");
			}
			if (!ValidPlayer())
			{
				Cleanup("invalid player state");
				return;
			}
			if (Vector3.Distance(previousPlayerPosition, ((Component)player).transform.position) > 15f && (State.Attached || State.Pending))
			{
				Cleanup("position discontinuity");
				return;
			}
			previousPlayerPosition = ((Component)player).transform.position;
			if (State.Attached && (!Object.op_Implicit((Object)(object)point) || !Object.op_Implicit((Object)(object)support) || !support.enabled || !((Component)support).gameObject.activeInHierarchy))
			{
				Cleanup("anchor support disappeared");
				return;
			}
			if (State.Pending && (!Object.op_Implicit((Object)(object)flight) || Time.time >= shotDeadline))
			{
				FinishMiss("flight expired");
			}
			if (!reloadLogged && (double)Time.time >= State.ReadyAt)
			{
				reloadLogged = true;
				plugin.Trace("reload ready (flight may still be pending)");
			}
			bool flag = Settings.Held(C.FireAction, C.FireKey, "Attack");
			bool flag2 = Settings.Held(C.ReleaseAction, C.ReleaseKey, "SecondaryAttack");
			bool flag3 = Settings.Held(C.RopeAction, C.RopeKey, "Use");
			bool flag4 = ClimbHeld();
			bool flag5 = Settings.Held(C.AimAction, C.AimKey, "Block");
			if (!InputAllowed())
			{
				fireQueued = false;
				if (State.Attached)
				{
					Suspend(release: true);
				}
				armed = false;
				aimHeld = false;
				fireHeld = flag;
				releaseHeld = flag2;
				ropeHeld = flag3;
				return;
			}
			if (!armed)
			{
				armed = !flag && !flag2 && !flag3 && !flag5 && !flag4;
				fireHeld = flag;
				releaseHeld = flag2;
				ropeHeld = flag3;
				aimHeld = false;
				return;
			}
			aimHeld = flag5;
			switch (RopeRules.Command(flag && !fireHeld, flag2 && !releaseHeld))
			{
			case GrappleCommand.Release:
				fireQueued = false;
				if (State.Attached || State.Pending)
				{
					Release("manual detach");
				}
				break;
			case GrappleCommand.Fire:
				fireQueued = true;
				break;
			}
			ropeHeld = flag3;
			RopeMode mode = State.Mode;
			State.Input(flag3, Time.time, C.Threshold.Value, flag4);
			if (State.Mode == RopeMode.IdentifyingPress && mode != State.Mode && mode != RopeMode.Descending)
			{
				descentGoal = ropeLength;
			}
			if (State.ContinuousDescent)
			{
				descentGoal = anchorRange;
			}
			if (State.DescentRequests != handledDescentRequest && Object.op_Implicit((Object)(object)point))
			{
				handledDescentRequest = State.DescentRequests;
				float num = CurrentDistance();
				float num2 = ((C.StepReference.Value == "MaximumRopeLength") ? anchorRange : ((C.StepReference.Value == "CurrentDistance") ? num : attachmentDistance));
				descentGoal = RopeRules.StepTarget(ropeLength, descentGoal, num2, C.StepFraction.Value, anchorRange);
				plugin.Trace($"rappel step target={descentGoal:F2} reference={num2:F2} fraction={C.StepFraction.Value:F2}");
			}
			if (State.Mode == RopeMode.Suspended && mode != State.Mode)
			{
				descentGoal = ropeLength;
			}
			fireHeld = flag;
			releaseHeld = flag2;
			if (previousMode != State.Mode)
			{
				plugin.Trace("rope state " + State.Mode);
				previousMode = State.Mode;
			}
		}

		internal void AfterCamera()
		{
			if (fireQueued)
			{
				fireQueued = false;
				if (armed && ValidPlayer() && InputAllowed())
				{
					Launch();
				}
			}
		}

		internal bool ConsumesUse(Player p)
		{
			if (IsPlayer(p) && Controls(p) && State.Attached && InputAllowed() && Settings.Held(C.RopeAction, C.RopeKey, "Use"))
			{
				if (!ZInput.GetButton("Use"))
				{
					return ZInput.GetButton("JoyUse");
				}
				return true;
			}
			return false;
		}

		internal void NativeJump(Player p)
		{
			if (IsPlayer(p) && State.Attached)
			{
				lastJumpAt = Time.time;
				State.Suspend(requireRelease: true, preserveClimbPress: true);
			}
		}

		private bool ClimbHeld()
		{
			if (C.JumpHoldClimbs.Value)
			{
				if (!ZInput.GetButton("Jump"))
				{
					return ZInput.GetButton("JoyJump");
				}
				return true;
			}
			return false;
		}

		private void SpawnPoint(Attack attack, out Vector3 origin, out Vector3 direction)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ed: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)player).transform;
			if (!string.IsNullOrEmpty(attack.m_attackOriginJoint))
			{
				Transform val2 = Utils.FindChild(((Character)player).GetVisual().transform, attack.m_attackOriginJoint, (IterativeSearchType)0);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val = val2;
				}
			}
			Transform transform = ((Component)player).transform;
			origin = val.position + transform.up * attack.m_attackHeight + transform.forward * attack.m_attackRange + transform.right * attack.m_attackOffset;
			Vector3 aimDir = ((Humanoid)player).GetAimDir(origin);
			direction = ((Vector3)(ref aimDir)).normalized;
			if (attack.m_launchAngle != 0f)
			{
				direction = Quaternion.AngleAxis(attack.m_launchAngle, Vector3.Cross(Vector3.up, direction)) * direction;
			}
		}

		private float NativeRange(Attack attack, Projectile prefab)
		{
			return Mathf.Min(prefab.m_spawnOnHit.GetComponent<GrapplingPoint>().m_maxLength, (prefab.m_ttl > 0f) ? (attack.m_projectileVel * prefab.m_ttl) : float.MaxValue);
		}

		private void Launch()
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			if (!ValidPlayer() || State.Pending || (double)Time.time < State.ReadyAt || ((Character)player).InAttack() || ((Character)player).InDodge() || ((Character)player).InMinorAction() || ((Character)player).IsAttached() || ((Character)player).IsStaggering() || ((Character)player).IsKnockedBack() || !((Character)player).CanMove() || (equipped.m_shared.m_useDurability && equipped.m_durability <= 0f))
			{
				return;
			}
			if (!((Character)player).HaveStamina(C.ShotCost.Value))
			{
				Hud instance = Hud.instance;
				if (instance != null)
				{
					instance.StaminaBarEmptyFlash();
				}
				return;
			}
			Attack attack = equipped.m_shared.m_attack;
			Projectile component = attack.m_attackProjectile.GetComponent<Projectile>();
			SpawnPoint(attack, out var origin, out var direction);
			float num = component.m_ttl * (aimHeld ? (1f + C.Bonus.Value) : 1f);
			float range = RopeRules.Range(NativeRange(attack, component), C.Bonus.Value, aimHeld);
			float ropeRange = RopeRules.Range(component.m_spawnOnHit.GetComponent<GrapplingPoint>().m_maxLength, C.Bonus.Value, aimHeld);
			GrappleAim.Plan(player, origin, component, attack.m_projectileVel, num, range, ropeRange, mask, out var velocity, out var _);
			direction = ((Vector3)(ref velocity)).normalized;
			if (!State.BeginShot(Time.time, C.Reload.Value, out flightToken))
			{
				return;
			}
			shotOrigin = origin;
			shotRange = range;
			shotRopeMaximum = ropeRange;
			shotDeadline = Time.time + Mathf.Max(num, 0.1f) + 0.2f;
			reloadLogged = false;
			try
			{
				GameObject val = Object.Instantiate<GameObject>(attack.m_attackProjectile, origin, Quaternion.LookRotation(direction));
				flight = val.GetComponent<Projectile>();
				flight.m_ttl = num;
				HitData val2 = new HitData();
				((DamageTypes)(ref val2.m_damage)).Add(equipped.GetDamage(), 1);
				val2.m_toolTier = (short)equipped.m_shared.m_toolTier;
				val2.m_pushForce = equipped.m_shared.m_attackForce * attack.m_forceMultiplier;
				val2.m_backstabBonus = equipped.m_shared.m_backstabBonus;
				val2.m_blockable = equipped.m_shared.m_blockable;
				val2.m_dodgeable = equipped.m_shared.m_dodgeable;
				val2.m_skill = equipped.m_shared.m_skillType;
				val2.m_hitType = (HitType)2;
				val2.SetAttacker((Character)(object)player);
				flight.Setup((Character)(object)player, velocity, attack.m_attackHitNoise, val2, equipped, (ItemData)null);
				((Character)player).UseStamina(C.ShotCost.Value);
				if (equipped.m_shared.m_useDurability)
				{
					equipped.m_durability = Mathf.Max(0f, equipped.m_durability - equipped.m_shared.m_useDurabilityDrain * Game.m_durabilityRate);
				}
				equipped.m_shared.m_triggerEffect.Create(origin, Quaternion.LookRotation(direction), (Transform)null, 1f, -1, ((Character)player).GetZDOID());
				attack.m_triggerEffect.Create(origin, Quaternion.LookRotation(direction), (Transform)null, 1f, -1, ((Character)player).GetZDOID());
				plugin.Trace($"shot token={flightToken} transfer={State.Attached} aimed={aimHeld} range={shotRange:F2} ttl={num:F2}; reload start; readyAt={State.ReadyAt:F3}");
			}
			catch (Exception ex)
			{
				plugin.Warn("Shot aborted: " + ex);
				FinishMiss("launch exception");
			}
		}

		internal bool CheckFlight(Projectile projectile)
		{
			//IL_0039: 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)
			if ((Object)(object)projectile != (Object)(object)flight)
			{
				return true;
			}
			if (!ValidPlayer() || !State.Pending || flightToken != State.Generation || Vector3.Distance(shotOrigin, ((Component)projectile).transform.position) > shotRange || Time.time >= shotDeadline)
			{
				FinishMiss("flight invalid / beyond range");
				return false;
			}
			return true;
		}

		internal bool BeginImpact(Projectile projectile, GameObject go, Collider collider)
		{
			//IL_0031: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)projectile != (Object)(object)flight)
			{
				return true;
			}
			Vector3 val = ((currentHit != null && (Object)(object)currentHit.Projectile == (Object)(object)projectile) ? currentHit.Position : ((Component)projectile).transform.position);
			bool flag = Object.op_Implicit((Object)(object)collider) && Object.op_Implicit((Object)(object)go) && collider.enabled && go.activeInHierarchy && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<Character>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<GrapplingBlocker>()) && projectile.m_spawnOnHit.GetComponent<GrapplingPoint>().CanAttach(go);
			bool flag2 = RopeRules.ValidImpact(flightToken, State.Generation, State.Pending, ValidPlayer(), flag, flag, Vector3.Distance(shotOrigin, val), Object.op_Implicit((Object)(object)player) ? Vector3.Distance(((Component)player).transform.position, val) : float.MaxValue, shotRange, shotRopeMaximum);
			if (State.Attached && (!Object.op_Implicit((Object)(object)point) || !AnchorAuthority() || !Object.op_Implicit((Object)(object)support) || !support.enabled || !((Component)support).gameObject.activeInHierarchy))
			{
				flag2 = false;
			}
			if (!flag2)
			{
				FinishMiss("impact rejected");
				return false;
			}
			CurrentImpact = new Impact
			{
				Support = collider,
				Token = flightToken,
				Position = val,
				Normal = (currentHit?.Normal ?? Vector3.up)
			};
			return true;
		}

		internal void EndImpact(Impact? previous)
		{
			if (CurrentImpact != previous && CurrentImpact != null && !CurrentImpact.Activated)
			{
				RollbackActivation();
				FinishMiss("no native anchor committed");
			}
			CurrentImpact = previous;
		}

		internal Hit? BeginHit(Projectile projectile, Vector3 hitPoint, Vector3 normal)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			Hit? result = currentHit;
			if ((Object)(object)projectile == (Object)(object)flight)
			{
				currentHit = new Hit
				{
					Projectile = projectile,
					Position = hitPoint,
					Normal = normal
				};
			}
			return result;
		}

		internal void EndHit(Hit? previous)
		{
			if (currentHit != previous && currentHit != null && (Object)(object)currentHit.Projectile == (Object)(object)flight && (bool)AccessTools.Field(typeof(Projectile), "m_didHit").GetValue(flight))
			{
				FinishMiss("impact without valid anchor");
			}
			currentHit = previous;
			if (currentHit == null && Object.op_Implicit((Object)(object)deferredDestroy))
			{
				DestroyNetwork(((Component)deferredDestroy).gameObject);
				deferredDestroy = null;
			}
		}

		internal bool BeforeActivate(GrapplingPoint next, Character character)
		{
			//IL_008d: 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_00a7: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character != (Object)(object)player || CurrentImpact == null)
			{
				return true;
			}
			if (CurrentImpact.Accepted || CurrentImpact.Token != State.Generation || !State.Pending || !ValidPlayer())
			{
				DestroyNetwork(((Component)next).gameObject);
				return false;
			}
			CurrentImpact.PreviousLocal = GrapplingPoint.m_localGrappler;
			CurrentImpact.Candidate = next;
			GrapplingPoint.m_localGrappler = null;
			((Component)next).transform.position = CurrentImpact.Position + ((Vector3)(ref CurrentImpact.Normal)).normalized * 0.025f;
			next.Method = (GrapplingMethod)1;
			next.m_FOVTarget = 0f;
			next.m_maxLength = shotRopeMaximum;
			next.m_secondary = true;
			CurrentImpact.Accepted = true;
			return true;
		}

		internal void AfterActivate(GrapplingPoint next, Character character)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character != (Object)(object)player || CurrentImpact == null || !CurrentImpact.Accepted || !Object.op_Implicit((Object)(object)next) || (Object)/*isinst with value type is only supported in some contexts*/ != (Object)(object)player)
			{
				return;
			}
			if (!AnchorOwned(next))
			{
				RollbackActivation();
				return;
			}
			Collider val = CurrentImpact.Support;
			if (!Object.op_Implicit((Object)(object)val) || !val.enabled || !((Component)val).gameObject.activeInHierarchy)
			{
				RollbackActivation();
				return;
			}
			object? value = pointEffect.GetValue(next);
			SE_Stats val2 = (SE_Stats)((value is SE_Stats) ? value : null);
			Vector3 val3 = ((Component)val).transform.InverseTransformPoint(((Component)next).transform.position);
			if (!State.Complete(CurrentImpact.Token, success: true, ropeHeld, ClimbHeld()))
			{
				RollbackActivation();
				return;
			}
			GrapplingPoint val4 = point;
			bool num = !Object.op_Implicit((Object)(object)val4) && ((Character)player).IsOnGround();
			point = next;
			attachedEffect = val2;
			support = val;
			supportOffset = val3;
			anchorRange = shotRopeMaximum;
			CurrentImpact.Activated = true;
			ropePath.Clear();
			if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val4 != (Object)(object)next)
			{
				DestroyNetwork(((Component)val4).gameObject);
			}
			next.m_rotateCharacter = false;
			next.m_secondary = true;
			((Character)player).GetZAnim().SetBool("grappling", false);
			((Character)player).GetZAnim().SetBool("repell", false);
			object? value2 = pointSound.GetValue(next);
			GameObject val5 = (GameObject)((value2 is GameObject) ? value2 : null);
			if (Object.op_Implicit((Object)(object)val5))
			{
				Object.Destroy((Object)(object)val5);
				pointSound.SetValue(next, null);
			}
			player.m_grapplingStaminaDrain = 0f;
			InitializeRopeLength();
			attachmentDistance = Vector3.Distance(((Component)player).transform.position, ((Component)next).transform.position);
			descentGoal = CurrentDistance();
			handledDescentRequest = State.DescentRequests;
			if (num)
			{
				departureAssist.GroundAttachment();
			}
			flight = null;
			plugin.Trace($"attached token={CurrentImpact.Token} length={ropeLength:F2} maximum={anchorRange:F2}");
		}

		private static bool AnchorOwned(GrapplingPoint p)
		{
			ZNetView component = ((Component)p).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				return component.IsOwner();
			}
			return false;
		}

		private void RollbackActivation()
		{
			if (CurrentImpact == null || CurrentImpact.Activated || !CurrentImpact.Accepted)
			{
				return;
			}
			GrapplingPoint.m_localGrappler = CurrentImpact.PreviousLocal;
			if (Object.op_Implicit((Object)(object)CurrentImpact.Candidate))
			{
				object? value = pointEffect.GetValue(CurrentImpact.Candidate);
				SE_Stats val = (SE_Stats)((value is SE_Stats) ? value : null);
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)attachedEffect && Object.op_Implicit((Object)(object)player))
				{
					((Character)player).GetSEMan().RemoveStatusEffect(((StatusEffect)val).NameHash(), false);
				}
				DestroyNetwork(((Component)CurrentImpact.Candidate).gameObject);
			}
			if (Object.op_Implicit((Object)(object)player))
			{
				player.m_grappling = (State.Attached ? 0.2f : 0f);
				((Character)player).GetZAnim().SetBool("grappling", false);
				((Character)player).GetZAnim().SetBool("repell", false);
			}
		}

		internal Exception? ActivationFailed(GrapplingPoint candidate, Exception? error)
		{
			if (error == null || CurrentImpact == null || (Object)(object)CurrentImpact.Candidate != (Object)(object)candidate || CurrentImpact.Activated)
			{
				return error;
			}
			plugin.Warn("Anchor activation failed; previous anchor retained: " + error);
			RollbackActivation();
			FinishMiss("activation failed");
			return null;
		}

		internal void UpdatePoint(GrapplingPoint p)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			if (!ValidPlayer() || !AnchorAuthority() || !Object.op_Implicit((Object)(object)support) || !support.enabled || !((Component)support).gameObject.activeInHierarchy)
			{
				Cleanup("point lifecycle invalid");
				return;
			}
			((Component)p).transform.position = ((Component)support).transform.TransformPoint(supportOffset);
			player.m_grappling = 0.2f;
			ropePath.Update(((Character)player).GetCenterPoint(), ((Component)p).transform.position, support, player, mask, out var _);
		}

		internal void UpdateRopeVisual()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (State.Attached && Object.op_Implicit((Object)(object)point) && Object.op_Implicit((Object)(object)player) && ValidPlayer() && AnchorAuthority() && Object.op_Implicit((Object)(object)support))
			{
				LineRenderer component = ((Component)point).GetComponent<LineRenderer>();
				if (Object.op_Implicit((Object)(object)component) && ((Renderer)component).enabled)
				{
					Vector3 anchor = ((Component)point).transform.position + ((Component)point).transform.rotation * point.m_attachOffsetProjectile;
					ropePath.Draw(component, anchor, RopeOutlet(point));
				}
			}
		}

		private Vector3 RopeOutlet(GrapplingPoint p)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment();
			GameObject val = (GameObject)(Object.op_Implicit((Object)(object)visEquipment) ? /*isinst with value type is only supported in some contexts*/: null);
			if (Object.op_Implicit((Object)(object)val))
			{
				return val.transform.TransformPoint(p.m_attachOffsetHand);
			}
			if (Object.op_Implicit((Object)(object)p.m_attachPoint))
			{
				return p.m_attachPoint.position + p.m_attachPoint.rotation * p.m_attachOffsetHand;
			}
			return ((Character)player).GetCenterPoint();
		}

		private void InitializeRopeLength()
		{
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)point))
			{
				ropeLength = Mathf.Min(anchorRange, CurrentDistance());
			}
		}

		private float CurrentDistance()
		{
			//IL_0039: 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)
			if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)point) || !Object.op_Implicit((Object)(object)support))
			{
				return 0f;
			}
			Vector3 pivot;
			return ropePath.Update(((Character)player).GetCenterPoint(), ((Component)point).transform.position, support, player, mask, out pivot);
		}

		private void Suspend(bool release = false)
		{
			State.Suspend(release);
		}

		internal void PhysicsTick(float dt)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0651: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f4: 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_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: 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_0731: Unknown result type (might be due to invalid IL or missing references)
			//IL_0733: Unknown result type (might be due to invalid IL or missing references)
			//IL_0735: Unknown result type (might be due to invalid IL or missing references)
			//IL_073c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0741: Unknown result type (might be due to invalid IL or missing references)
			//IL_0746: Unknown result type (might be due to invalid IL or missing references)
			//IL_074a: 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_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			if (!State.Attached || !Object.op_Implicit((Object)(object)point) || !Object.op_Implicit((Object)(object)player))
			{
				return;
			}
			if (!ValidPlayer() || !AnchorAuthority() || !Object.op_Implicit((Object)(object)support) || !support.enabled || !((Component)support).gameObject.activeInHierarchy)
			{
				Cleanup("physics lifecycle invalid");
			}
			else
			{
				if (dt <= 0f)
				{
					return;
				}
				((Component)point).transform.position = ((Component)support).transform.TransformPoint(supportOffset);
				Vector3 pivot;
				float num = ropePath.Update(((Character)player).GetCenterPoint(), ((Component)point).transform.position, support, player, mask, out pivot);
				Vector3 val = pivot - ((Character)player).GetCenterPoint();
				float magnitude = ((Vector3)(ref val)).magnitude;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
				if (!Object.op_Implicit((Object)(object)component) || component.isKinematic)
				{
					return;
				}
				Vector3 velocity = component.linearVelocity;
				bool flag = ((Character)player).IsOnGround();
				if (flag)
				{
					lastGroundedAt = Time.time;
				}
				bool recentGround = flag || Time.time - lastGroundedAt < 1.2f || Time.time - lastJumpAt < 1.2f;
				bool flag2 = InputAllowed() && armed && !((Character)player).InDodge() && !((Character)player).IsStaggering() && !((Character)player).IsKnockedBack() && !((Character)player).IsEncumbered() && ((Character)player).CanMove() && ((Character)player).HaveStamina(C.ClimbCost.Value * dt);
				bool eligible = flag2 && magnitude > C.Stop.Value + 0.5f && normalized.y > 0.15f;
				AssistKind assistKind = departureAssist.Sample(Time.time, ClimbHeld(), State.Mode == RopeMode.Ascending, recentGround, eligible);
				if (assistKind != AssistKind.None)
				{
					float num2 = ((assistKind == AssistKind.GroundStart) ? C.GroundAssist.Value : C.JumpAssist.Value);
					Vector3 val2 = normalized * RopePhysics.AssistSpeed(Vector3.Dot(velocity, normalized), num2);
					if (flag && num2 > 0f && ((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
					{
						val2.y = Mathf.Max(val2.y, Mathf.Min(num2, Mathf.Max(0f, 3.5f - velocity.y)));
						float num3 = ((Vector3)(ref val2)).magnitude * dt + 0.1f;
						RaycastHit val3 = default(RaycastHit);
						if (((Vector3)(ref val2)).sqrMagnitude > 0f && !component.SweepTest(((Vector3)(ref val2)).normalized, ref val3, num3, (QueryTriggerInteraction)1))
						{
							velocity += val2;
							((Character)player).ForceJump(velocity, false);
						}
					}
					else if (num2 > 0f)
					{
						component.AddForce(val2, (ForceMode)2);
						velocity += val2;
					}
				}
				AccessTools.Field(typeof(Character), "m_maxAirAltitude").SetValue(player, ((Component)player).transform.position.y);
				if (State.Mode == RopeMode.Ascending)
				{
					float num4 = C.ClimbCost.Value * dt;
					float stop = Mathf.Max(0f, num - magnitude) + C.Stop.Value;
					float num5 = Mathf.Min(C.Climb.Value * dt + 0.1f, Mathf.Max(0f, magnitude - C.Stop.Value));
					RaycastHit val4 = default(RaycastHit);
					bool flag3 = num5 > 0f && component.SweepTest(normalized, ref val4, num5, (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<Player>() != (Object)(object)player;
					if ((assistKind == AssistKind.None && flag2 && TryClearLedge(component, pivot, magnitude, ref velocity)) || magnitude <= C.Stop.Value || !((Character)player).HaveStamina(num4))
					{
						Suspend(ropeHeld);
					}
					else
					{
						if (flag3)
						{
							Vector3 val5 = Vector3.ProjectOnPlane(normalized, ((RaycastHit)(ref val4)).normal);
							Vector3 normalized2 = ((Vector3)(ref val5)).normalized;
							if (normalized2.y > 0.1f)
							{
								float num6 = RopePhysics.ChaseSpeed(Vector3.Dot(velocity, normalized2), Mathf.Min(6f, C.Climb.Value), C.PullAcceleration.Value, dt);
								component.AddForce(normalized2 * num6, (ForceMode)2);
								velocity += normalized2 * num6;
							}
						}
						else
						{
							ropeLength = Mathf.Min(ropeLength, num);
							float num7 = RopePhysics.ReelIn(ropeLength, num, Vector3.Dot(velocity, normalized), C.Climb.Value, C.PullAcceleration.Value, stop, dt);
							ropeLength = Mathf.Min(ropeLength, num7);
						}
						((Character)player).UseStamina(num4);
					}
				}
				else if (State.Mode == RopeMode.Descending)
				{
					float num8 = C.DescendCost.Value * dt;
					float num9 = (State.ContinuousDescent ? anchorRange : descentGoal);
					if (((Character)player).IsOnGround() || ropeLength >= num9 - 0.005f || !((Character)player).HaveStamina(num8))
					{
						Suspend(ropeHeld);
					}
					else
					{
						ropeLength = RopeRules.Payout(ropeLength, num9, C.Descend.Value, dt);
						((Character)player).UseStamina(num8);
					}
				}
				Vector3 val6 = velocity + Physics.gravity * dt;
				float num10 = 0f - Vector3.Dot(val6, normalized);
				float predictedTangentSquared = Mathf.Max(0f, ((Vector3)(ref val6)).sqrMagnitude - num10 * num10);
				float num11 = Mathf.Max(0f, num - magnitude);
				float num12 = Mathf.Max(0.05f, ropeLength - num11);
				float acceleration = ((State.Mode == RopeMode.Ascending) ? C.PullAcceleration.Value : C.Acceleration.Value);
				float num13 = RopePhysics.Tension(magnitude, num12, num10, predictedTangentSquared, dt, acceleration);
				if (num13 > 0f && magnitude > 0.0001f)
				{
					component.AddForce(normalized * num13, (ForceMode)2);
				}
				if (C.Damping.Value > 0f && State.Mode == RopeMode.Suspended && magnitude >= num12 - 0.02f)
				{
					Vector3 val7 = velocity - normalized * Vector3.Dot(velocity, normalized);
					component.AddForce(-val7 * C.Damping.Value, (ForceMode)5);
				}
				if (!C.Regen.Value)
				{
					AccessTools.Field(typeof(Player), "m_staminaRegenTimer").SetValue(player, 1f);
				}
			}
		}

		private bool TryClearLedge(Rigidbody body, Vector3 pivot, float distance, ref Vector3 velocity)
		{
			//IL_0052: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00ac: 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_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_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_0116: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: 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_02d3: 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_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			if (!C.LedgeAssist.Value || distance > C.Stop.Value + 1f || !ClimbHeld() || !((Character)player).HaveStamina(C.ShotCost.Value))
			{
				return false;
			}
			Vector3 val = Vector3.ProjectOnPlane(pivot - ((Component)player).transform.position, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				return false;
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float height = ((Character)player).GetHeight();
			float radius = ((Character)player).GetRadius();
			RaycastHit val2 = default(RaycastHit);
			foreach (RaycastHit item in from h in Physics.RaycastAll(pivot + normalized * (radius + 0.25f) + Vector3.up * (height + 0.5f), Vector3.down, height + 1f, mask, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Character>()))
				{
					if (((RaycastHit)(ref current)).normal.y < 0.5f)
					{
						return false;
					}
					float num = ((RaycastHit)(ref current)).point.y - ((Component)player).transform.position.y;
					float num2 = RopePhysics.LedgeLift(num, Physics.gravity.y);
					if (num2 <= 0f)
					{
						return false;
					}
					if (body.SweepTest(Vector3.up, ref val2, num + 0.15f, (QueryTriggerInteraction)1))
					{
						return false;
					}
					Vector3 val3 = ((RaycastHit)(ref current)).point + Vector3.up * 0.08f;
					Vector3 val4 = val3 + Vector3.up * radius;
					Vector3 val5 = val3 + Vector3.up * Mathf.Max(radius, height - radius);
					if (Physics.OverlapCapsule(val4, val5, radius * 0.95f, mask, (QueryTriggerInteraction)1).Any((Collider c) => (Object)(object)((Component)c).GetComponentInParent<Player>() != (Object)(object)player))
					{
						return false;
					}
					Vector3 val6 = val3 - ((Component)player).transform.position;
					float num3 = Mathf.Max(0.15f, num2 / Mathf.Max(0.1f, 0f - Physics.gravity.y));
					Vector3 val7 = Vector3.ProjectOnPlane(val6, Vector3.up);
					float num4 = Mathf.Min(6f, ((Vector3)(ref val7)).magnitude / num3);
					if (!departureAssist.TryLedge(Time.time))
					{
						return false;
					}
					velocity += Vector3.up * Mathf.Max(0f, num2 - velocity.y) + normalized * Mathf.Max(0f, num4 - Vector3.Dot(velocity, normalized));
					((Character)player).UseStamina(C.ShotCost.Value);
					((Character)player).ForceJump(velocity, false);
					plugin.Trace($"ledge clearance rise={num:F2} lift={num2:F2}; anchor retained");
					return true;
				}
			}
			return false;
		}

		internal void UpdateAimPose()
		{
			bool flag = Aiming && Object.op_Implicit((Object)(object)player) && !((Character)player).InAttack() && !((Character)player).InDodge() && !((Character)player).InMinorAction() && !((Character)player).IsStaggering();
			aimWeight = Mathf.MoveTowards(aimWeight, (float)(flag ? 1 : 0), Time.deltaTime / 0.16f);
			if (!flag)
			{
				RestoreAimPose();
				return;
			}
			if (!Object.op_Implicit((Object)(object)aimAnimator))
			{
				aimAnimator = ((Component)player).GetComponentInChildren<Animator>();
			}
			if (Object.op_Implicit((Object)(object)aimAnimator) && aimAnimator.isHuman)
			{
				if (!ownsAimPose)
				{
					savedAimBool = aimAnimator.GetBool("blocking");
					ownsAimPose = true;
				}
				((Character)player).GetZAnim().SetBool("blocking", true);
				CalibrateAimVisual();
				AlignAimVisual();
			}
		}

		private Quaternion AimFrame(Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_005f: 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_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)
			Vector3 val = Vector3.Cross(Vector3.up, direction);
			Vector3 val2 = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = ((Component)player).transform.right;
			}
			val = Vector3.Cross(direction, val2);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Quaternion.LookRotation(direction, normalized) * Quaternion.AngleAxis(C.AimRoll.Value, Vector3.forward);
		}

		private void AlignAimVisual()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (Aiming && aimCalibrated && Object.op_Implicit((Object)(object)aimWeaponVisual))
			{
				Transform? obj = aimWeaponVisual;
				Ray val = GrappleAim.ReticleRay(player);
				obj.rotation = AimFrame(((Ray)(ref val)).direction) * Quaternion.Inverse(weaponToBarrel);
			}
		}

		private bool CalibrateAimVisual()
		{
			//IL_0076: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0119: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment();
			GameObject val = (GameObject)(Object.op_Implicit((Object)(object)visEquipment) ? /*isinst with value type is only supported in some contexts*/: null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if ((Object)(object)aimWeaponVisual != (Object)(object)val.transform)
			{
				if (Object.op_Implicit((Object)(object)aimWeaponVisual))
				{
					aimWeaponVisual.localRotation = savedWeaponRotation;
				}
				aimWeaponVisual = val.transform;
				savedWeaponRotation = aimWeaponVisual.localRotation;
				aimCalibrated = false;
			}
			if (aimCalibrated)
			{
				return true;
			}
			Transform val2 = aimWeaponVisual.Find("Loaded");
			Animator componentInChildren = ((Component)player).GetComponentInChildren<Animator>();
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)componentInChildren) || !componentInChildren.isHuman)
			{
				return false;
			}
			Transform boneTransform = componentInChildren.GetBoneTransform((HumanBodyBones)17);
			Transform boneTransform2 = componentInChildren.GetBoneTransform((HumanBodyBones)18);
			if (!Object.op_Implicit((Object)(object)boneTransform) || !Object.op_Implicit((Object)(object)boneTransform2))
			{
				return false;
			}
			weaponToBarrel = Quaternion.Inverse(aimWeaponVisual.rotation) * val2.rotation;
			wristToWeapon = Quaternion.Inverse(boneTransform.rotation) * aimWeaponVisual.rotation;
			rightWristToWeapon = Quaternion.Inverse(boneTransform2.rotation) * aimWeaponVisual.rotation;
			aimCalibrated = true;
			return true;
		}

		internal void ApplyAimIK(CharacterAnimEvent animation, int layer)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			Animator component = ((Component)animation).GetComponent<Animator>();
			if (layer != 0 || !Object.op_Implicit((Object)(object)component) || !component.isHuman)
			{
				return;
			}
			bool flag = Aiming && Object.op_Implicit((Object)(object)player) && ValidPlayer() && (Object)(object)((Component)animation).GetComponentInParent<Player>() == (Object)(object)player;
			if ((Object)(object)ikAnimator == (Object)(object)component && (aimWeight <= 0f || !flag))
			{
				component.SetIKPositionWeight((AvatarIKGoal)3, 0f);
				component.SetIKRotationWeight((AvatarIKGoal)3, 0f);
				component.SetIKPositionWeight((AvatarIKGoal)2, 0f);
				component.SetIKRotationWeight((AvatarIKGoal)2, 0f);
				ikAnimator = null;
			}
			if (!flag || aimWeight <= 0f)
			{
				return;
			}
			Transform boneTransform = component.GetBoneTransform((HumanBodyBones)14);
			Transform boneTransform2 = component.GetBoneTransform((HumanBodyBones)17);
			Transform boneTransform3 = component.GetBoneTransform((HumanBodyBones)18);
			if (Object.op_Implicit((Object)(object)boneTransform) && Object.op_Implicit((Object)(object)boneTransform2) && Object.op_Implicit((Object)(object)boneTransform3))
			{
				ikAnimator = component;
				Ray val = GrappleAim.ReticleRay(player);
				Vector3 direction = ((Ray)(ref val)).direction;
				Vector3 val2 = Vector3.Cross(Vector3.up, direction);
				Vector3 val3 = ((Vector3)(ref val2)).normalized;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
				{
					val3 = ((Component)player).transform.right;
				}
				val2 = Vector3.Cross(direction, val3);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (CalibrateAimVisual())
				{
					Quaternion val4 = AimFrame(direction) * Quaternion.Inverse(weaponToBarrel);
					Quaternion val5 = val4 * Quaternion.Inverse(wristToWeapon);
					Vector3 val6 = boneTransform.position - normalized * 0.06f - val3 * 0.04f;
					component.SetIKPositionWeight((AvatarIKGoal)3, aimWeight);
					component.SetIKRotationWeight((AvatarIKGoal)3, aimWeight);
					component.SetIKPosition((AvatarIKGoal)3, val6 + direction * 0.22f);
					component.SetIKRotation((AvatarIKGoal)3, val4 * Quaternion.Inverse(rightWristToWeapon));
					component.SetIKPositionWeight((AvatarIKGoal)2, aimWeight);
					component.SetIKRotationWeight((AvatarIKGoal)2, aimWeight);
					component.SetIKPosition((AvatarIKGoal)2, val6 + direction * 0.55f - val3 * 0.12f - normalized * 0.06f);
					component.SetIKRotation((AvatarIKGoal)2, val5);
					component.SetLookAtWeight(aimWeight, 0.25f, 0.8f, 0f, 0.6f);
					component.SetLookAtPosition(val6 + direction * 20f);
				}
			}
		}

		private void RestoreAimPose()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)aimWeaponVisual))
			{
				aimWeaponVisual.localRotation = savedWeaponRotation;
			}
			aimWeaponVisual = null;
			aimCalibrated = false;
			if (ownsAimPose && Object.op_Implicit((Object)(object)player) && LocalAuthority(player))
			{
				((Character)player).GetZAnim().SetBool("blocking", Controls(player) ? savedAimBool : ((Character)player).IsBlocking());
			}
			ownsAimPose = false;
			aimAnimator = null;
		}

		private void FinishMiss(string reason)
		{
			State.Complete(flightToken, success: false, ropeHeld);
			if (Object.op_Implicit((Object)(object)flight))
			{
				if (currentHit != null)
				{
					deferredDestroy = flight;
				}
				else
				{
					DestroyNetwork(((Component)flight).gameObject);
				}
			}
			flight = null;
			plugin.Trace(reason + "; previous anchor preserved");
		}

		private void BreakPoint()
		{
			GrapplingPoint val = point;
			point = null;
			support = null;
			ropePath.Clear();
			RemoveAttachedEffect();
			if (Object.op_Implicit((Object)(object)val))
			{
				val.Break(true);
				if (Object.op_Implicit((Object)(object)val))
				{
					DestroyNetwork(((Component)val).gameObject);
				}
				if ((Object)(object)GrapplingPoint.m_localGrappler == (Object)(object)val)
				{
					GrapplingPoint.m_localGrappler = null;
				}
			}
		}

		private void RemoveAttachedEffect()
		{
			if (Object.op_Implicit((Object)(object)attachedEffect) && Object.op_Implicit((Object)(object)player))
			{
				((Character)player).GetSEMan().RemoveStatusEffect(((StatusEffect)attachedEffect).NameHash(), false);
			}
			attachedEffect = null;
		}

		internal void PointBroken(GrapplingPoint p)
		{
			if (!((Object)(object)p != (Object)(object)point))
			{
				RemoveAttachedEffect();
				if ((Object)(object)GrapplingPoint.m_localGrappler == (Object)(object)p)
				{
					GrapplingPoint.m_localGrappler = null;
				}
				point = null;
				support = null;
				Release("native point broken");
			}
		}

		internal bool AllowNativeBreak(GrapplingPoint p)
		{
			if (!Owns(p) || !ValidPlayer() || !AnchorAuthority() || !Object.op_Implicit((Object)(object)support) || !support.enabled || !((Component)support).gameObject.activeInHierarchy)
			{
				return true;
			}
			return false;
		}

		private void Release(string reason)
		{
			fireQueued = false;
			State.Detach();
			departureAssist.Clear();
			if (Object.op_Implicit((Object)(object)flight))
			{
				if (currentHit != null)
				{
					deferredDestroy = flight;
				}
				else
				{
					DestroyNetwork(((Component)flight).gameObject);
				}
			}
			flight = null;
			BreakPoint();
			if (Object.op_Implicit((Object)(object)player))
			{
				player.m_grapplingStaminaDrain = nativeDrain;
				player.m_grappling = 0f;
			}
			plugin.Trace("released: " + reason);
		}

		internal void Cleanup(string reason)
		{
			if (cleaning)
			{
				return;
			}
			cleaning = true;
			try
			{
				RestoreAimPose();
				aimWeight = 0f;
				fireQueued = false;
				Release(reason);
				player = null;
				equipped = null;
				armed = false;
				aimHeld = false;
				CurrentImpact = null;
			}
			finally
			{
				cleaning = false;
			}
		}

		private static void DestroyNetwork(GameObject obj)
		{
			if (Object.op_Implicit((Object)(object)obj))
			{
				ZNetView component = obj.GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)ZNetScene.instance) && Object.op_Implicit((Object)(object)component) && component.IsValid() && component.IsOwner())
				{
					ZNetScene.instance.Destroy(obj);
				}
				else
				{
					Object.Destroy((Object)(object)obj);
				}
			}
		}

		private string Text(string english, string french)
		{
			if (!French)
			{
				return english;
			}
			return french;
		}

		internal void Draw()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0083: Expected O, but got Unknown
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player) || !ValidPlayer() || !InputAllowed() || !armed || !RopeRules.ShowStatus(aimHeld, State.Attached, State.Pending, (double)Time.time < State.ReadyAt))
			{
				return;
			}
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 16,
				wordWrap = true
			};
			string text = ((State.Mode == RopeMode.Ascending) ? Text("Ascending", "Montée") : ((State.Mode == RopeMode.Descending) ? Text("Descending", "Descente") : (State.Attached ? Text("Attached", "Accroché") : (State.Pending ? Text("In flight", "En vol") : Text("Reloading", "Recharge")))));
			if (State.Pending && State.Attached)
			{
				text += Text(" · Transfer in flight", " · Transfert en vol");
			}
			if (aimHeld)
			{
				Attack attack = equipped.m_shared.m_attack;
				Projectile component = attack.m_attackProjectile.GetComponent<Projectile>();
				SpawnPoint(attack, out var origin, out var _);
				float range = RopeRules.Range(NativeRange(attack, component), C.Bonus.Value, aimed: true);
				float ropeRange = RopeRules.Range(component.m_spawnOnHit.GetComponent<GrapplingPoint>().m_maxLength, C.Bonus.Value, aimed: true);
				Vector3 velocity;
				float distance;
				bool flag = GrappleAim.Plan(player, origin, component, attack.m_projectileVel, component.m_ttl * (1f + C.Bonus.Value), range, ropeRange, mask, out velocity, out distance);
				val.normal.textColor = (flag ? Color.green : Color.red);
				if (!flag)
				{
					return;
				}
				text = $"{distance:F1} m";
			}
			GUI.Label(new Rect((float)Screen.width / 2f - 260f, (float)Screen.height / 2f + 35f, 520f, 55f), text, val);
		}
	}
	[DefaultExecutionOrder(10000)]
	[BepInPlugin("Zephyrfit.Grappling", "Zephyrfit Grappling TEST", "0.1.8")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "Zephyrfit.Grappling";

		internal static Plugin Instance;

		internal Settings Options;

		internal GrappleSession Session;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			Instance = this;
			Options = new Settings(((BaseUnityPlugin)this).Config);
			Session = new GrappleSession(this);
			harmony = new Harmony("Zephyrfit.Grappling");
			try
			{
				harmony.PatchAll(typeof(Plugin).Assembly);
			}
			catch (Exception ex)
			{
				harmony.UnpatchSelf();
				Options.Enabled.Value = false;
				((BaseUnityPlugin)this).Logger.LogError((object)("Grappling disabled: installed game API could not be patched. " + ex));
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Zephyrfit Grappling TEST 0.1.8; game " + Version.GetVersionString(false) + "; Unity " + Application.unityVersion));
			((MonoBehaviour)this).Invoke("AuditPatches", 5f);
		}

		private void Update()
		{
			Session.Tick();
		}

		private void LateUpdate()
		{
			Session.UpdateAimPose();
			Session.UpdateRopeVisual();
		}

		private void OnGUI()
		{
			Session.Draw();
		}

		private void OnDestroy()
		{
			Session?.Cleanup("plugin unloaded");
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		internal void Trace(string message)
		{
			if (Options.Diagnostics.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"t={Time.time:F3} {message}");
			}
		}

		internal void Warn(string message)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)message);
		}

		private void AuditPatches()
		{
			MethodBase[] array = Harmony.GetAllPatchedMethods().ToArray();
			foreach (MethodBase methodBase in array)
			{
				if (!(methodBase.DeclaringType != typeof(GrapplingPoint)) || (methodBase.DeclaringType == typeof(Player) && (methodBase.Name == "SetControls" || methodBase.Name == "UpdateStats")) || (methodBase.DeclaringType == typeof(Character) && methodBase.Name == "UpdateMotion"))
				{
					string[] array2 = Harmony.GetPatchInfo(methodBase).Owners.Where((string x) => x != "Zephyrfit.Grappling").ToArray();
					if (array2.Length != 0)
					{
						Warn("Other Harmony patches on " + methodBase.DeclaringType.Name + "." + methodBase.Name + ": " + string.Join(", ", array2));
					}
					else
					{
						Trace("patch audit " + methodBase.DeclaringType.Name + "." + methodBase.Name + ": no other owners");
					}
				}
			}
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				string text = value.Metadata.Name + " " + value.Metadata.GUID;
				if (value.Metadata.GUID != "Zephyrfit.Grappling" && (text.IndexOf("grappl", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("momentum", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					Warn("Conflicting grappling plugin detected; grappling controls disabled: " + text);
					Session.Conflict = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetControls")]
	internal static class ControlsPatch
	{
		private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold)
		{
			if (Plugin.Instance.Session.Controls(__instance))
			{
				AccessTools.Field(typeof(Character), "m_blocking").SetValue(__instance, false);
				attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = false)))));
			}
		}
	}
	[HarmonyPatch(typeof(Player), "QueueReloadAction")]
	internal static class ReloadPatch
	{
		private static bool Prefix(Player __instance)
		{
			return !Plugin.Instance.Session.Controls(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "IsWeaponLoaded")]
	internal static class LoadedPatch
	{
		private static bool Prefix(Player __instance, ref bool __result)
		{
			GrappleSession session = Plugin.Instance.Session;
			if (!session.Controls(__instance))
			{
				return true;
			}
			__result = session.State.Shot(Time.time) == ShotMode.Ready;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "AlwaysRotateCamera")]
	internal static class AimRotationPatch
	{
		private static void Postfix(Player __instance, ref bool __result)
		{
			if (Plugin.Instance.Session.IsPlayer(__instance) && Plugin.Instance.Session.Aiming)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(GrapplingPoint), "Update")]
	internal static class PointUpdatePatch
	{
		private static bool Prefix(GrapplingPoint __instance)
		{
			GrappleSession session = Plugin.Instance.Session;
			if (!session.Owns(__instance))
			{
				return true;
			}
			session.UpdatePoint(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateMotion")]
	internal static class MotionPatch
	{
		private static void Postfix(Character __instance, float dt)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				Plugin.Instance.Session.PhysicsTick(dt);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })]
	internal static class StatsPatch
	{
		private static void Prefix(Player __instance)
		{
			GrappleSession session = Plugin.Instance.Session;
			if (session.IsPlayer(__instance) && session.State.Attached && !Plugin.Instance.Options.Regen.Value)
			{
				AccessTools.Field(typeof(Player), "m_staminaRegenTimer").SetValue(__instance, 1f);
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "FixedUpdate")]
	internal static class ProjectileTickPatch
	{
		private static bool Prefix(Projectile __instance)
		{
			return Plugin.Instance.Session.CheckFlight(__instance);
		}
	}
	[HarmonyPatch(typeof(Projectile), "SpawnOnHit")]
	internal static class ImpactPatch
	{
		private static bool Prefix(Projectile __instance, GameObject go, Collider collider, out GrappleSession.Impact? __state)
		{
			__state = Plugin.Instance.Session.CurrentImpact;
			return Plugin.Instance.Session.BeginImpact(__instance, go, collider);
		}

		private static Exception? Finalizer(Exception? __exception, GrappleSession.Impact? __state)
		{
			Plugin.Instance.Session.EndImpact(__state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	internal static class HitPatch
	{
		private static void Prefix(Projectile __instance, Vector3 hitPoint, Vector3 normal, out GrappleSession.Hit? __state)
		{
			//IL_000c: 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)
			__state = Plugin.Instance.Session.BeginHit(__instance, hitPoint, normal);
		}

		private static Exception? Finalizer(Exception? __exception, GrappleSession.Hit? __state)
		{
			Plugin.Instance.Session.EndHit(__state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(GrapplingPoint), "Activate")]
	internal static class ActivatePatch
	{
		private static bool Prefix(GrapplingPoint __instance, Character character)
		{
			return Plugin.Instance.Session.BeforeActivate(__instance, character);
		}

		private static void Postfix(GrapplingPoint __instance, Character character)
		{
			Plugin.Instance.Session.AfterActivate(__instance, character);
		}

		private static Exception? Finalizer(GrapplingPoint __instance, Exception? __exception)
		{
			return Plugin.Instance.Session.ActivationFailed(__instance, __exception);
		}
	}
	[HarmonyPatch(typeof(GrapplingPoint), "Break")]
	internal static class BreakPatch
	{
		private static bool Prefix(GrapplingPoint __instance, out bool __state)
		{
			return __state = Plugin.Instance.Session.AllowNativeBreak(__instance);
		}

		private static void Postfix(GrapplingPoint __instance, bool __state)
		{
			if (__state)
			{
				Plugin.Instance.Session.PointBroken(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAnimEvent), "OnAnimatorIK")]
	internal static class AimIKPatch
	{
		private static void Postfix(CharacterAnimEvent __instance, int layerIndex)
		{
			Plugin.Instance.Session.ApplyAimIK(__instance, layerIndex);
		}
	}
	[HarmonyPatch(typeof(GameCamera), "LateUpdate")]
	internal static class CameraShotPatch
	{
		private static void Postfix()
		{
			Plugin.Instance.Session.AfterCamera();
		}
	}
	[HarmonyPatch(typeof(Player), "Interact")]
	internal static class RopeUsePatch
	{
		private static bool Prefix(Player __instance)
		{
			return !Plugin.Instance.Session.ConsumesUse(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "OnJump")]
	internal static class NativeJumpPatch
	{
		private static void Postfix(Player __instance)
		{
			Plugin.Instance.Session.NativeJump(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "TeleportTo")]
	internal static class TeleportPatch
	{
		private static void Prefix(Player __instance)
		{
			if (Plugin.Instance.Session.IsPlayer(__instance))
			{
				Plugin.Instance.Session.Cleanup("teleport started");
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	internal static class DeathPatch
	{
		private static void Prefix(Player __instance)
		{
			if (Plugin.Instance.Session.IsPlayer(__instance))
			{
				Plugin.Instance.Session.Cleanup("death");
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDestroy")]
	internal static class PlayerDestroyPatch
	{
		private static void Prefix(Player __instance)
		{
			if (Plugin.Instance.Session.IsPlayer(__instance))
			{
				Plugin.Instance.Session.Cleanup("player destroyed / di