Decompiled source of Yoink v1.2.0

Yoink.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dragging;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.Vehicles;
using Il2CppScheduleOne.Vehicles.AI;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using S1API.Console;
using S1API.Items;
using S1API.Items.Storable;
using S1API.Shops;
using UnityEngine;
using UnityEngine.Rendering;
using Yoink;
using Yoink.Assets;
using Yoink.Audio;
using Yoink.Config;
using Yoink.Item;
using Yoink.Net;
using Yoink.Rope;
using Yoink.Winch;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Yoink", "1.2.0", "DooDesch", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DooDesch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © DooDesch")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+f18ae14700096635a79997e18016071d2f90a4f5")]
[assembly: AssemblyProduct("Yoink")]
[assembly: AssemblyTitle("Yoink")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class ClipwiseProbe
{
	internal static void Register()
	{
	}
}
namespace Yoink
{
	public sealed class Core : MelonMod
	{
		private bool _inWorld;

		private float _shopRetryAt;

		public static Core Instance { get; private set; }

		public static Instance Log { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			Log = ((MelonBase)this).LoggerInstance;
			Preferences.Initialize();
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll();
			}
			catch (Exception ex)
			{
				Log.Warning("[Core] Harmony patch failed: " + ex.Message);
			}
			try
			{
				QuestRpcPatches.Apply(((MelonBase)this).HarmonyInstance);
				RemotePulls.Install();
			}
			catch (Exception ex2)
			{
				Log.Warning("[Core] co-op bus setup failed - single-player is unaffected: " + ex2.Message);
			}
			Log.Msg("Yoink v1.2.0 - winch.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_inWorld = sceneName == "Main";
			if (!_inWorld)
			{
				WinchSession.Reset();
				WinchItem.ResetSession();
				WinchShop.ResetSession();
				WinchAim.Reset();
				WinchSound.ResetSession();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			_inWorld = false;
			WinchSession.Reset();
			WinchItem.ResetSession();
			WinchShop.ResetSession();
			WinchAim.Reset();
			WinchSound.ResetSession();
		}

		public override void OnUpdate()
		{
			if (_inWorld)
			{
				WinchItem.EnsureRegistered();
				if (Time.time >= _shopRetryAt)
				{
					_shopRetryAt = Time.time + 2f;
					WinchShop.EnsureListed();
				}
				WinchItem.TickControls();
				WinchSession.Tick(Time.deltaTime);
				NpcGrip.Tick();
			}
		}

		public override void OnLateUpdate()
		{
			if (_inWorld)
			{
				WinchSession.LateTick(Time.deltaTime);
				VehicleGrip.TickHeld();
			}
		}

		public override void OnFixedUpdate()
		{
			if (_inWorld)
			{
				WinchSession.FixedTick();
				RemotePulls.FixedTick();
			}
		}
	}
}
namespace Yoink.Winch
{
	internal static class Input
	{
		private static bool _loggedHook;

		private static bool _loggedReel;

		internal static bool HookPressed()
		{
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = GameInput.GetButtonDown((ButtonCode)0);
			}
			catch
			{
			}
			try
			{
				flag2 = Input.GetMouseButtonDown(0);
			}
			catch
			{
			}
			if ((flag || flag2) && !_loggedHook)
			{
				_loggedHook = true;
				Core.Log.Msg("[Input] hook button seen (" + Source(flag, flag2) + ").");
			}
			return flag || flag2;
		}

		internal static bool ReelHeld()
		{
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = GameInput.GetButton((ButtonCode)1);
			}
			catch
			{
			}
			try
			{
				flag2 = Input.GetMouseButton(1);
			}
			catch
			{
			}
			if ((flag || flag2) && !_loggedReel)
			{
				_loggedReel = true;
				Core.Log.Msg("[Input] reel button seen (" + Source(flag, flag2) + ").");
			}
			return flag || flag2;
		}

		private static string Source(bool game, bool raw)
		{
			if (game && raw)
			{
				return "GameInput and raw mouse";
			}
			if (!game)
			{
				return "raw mouse only - the game's input map did not report it";
			}
			return "GameInput";
		}
	}
	internal static class NpcGrip
	{
		private static readonly Dictionary<int, NPC> _held = new Dictionary<int, NPC>();

		internal static int HeldCount => _held.Count;

		internal static bool TryHook(NPC npc, Vector3 hitPoint, Vector3 impactDir, out Rigidbody limb, out int limbIndex, out string reason)
		{
			//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_00d0: Unknown result type (might be due to invalid IL or missing references)
			limb = null;
			limbIndex = -1;
			reason = null;
			if ((Object)(object)npc == (Object)null)
			{
				reason = "nobody there";
				return false;
			}
			if (!Preferences.HookPeople)
			{
				reason = "the hook is set not to bite people (Yoink/HookPeople in MelonPreferences.cfg)";
				return false;
			}
			try
			{
				if (npc.IsInVehicle)
				{
					reason = SafeName(npc) + " is in a vehicle - hook the vehicle instead";
					return false;
				}
			}
			catch
			{
			}
			NPCMovement val = null;
			try
			{
				val = npc.Movement;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				reason = SafeName(npc) + " has no movement component";
				return false;
			}
			try
			{
				if (!((Object)(object)npc.Avatar != (Object)null) || !npc.Avatar.Ragdolled)
				{
					Knock(val, hitPoint, impactDir);
				}
			}
			catch (Exception ex)
			{
				reason = "could not knock " + SafeName(npc) + " down: " + ex.Message;
				return false;
			}
			if (!TryNearestLimb(npc, hitPoint, out limb, out limbIndex))
			{
				reason = SafeName(npc) + " has no ragdoll to hook onto";
				return false;
			}
			Hold(npc);
			return true;
		}

		private static void Knock(NPCMovement move, Vector3 hitPoint, Vector3 impactDir)
		{
			//IL_0017: 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_001c: 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_003f: 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)
			Vector3 val = ((((Vector3)(ref impactDir)).sqrMagnitude > 1E-06f) ? ((Vector3)(ref impactDir)).normalized : Vector3.forward);
			float knockdown = Preferences.Knockdown;
			bool flag = false;
			try
			{
				flag = InstanceFinder.IsServer;
			}
			catch
			{
			}
			if (flag)
			{
				move.ActivateRagdoll_Server(hitPoint, val, knockdown);
			}
			else
			{
				move.RpcLogic___ActivateRagdoll_2690242654(hitPoint, val, knockdown);
			}
		}

		internal static void TryHold(NPC npc, Vector3 hitPoint, Vector3 anchor)
		{
			//IL_003c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)npc == (Object)null)
			{
				return;
			}
			try
			{
				NPCMovement movement = npc.Movement;
				if ((Object)(object)movement == (Object)null)
				{
					return;
				}
				if (!((Object)(object)npc.Avatar != (Object)null) || !npc.Avatar.Ragdolled)
				{
					Knock(movement, hitPoint, hitPoint - anchor);
				}
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Grip] could not knock " + SafeName(npc) + " down: " + ex.Message);
			}
			Hold(npc);
		}

		internal static void Hold(NPC npc)
		{
			if ((Object)(object)npc == (Object)null)
			{
				return;
			}
			try
			{
				_held[((Object)npc).GetInstanceID()] = npc;
			}
			catch
			{
			}
		}

		internal static void Release(NPC npc)
		{
			if ((Object)(object)npc == (Object)null)
			{
				return;
			}
			try
			{
				_held.Remove(((Object)npc).GetInstanceID());
			}
			catch
			{
			}
		}

		internal static void ReleaseAll()
		{
			_held.Clear();
		}

		internal static void Tick()
		{
			if (_held.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, NPC> item in _held)
			{
				NPCMovement val = null;
				try
				{
					val = (((Object)(object)item.Value != (Object)null && (Object)(object)item.Value.Avatar != (Object)null) ? item.Value.Movement : null);
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					(list ?? (list = new List<int>())).Add(item.Key);
					continue;
				}
				try
				{
					val.ragdollStaticTime = 0f;
				}
				catch
				{
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					_held.Remove(list[i]);
				}
			}
		}

		internal static bool IsDown(NPC npc)
		{
			try
			{
				return (Object)(object)npc != (Object)null && (Object)(object)npc.Avatar != (Object)null && npc.Avatar.Ragdolled;
			}
			catch
			{
				return false;
			}
		}

		internal static bool TryNearestLimb(NPC npc, Vector3 point, out Rigidbody limb, out int index)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			limb = null;
			index = -1;
			try
			{
				Il2CppReferenceArray<Rigidbody> val = (((Object)(object)npc.Avatar != (Object)null) ? npc.Avatar.RagdollRBs : null);
				if (val == null)
				{
					return false;
				}
				float num = float.MaxValue;
				for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)val).Length; i++)
				{
					Rigidbody val2 = ((Il2CppArrayBase<Rigidbody>)(object)val)[i];
					if (!((Object)(object)val2 == (Object)null))
					{
						float num2 = Vector3.SqrMagnitude(val2.worldCenterOfMass - point);
						if (!(num2 >= num))
						{
							num = num2;
							limb = val2;
							index = i;
						}
					}
				}
			}
			catch
			{
			}
			return (Object)(object)limb != (Object)null;
		}

		internal static Il2CppReferenceArray<Rigidbody> PartsOf(NPC npc)
		{
			try
			{
				return ((Object)(object)npc != (Object)null && (Object)(object)npc.Avatar != (Object)null) ? npc.Avatar.RagdollRBs : null;
			}
			catch
			{
				return null;
			}
		}

		internal static Rigidbody LimbAt(NPC npc, int index)
		{
			try
			{
				Il2CppReferenceArray<Rigidbody> val = (((Object)(object)npc != (Object)null && (Object)(object)npc.Avatar != (Object)null) ? npc.Avatar.RagdollRBs : null);
				if (val == null || index < 0 || index >= ((Il2CppArrayBase<Rigidbody>)(object)val).Length)
				{
					return null;
				}
				return ((Il2CppArrayBase<Rigidbody>)(object)val)[index];
			}
			catch
			{
				return null;
			}
		}

		internal static string SafeName(NPC npc)
		{
			try
			{
				string fullName = npc.FullName;
				return string.IsNullOrEmpty(fullName) ? ((Object)((Component)npc).gameObject).name : fullName;
			}
			catch
			{
				return "someone";
			}
		}
	}
	internal static class PullPhysics
	{
		internal static bool Apply(Rigidbody rb, Vector3 pivotWorld, Vector3 anchor, Vector3 anchorVelocity, out float distance, out float alongRope)
		{
			//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_0049: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			distance = 0f;
			alongRope = 0f;
			if ((Object)(object)rb == (Object)null)
			{
				return false;
			}
			try
			{
				if (rb.isKinematic)
				{
					return false;
				}
				float fixedDeltaTime = Time.fixedDeltaTime;
				if (fixedDeltaTime <= 0f)
				{
					return false;
				}
				Vector3 val = anchor - pivotWorld;
				distance = ((Vector3)(ref val)).magnitude;
				if (distance <= Preferences.StopDistance)
				{
					return false;
				}
				Vector3 val2 = val / distance;
				Vector3 pointVelocity = rb.GetPointVelocity(pivotWorld);
				alongRope = Vector3.Dot(pointVelocity - anchorVelocity, val2);
				float num = Preferences.MaxSpeed - alongRope;
				if (num <= 0f)
				{
					return false;
				}
				float mass = rb.mass;
				if (mass <= 1E-06f || float.IsNaN(mass) || float.IsInfinity(mass))
				{
					return false;
				}
				if (!TryHookResponse(rb, pivotWorld, val2, mass, out var inverseEffectiveMass))
				{
					return false;
				}
				float num2 = Preferences.PullNewtons * fixedDeltaTime;
				float num3 = num / inverseEffectiveMass;
				if (num2 > num3)
				{
					num2 = num3;
				}
				if (num2 <= 0f)
				{
					return false;
				}
				rb.AddForceAtPosition(val2 * num2, pivotWorld, (ForceMode)1);
				return true;
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Winch] pull failed: " + ex.Message);
				return false;
			}
		}

		internal static bool ApplyToRagdoll(Il2CppReferenceArray<Rigidbody> parts, Rigidbody hooked, Vector3 pivotWorld, Vector3 anchor, Vector3 anchorVelocity, out float distance, out float alongRope)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			distance = 0f;
			alongRope = 0f;
			if ((Object)(object)hooked == (Object)null || parts == null)
			{
				return false;
			}
			try
			{
				if (hooked.isKinematic)
				{
					return false;
				}
				float fixedDeltaTime = Time.fixedDeltaTime;
				if (fixedDeltaTime <= 0f)
				{
					return false;
				}
				Vector3 val = anchor - pivotWorld;
				distance = ((Vector3)(ref val)).magnitude;
				if (distance <= Preferences.StopDistance)
				{
					return false;
				}
				Vector3 val2 = val / distance;
				alongRope = Vector3.Dot(hooked.GetPointVelocity(pivotWorld) - anchorVelocity, val2);
				float num = Preferences.MaxSpeed - alongRope;
				if (num <= 0f)
				{
					return false;
				}
				float num2 = 0f;
				for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)parts).Length; i++)
				{
					Rigidbody val3 = ((Il2CppArrayBase<Rigidbody>)(object)parts)[i];
					if (!((Object)(object)val3 == (Object)null) && !val3.isKinematic)
					{
						num2 += val3.mass;
					}
				}
				if (num2 <= 1E-06f)
				{
					return false;
				}
				float num3 = Preferences.PullNewtons * fixedDeltaTime;
				float num4 = num * num2;
				if (num3 > num4)
				{
					num3 = num4;
				}
				if (num3 <= 0f)
				{
					return false;
				}
				int instanceID = ((Object)hooked).GetInstanceID();
				for (int j = 0; j < ((Il2CppArrayBase<Rigidbody>)(object)parts).Length; j++)
				{
					Rigidbody val4 = ((Il2CppArrayBase<Rigidbody>)(object)parts)[j];
					if (!((Object)(object)val4 == (Object)null) && !val4.isKinematic)
					{
						Vector3 val5 = val2 * (num3 * (val4.mass / num2));
						if (((Object)val4).GetInstanceID() == instanceID)
						{
							val4.AddForceAtPosition(val5, pivotWorld, (ForceMode)1);
						}
						else
						{
							val4.AddForce(val5, (ForceMode)1);
						}
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Winch] ragdoll pull failed: " + ex.Message);
				return false;
			}
		}

		private static bool TryHookResponse(Rigidbody rb, Vector3 pivotWorld, Vector3 dir, float mass, out float inverseEffectiveMass)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			inverseEffectiveMass = 1f / mass;
			try
			{
				Vector3 inertiaTensor = rb.inertiaTensor;
				if (inertiaTensor.x <= 1E-08f || inertiaTensor.y <= 1E-08f || inertiaTensor.z <= 1E-08f)
				{
					return true;
				}
				Vector3 val = pivotWorld - rb.worldCenterOfMass;
				Vector3 val2 = InverseInertiaTimes(rb, Vector3.Cross(val, dir), inertiaTensor);
				float num = Vector3.Dot(dir, Vector3.Cross(val2, val));
				if (float.IsNaN(num) || float.IsInfinity(num) || num < 0f)
				{
					num = 0f;
				}
				inverseEffectiveMass = 1f / mass + num;
				return !float.IsNaN(inverseEffectiveMass) && !float.IsInfinity(inverseEffectiveMass) && inverseEffectiveMass > 0f;
			}
			catch
			{
				inverseEffectiveMass = 1f / mass;
				return true;
			}
		}

		private static Vector3 InverseInertiaTimes(Rigidbody rb, Vector3 worldVector, Vector3 inertia)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = rb.rotation * rb.inertiaTensorRotation;
			Vector3 val2 = Quaternion.Inverse(val) * worldVector;
			val2.x /= inertia.x;
			val2.y /= inertia.y;
			val2.z /= inertia.z;
			return val * val2;
		}
	}
	internal static class VehicleGrip
	{
		private struct Saved
		{
			internal LandVehicle Vehicle;

			internal bool OverrideControls;

			internal float ThrottleOverride;

			internal float SteerOverride;

			internal VehicleAgent Agent;

			internal bool StuckDetection;
		}

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

		internal static int HeldCount => _held.Count;

		internal static void TakeShared(LandVehicle v)
		{
			if ((Object)(object)v == (Object)null)
			{
				return;
			}
			try
			{
				int instanceID = ((Object)v).GetInstanceID();
				if (_held.ContainsKey(instanceID))
				{
					return;
				}
				VehicleAgent val = null;
				try
				{
					val = v.Agent;
				}
				catch
				{
				}
				Saved value = new Saved
				{
					Vehicle = v,
					OverrideControls = v.overrideControls,
					ThrottleOverride = v.throttleOverride,
					SteerOverride = v.steerOverride,
					Agent = val,
					StuckDetection = true
				};
				try
				{
					if ((Object)(object)val != (Object)null && val.Flags != null)
					{
						value.StuckDetection = val.Flags.StuckDetection;
						val.Flags.StuckDetection = false;
					}
				}
				catch
				{
				}
				_held[instanceID] = value;
				Neutralise(v);
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Grip] could not release the handbrake: " + ex.Message);
			}
		}

		internal static void TickHeld()
		{
			if (_held.Count == 0)
			{
				return;
			}
			List<int> list = null;
			List<int> list2 = null;
			foreach (KeyValuePair<int, Saved> item in _held)
			{
				LandVehicle vehicle = item.Value.Vehicle;
				bool flag;
				try
				{
					flag = (Object)(object)vehicle != (Object)null;
				}
				catch
				{
					flag = false;
				}
				if (!flag)
				{
					(list ?? (list = new List<int>())).Add(item.Key);
				}
				else if (HasPlayerDriver(vehicle))
				{
					(list2 ?? (list2 = new List<int>())).Add(item.Key);
				}
				else
				{
					Neutralise(vehicle);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					_held.Remove(list[i]);
				}
			}
			if (list2 != null)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					Restore(list2[j]);
				}
			}
		}

		private static void Neutralise(LandVehicle v)
		{
			try
			{
				v.throttleOverride = 0f;
				v.steerOverride = 0f;
				v.handbrakeOverride = false;
				v.overrideControls = true;
				v.currentThrottle = 0f;
			}
			catch
			{
			}
		}

		internal static void ReleaseShared(LandVehicle v)
		{
			if ((Object)(object)v == (Object)null)
			{
				return;
			}
			try
			{
				Restore(((Object)v).GetInstanceID());
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Grip] could not restore vehicle controls: " + ex.Message);
			}
		}

		internal static void ReleaseAll()
		{
			List<int> list = new List<int>(_held.Keys);
			for (int i = 0; i < list.Count; i++)
			{
				Restore(list[i]);
			}
			_held.Clear();
		}

		private static void Restore(int id)
		{
			if (!_held.TryGetValue(id, out var value))
			{
				return;
			}
			_held.Remove(id);
			try
			{
				if ((Object)(object)value.Agent != (Object)null && value.Agent.Flags != null)
				{
					value.Agent.Flags.StuckDetection = value.StuckDetection;
				}
			}
			catch
			{
			}
			try
			{
				LandVehicle vehicle = value.Vehicle;
				if (!((Object)(object)vehicle == (Object)null))
				{
					vehicle.throttleOverride = value.ThrottleOverride;
					vehicle.steerOverride = value.SteerOverride;
					vehicle.handbrakeOverride = false;
					vehicle.overrideControls = value.OverrideControls;
				}
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Grip] restore failed: " + ex.Message);
			}
		}

		internal static bool HasPlayerDriver(LandVehicle v)
		{
			try
			{
				return (Object)(object)v != (Object)null && v.CurrentPlayerOccupancy > 0;
			}
			catch
			{
				return false;
			}
		}

		internal static bool HasNpcDriver(LandVehicle v)
		{
			try
			{
				if ((Object)(object)v == (Object)null)
				{
					return false;
				}
				Il2CppReferenceArray<NPC> occupantNPCs = v.OccupantNPCs;
				if (occupantNPCs == null)
				{
					return false;
				}
				for (int i = 0; i < ((Il2CppArrayBase<NPC>)(object)occupantNPCs).Length; i++)
				{
					if ((Object)(object)((Il2CppArrayBase<NPC>)(object)occupantNPCs)[i] != (Object)null)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		internal static string DescribeDriver(LandVehicle v)
		{
			try
			{
				if ((Object)(object)v == (Object)null)
				{
					return "none";
				}
				if (HasPlayerDriver(v))
				{
					return v.LocalPlayerIsDriver ? "you" : "another player";
				}
				if (HasNpcDriver(v))
				{
					bool flag = false;
					try
					{
						flag = (Object)(object)v.Agent != (Object)null && v.Agent.AutoDriving;
					}
					catch
					{
					}
					string text = "an NPC";
					try
					{
						Il2CppReferenceArray<NPC> occupantNPCs = v.OccupantNPCs;
						for (int i = 0; i < ((Il2CppArrayBase<NPC>)(object)occupantNPCs).Length; i++)
						{
							if (!((Object)(object)((Il2CppArrayBase<NPC>)(object)occupantNPCs)[i] == (Object)null))
							{
								text = NpcGrip.SafeName(((Il2CppArrayBase<NPC>)(object)occupantNPCs)[i]);
								break;
							}
						}
					}
					catch
					{
					}
					return text + (flag ? " (driving)" : " (idle)");
				}
			}
			catch
			{
			}
			return "nobody";
		}
	}
	internal static class WinchSession
	{
		private static WinchTarget _target;

		private static Vector3 _pullAnchor;

		private static bool _pulling;

		private static bool _holdPulling;

		private static float _pullUntil = -1f;

		private static bool _delegatedToHost;

		private static bool _delegatedToDriver;

		private static VerletRope _rope;

		private static float _lastDistance = -1f;

		private static readonly float[] _rateWindow = new float[3];

		private static int _rateIndex;

		private static float _lowRateTime;

		private static Vector3 _physicsAnchor;

		private static Vector3 _physicsAnchorVelocity;

		private static bool _physicsAnchorValid;

		private const float AnchorFollowTime = 0.06f;

		private const float AnchorMaxSpeed = 10f;

		internal static bool Hooked
		{
			get
			{
				if (_target != null)
				{
					return _target.Alive;
				}
				return false;
			}
		}

		internal static bool Pulling => _pulling;

		internal static float ReelRate { get; private set; }

		internal static float ReelRateSmoothed { get; private set; }

		internal static bool Stalled { get; private set; }

		internal static float PayOutRate { get; private set; }

		private static void TrackRate(float rawAlongRope, bool demandingTension)
		{
			float fixedDeltaTime = Time.fixedDeltaTime;
			float num = Mathf.Max(rawAlongRope, 0f);
			_rateWindow[_rateIndex % 3] = num;
			_rateIndex++;
			float num2 = Median(_rateWindow[0], _rateWindow[1], _rateWindow[2]);
			float num3 = ((num2 > ReelRateSmoothed) ? 0.1f : 0.25f);
			ReelRateSmoothed += (num2 - ReelRateSmoothed) * (1f - Mathf.Exp((0f - fixedDeltaTime) / num3));
			ReelRate = num;
			if (demandingTension && ReelRateSmoothed < 0.04f)
			{
				_lowRateTime += fixedDeltaTime;
			}
			else
			{
				_lowRateTime = 0f;
			}
			Stalled = demandingTension && _lowRateTime >= 0.25f;
		}

		private static void TrackPayOut(float distance, float dt)
		{
			if (_lastDistance < 0f)
			{
				_lastDistance = distance;
				return;
			}
			float num = (distance - _lastDistance) / Mathf.Max(dt, 0.0001f);
			_lastDistance = distance;
			float num2 = Mathf.Max(num, 0f);
			float num3 = ((num2 > PayOutRate) ? 0.08f : 0.2f);
			PayOutRate += (num2 - PayOutRate) * (1f - Mathf.Exp((0f - dt) / num3));
			if (PayOutRate < 0.01f)
			{
				PayOutRate = 0f;
			}
		}

		private static float Median(float a, float b, float c)
		{
			return Mathf.Max(Mathf.Min(a, b), Mathf.Min(Mathf.Max(a, b), c));
		}

		internal static bool HookFromCamera(out string message)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			message = null;
			Transform val = Camera();
			if ((Object)(object)val == (Object)null)
			{
				message = "no player camera - are you in the world?";
				return false;
			}
			if (!WinchTarget.TryAcquire(new Ray(val.position, val.forward), Preferences.HookRange, out var target, out var reason))
			{
				message = "no hold: " + reason;
				return false;
			}
			Attach(target);
			message = "hooked " + target.Describe() + " at " + Distance().ToString("F1", CultureInfo.InvariantCulture) + "m";
			return true;
		}

		internal static bool HookNearest(float radius, out string message)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			message = null;
			Vector3 origin;
			try
			{
				Player local = Player.Local;
				if ((Object)(object)local == (Object)null)
				{
					message = "no local player";
					return false;
				}
				origin = ((Component)local).transform.position + Vector3.up * 1f;
			}
			catch
			{
				message = "no local player";
				return false;
			}
			if (!WinchTarget.TryAcquireNearest(origin, radius, out var target, out var reason))
			{
				message = "no hold: " + reason;
				return false;
			}
			Attach(target);
			message = "hooked " + target.Describe() + " at " + Distance().ToString("F1", CultureInfo.InvariantCulture) + "m (nearest)";
			return true;
		}

		internal static bool HookNearestPerson(float radius, out string message)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			message = null;
			Vector3 origin;
			try
			{
				Player local = Player.Local;
				if ((Object)(object)local == (Object)null)
				{
					message = "no local player";
					return false;
				}
				origin = ((Component)local).transform.position + Vector3.up * 1f;
			}
			catch
			{
				message = "no local player";
				return false;
			}
			if (!WinchTarget.TryAcquireNearestPerson(origin, radius, out var target, out var reason))
			{
				message = "no hold: " + reason;
				return false;
			}
			Attach(target);
			message = "hooked " + target.Describe() + " at " + Distance().ToString("F1", CultureInfo.InvariantCulture) + "m (nearest person)";
			return true;
		}

		private static void Attach(WinchTarget t)
		{
			//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_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)
			Drop();
			_target = t;
			_pullAnchor = MuzzlePoint();
			_pulling = false;
			_pullUntil = -1f;
			t.PrepareForPull();
			EnsureRope();
			if (_rope != null)
			{
				_rope.Attach(t.PivotWorld, MuzzlePoint());
			}
		}

		internal static bool Pull(float seconds, out string message)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!Hooked)
			{
				message = "nothing hooked";
				return false;
			}
			_pullAnchor = MuzzlePoint();
			_pulling = true;
			_pullUntil = ((seconds > 0f) ? (Time.time + seconds) : (-1f));
			_target.PrepareForPull();
			RoutePull();
			message = ((seconds > 0f) ? ("pulling for " + seconds.ToString("F1", CultureInfo.InvariantCulture) + "s") : "pulling until yoinkstop");
			return true;
		}

		private static void RoutePull()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f1: 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)
			_delegatedToHost = false;
			_delegatedToDriver = false;
			bool online = YoinkNet.Online;
			bool isServer = YoinkNet.IsServer;
			if (online && !isServer && _target.IsNetworked)
			{
				_delegatedToHost = true;
				YoinkNet.SendToHost(new YoinkMsg
				{
					Op = YoinkOp.PullStart,
					TargetId = _target.NetId,
					PivotLocal = _target.PivotLocal,
					Anchor = _pullAnchor
				});
				return;
			}
			if ((Object)(object)_target.Vehicle != (Object)null && VehicleGrip.HasPlayerDriver(_target.Vehicle))
			{
				bool flag = false;
				try
				{
					flag = _target.Vehicle.LocalPlayerIsDriver;
				}
				catch
				{
				}
				if (!flag)
				{
					_delegatedToDriver = true;
					if (online && isServer && _target.IsNetworked)
					{
						YoinkNet.BroadcastToAll(new YoinkMsg
						{
							Op = YoinkOp.DriverPull,
							TargetId = _target.NetId,
							PivotLocal = _target.PivotLocal,
							Anchor = _pullAnchor
						});
					}
					Core.Log.Msg("[Winch] another player is driving - the pull is theirs to feel, not ours to apply.");
					return;
				}
			}
			if ((Object)(object)_target.Vehicle != (Object)null)
			{
				VehicleGrip.TakeShared(_target.Vehicle);
				if (VehicleGrip.HasNpcDriver(_target.Vehicle))
				{
					Core.Log.Msg("[Winch] " + _target.Label + " has " + VehicleGrip.DescribeDriver(_target.Vehicle) + " at the wheel - holding it in neutral while the hook is in.");
				}
			}
		}

		internal static void Stop()
		{
			bool pulling = _pulling;
			_pulling = false;
			_pullUntil = -1f;
			ReelRate = 0f;
			Stalled = false;
			_lowRateTime = 0f;
			if (!pulling)
			{
				return;
			}
			try
			{
				if (_target != null && _target.IsNetworked && YoinkNet.Online)
				{
					if (_delegatedToHost)
					{
						YoinkNet.SendToHost(new YoinkMsg
						{
							Op = YoinkOp.PullStop,
							TargetId = _target.NetId
						});
					}
					else if (_delegatedToDriver && YoinkNet.IsServer)
					{
						YoinkNet.BroadcastToAll(new YoinkMsg
						{
							Op = YoinkOp.DriverStop,
							TargetId = _target.NetId
						});
					}
				}
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Winch] stop message failed: " + ex.Message);
			}
			if (_target != null && (Object)(object)_target.Vehicle != (Object)null && !_delegatedToHost)
			{
				VehicleGrip.ReleaseShared(_target.Vehicle);
			}
			_delegatedToHost = false;
			_delegatedToDriver = false;
		}

		internal static void Drop()
		{
			Stop();
			PayOutRate = 0f;
			_lastDistance = -1f;
			if (_target != null && (Object)(object)_target.Vehicle != (Object)null)
			{
				VehicleGrip.ReleaseShared(_target.Vehicle);
			}
			if (_target != null)
			{
				_target.Release();
			}
			_target = null;
			_holdPulling = false;
			if (_rope != null)
			{
				_rope.Detach();
			}
		}

		private static void HandleHoldToReel()
		{
			//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)
			if (!Hooked)
			{
				return;
			}
			bool flag;
			try
			{
				if (GameInput.IsTyping)
				{
					flag = false;
				}
				else
				{
					PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
					flag = (Object)(object)instance == (Object)null || instance.activeUIElements.Count == 0;
				}
			}
			catch
			{
				flag = false;
			}
			bool flag2 = flag && Input.ReelHeld();
			if (flag2 && !_holdPulling)
			{
				_holdPulling = true;
				Pull(0f, out var _);
				Core.Log.Msg("[Winch] reeling. " + StatusLine());
			}
			else if (flag2 && _holdPulling)
			{
				_pullAnchor = MuzzlePoint();
				if (!_pulling)
				{
					_pulling = true;
				}
			}
			else if (!flag2 && _holdPulling)
			{
				_holdPulling = false;
				Stop();
				Core.Log.Msg("[Winch] released. " + StatusLine());
			}
		}

		internal static void Tick(float dt)
		{
			if (_target == null)
			{
				return;
			}
			HandleHoldToReel();
			if (!_target.Alive)
			{
				Core.Log.Msg("[Winch] target is gone - hook released.");
				Drop();
				return;
			}
			if ((Object)(object)_target.Npc != (Object)null && !NpcGrip.IsDown(_target.Npc))
			{
				Core.Log.Msg("[Winch] " + _target.Label + " got back on their feet - hook released.");
				Drop();
				return;
			}
			if (_pulling && _pullUntil > 0f && Time.time >= _pullUntil)
			{
				Stop();
				Core.Log.Msg("[Winch] pull finished. " + StatusLine());
			}
			float num = Distance();
			TrackPayOut(num, dt);
			if (num > Preferences.BreakDistance)
			{
				Core.Log.Msg("[Winch] rope snapped at " + num.ToString("F1", CultureInfo.InvariantCulture) + "m.");
				Drop();
			}
		}

		internal static void LateTick(float dt)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (_target != null && _target.Alive && _rope != null)
			{
				_rope.SetEnds(_target.PivotWorld, MuzzlePoint());
				_rope.Simulate(dt, _pulling);
			}
		}

		private static void StepPhysicsAnchor(Vector3 drawn, float dt)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!_physicsAnchorValid || dt <= 0f)
			{
				_physicsAnchor = drawn;
				_physicsAnchorVelocity = Vector3.zero;
				_physicsAnchorValid = true;
			}
			else
			{
				Vector3 val = (drawn - _physicsAnchor) * (1f - Mathf.Exp((0f - dt) / 0.06f));
				val = Vector3.ClampMagnitude(val, 10f * dt);
				_physicsAnchor += val;
				_physicsAnchorVelocity = val / dt;
			}
		}

		internal static void FixedTick()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (!_pulling || _target == null || !_target.Alive)
			{
				if (ReelRateSmoothed > 0f || Stalled)
				{
					TrackRate(0f, demandingTension: false);
				}
				_physicsAnchorValid = false;
				return;
			}
			StepPhysicsAnchor(_pullAnchor, Time.fixedDeltaTime);
			Rigidbody rb = _target.Rb;
			if (_delegatedToHost || _delegatedToDriver)
			{
				MeasureOnly(rb);
				return;
			}
			float distance;
			float alongRope;
			bool num = (((Object)(object)_target.Npc != (Object)null) ? PullPhysics.ApplyToRagdoll(_target.Parts, rb, _target.PivotWorld, _physicsAnchor, _physicsAnchorVelocity, out distance, out alongRope) : PullPhysics.Apply(rb, _target.PivotWorld, _physicsAnchor, _physicsAnchorVelocity, out distance, out alongRope));
			TrackRate(alongRope, distance > Preferences.StopDistance);
			if (!num && distance > 0f && distance <= Preferences.StopDistance)
			{
				if (!_holdPulling)
				{
					Stop();
					Core.Log.Msg("[Winch] load is in reach - stopped reeling.");
				}
				return;
			}
			bool flag = false;
			try
			{
				flag = (Object)(object)rb != (Object)null && rb.isKinematic;
			}
			catch
			{
			}
		}

		private static void MeasureOnly(Rigidbody rb)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector3 val = _pullAnchor - _target.PivotWorld;
				float magnitude = ((Vector3)(ref val)).magnitude;
				TrackRate((magnitude > 0.001f) ? Vector3.Dot(rb.velocity, val / magnitude) : 0f, magnitude > Preferences.StopDistance);
			}
			catch
			{
			}
		}

		internal static void Reset()
		{
			Drop();
			VehicleGrip.ReleaseAll();
			NpcGrip.ReleaseAll();
			RemotePulls.Clear();
			if (_rope != null)
			{
				_rope.Destroy();
				_rope = null;
			}
		}

		internal static float Distance()
		{
			//IL_001e: 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)
			if (_target == null || !_target.Alive)
			{
				return 0f;
			}
			return Vector3.Distance(_target.PivotWorld, _pullAnchor);
		}

		internal static float TargetMass()
		{
			try
			{
				return (_target != null && _target.Alive) ? _target.Mass : 0f;
			}
			catch
			{
				return 0f;
			}
		}

		internal static float TargetSpeed()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float result;
				if (_target == null || !_target.Alive)
				{
					result = 0f;
				}
				else
				{
					Vector3 velocity = _target.Rb.velocity;
					result = ((Vector3)(ref velocity)).magnitude;
				}
				return result;
			}
			catch
			{
				return 0f;
			}
		}

		internal static string TargetLabel()
		{
			try
			{
				return (_target != null && _target.Alive) ? _target.Label : "-";
			}
			catch
			{
				return "-";
			}
		}

		internal static string StatusLine()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!Hooked)
			{
				return "no hook. " + Preferences.Describe();
			}
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			float num = 0f;
			try
			{
				Vector3 velocity = _target.Rb.velocity;
				num = ((Vector3)(ref velocity)).magnitude;
			}
			catch
			{
			}
			string text = (_delegatedToHost ? " [host pulls]" : (_delegatedToDriver ? " [driver pulls]" : ""));
			if ((Object)(object)_target.Npc != (Object)null)
			{
				text += (NpcGrip.IsDown(_target.Npc) ? " [down]" : " [back on their feet]");
			}
			return _target.Describe() + " dist=" + Distance().ToString("F1", invariantCulture) + "m speed=" + num.ToString("F2", invariantCulture) + "m/s" + (_pulling ? " PULLING" : " idle") + text + " | " + Preferences.Describe();
		}

		private static Vector3 MuzzlePoint()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (WinchItem.TryGetMuzzle(out var world))
			{
				return world;
			}
			Transform val = Camera();
			if ((Object)(object)val == (Object)null)
			{
				return _pullAnchor;
			}
			return val.position + val.forward * 0.7f + val.right * 0.2f - val.up * 0.3f;
		}

		internal static bool RopeEndsInModel()
		{
			Vector3 world;
			return WinchItem.TryGetMuzzle(out world);
		}

		private static Transform Camera()
		{
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				return ((Object)(object)instance != (Object)null) ? ((Component)instance).transform : null;
			}
			catch
			{
				return null;
			}
		}

		private static void EnsureRope()
		{
			if (_rope == null)
			{
				_rope = new VerletRope(Preferences.RopeSegments);
			}
		}

		[Conditional("DEBUG")]
		private static void Trace(string msg)
		{
		}
	}
	internal sealed class WinchTarget
	{
		internal Rigidbody Rb;

		internal Transform Root;

		internal Vector3 PivotLocal;

		internal LandVehicle Vehicle;

		internal Draggable Draggable;

		internal NPC Npc;

		internal int LimbIndex = -1;

		internal Il2CppReferenceArray<Rigidbody> Parts;

		internal string Label = "?";

		internal string NetId;

		internal bool IsNetworked => !string.IsNullOrEmpty(NetId);

		internal Vector3 PivotWorld
		{
			get
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Root != (Object)null))
				{
					return Vector3.zero;
				}
				return Root.TransformPoint(PivotLocal);
			}
		}

		internal bool Alive
		{
			get
			{
				try
				{
					return (Object)(object)Rb != (Object)null && (Object)(object)Root != (Object)null;
				}
				catch
				{
					return false;
				}
			}
		}

		internal float Mass
		{
			get
			{
				try
				{
					if ((Object)(object)Npc != (Object)null && Parts != null)
					{
						float num = 0f;
						for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)Parts).Length; i++)
						{
							if ((Object)(object)((Il2CppArrayBase<Rigidbody>)(object)Parts)[i] != (Object)null)
							{
								num += ((Il2CppArrayBase<Rigidbody>)(object)Parts)[i].mass;
							}
						}
						if (num > 0f)
						{
							return num;
						}
					}
					return ((Object)(object)Rb != (Object)null) ? Rb.mass : 0f;
				}
				catch
				{
					return 0f;
				}
			}
		}

		internal static bool TryAcquire(Ray ray, float maxRange, out WinchTarget target, out string reason)
		{
			//IL_0006: 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_0094: 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_0160: 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)
			target = null;
			reason = null;
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(ray, ref val, maxRange, -5, (QueryTriggerInteraction)1))
			{
				reason = "nothing within " + Mathf.RoundToInt(maxRange) + "m";
				return false;
			}
			Collider collider = ((RaycastHit)(ref val)).collider;
			if ((Object)(object)collider == (Object)null)
			{
				reason = "no collider on the hit";
				return false;
			}
			try
			{
				if ((Object)(object)((Component)collider).GetComponentInParent<Player>() != (Object)null)
				{
					reason = "that is you";
					return false;
				}
			}
			catch
			{
			}
			NPC val2 = null;
			try
			{
				val2 = ((Component)collider).GetComponentInParent<NPC>();
			}
			catch
			{
			}
			if ((Object)(object)val2 != (Object)null)
			{
				return TryAcquireNpc(val2, ((RaycastHit)(ref val)).point, ((Ray)(ref ray)).direction, out target, out reason);
			}
			Rigidbody val3 = ((RaycastHit)(ref val)).rigidbody;
			if ((Object)(object)val3 == (Object)null)
			{
				try
				{
					val3 = ((Component)collider).GetComponentInParent<Rigidbody>();
				}
				catch
				{
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				reason = "'" + SafeName(((Component)collider).transform) + "' has no rigidbody - the hook needs something that can move";
				return false;
			}
			LandVehicle val4 = null;
			try
			{
				val4 = ((Component)collider).GetComponentInParent<LandVehicle>();
			}
			catch
			{
			}
			bool flag = false;
			try
			{
				flag = (Object)(object)val4 == (Object)null && val3.isKinematic;
			}
			catch
			{
			}
			if (flag)
			{
				reason = "'" + SafeName(((Component)val3).transform) + "' is fixed in place - no winch is going to move that";
				return false;
			}
			WinchTarget winchTarget = new WinchTarget();
			winchTarget.Rb = val3;
			winchTarget.Root = ((Component)val3).transform;
			winchTarget.PivotLocal = winchTarget.Root.InverseTransformPoint(((RaycastHit)(ref val)).point);
			winchTarget.Vehicle = val4;
			try
			{
				winchTarget.Draggable = ((Component)collider).GetComponentInParent<Draggable>();
			}
			catch
			{
			}
			winchTarget.Label = (((Object)(object)winchTarget.Vehicle != (Object)null) ? SafeVehicleName(winchTarget.Vehicle) : SafeName(winchTarget.Root));
			winchTarget.NetId = MakeNetId(winchTarget);
			target = winchTarget;
			return true;
		}

		private static bool TryAcquireNpc(NPC npc, Vector3 hitPoint, Vector3 shotDir, out WinchTarget target, out string reason)
		{
			//IL_0004: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			if (!NpcGrip.TryHook(npc, hitPoint, shotDir, out var limb, out var limbIndex, out reason))
			{
				return false;
			}
			WinchTarget winchTarget = new WinchTarget();
			winchTarget.Rb = limb;
			winchTarget.Root = ((Component)limb).transform;
			winchTarget.PivotLocal = winchTarget.Root.InverseTransformPoint(hitPoint);
			winchTarget.Npc = npc;
			winchTarget.LimbIndex = limbIndex;
			winchTarget.Parts = NpcGrip.PartsOf(npc);
			winchTarget.Label = NpcGrip.SafeName(npc);
			winchTarget.NetId = MakeNetId(winchTarget);
			target = winchTarget;
			return true;
		}

		internal static bool TryAcquireNearest(Vector3 origin, float radius, out WinchTarget target, out string reason)
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_018b: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			reason = null;
			Collider[] array;
			try
			{
				array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(origin, radius, -5, (QueryTriggerInteraction)1));
			}
			catch (Exception ex)
			{
				reason = "overlap query failed: " + ex.Message;
				return false;
			}
			if (array == null || array.Length == 0)
			{
				reason = "nothing within " + Mathf.RoundToInt(radius) + "m";
				return false;
			}
			Rigidbody val = null;
			Collider val2 = null;
			float num = float.MaxValue;
			bool flag = false;
			foreach (Collider val3 in array)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				try
				{
					if ((Object)(object)((Component)val3).GetComponentInParent<Player>() != (Object)null)
					{
						continue;
					}
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)((Component)val3).GetComponentInParent<NPC>() != (Object)null)
					{
						continue;
					}
				}
				catch
				{
				}
				Rigidbody attachedRigidbody = val3.attachedRigidbody;
				if ((Object)(object)attachedRigidbody == (Object)null)
				{
					continue;
				}
				bool flag2 = false;
				try
				{
					flag2 = (Object)(object)((Component)val3).GetComponentInParent<LandVehicle>() != (Object)null;
				}
				catch
				{
				}
				if (!flag2)
				{
					try
					{
						if (attachedRigidbody.isKinematic)
						{
							continue;
						}
					}
					catch
					{
					}
				}
				float num2;
				try
				{
					num2 = Vector3.Distance(origin, val3.ClosestPoint(origin));
				}
				catch
				{
					continue;
				}
				if ((!flag || flag2) && ((flag2 && !flag) || !(num2 >= num)))
				{
					num = num2;
					val = attachedRigidbody;
					val2 = val3;
					flag = flag2;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				reason = "nothing within " + Mathf.RoundToInt(radius) + "m that can move";
				return false;
			}
			WinchTarget winchTarget = new WinchTarget();
			winchTarget.Rb = val;
			winchTarget.Root = ((Component)val).transform;
			Vector3 val4;
			try
			{
				val4 = val2.ClosestPoint(origin);
			}
			catch
			{
				val4 = val.worldCenterOfMass;
			}
			winchTarget.PivotLocal = winchTarget.Root.InverseTransformPoint(val4);
			try
			{
				winchTarget.Vehicle = ((Component)val2).GetComponentInParent<LandVehicle>();
			}
			catch
			{
			}
			try
			{
				winchTarget.Draggable = ((Component)val2).GetComponentInParent<Draggable>();
			}
			catch
			{
			}
			winchTarget.Label = (((Object)(object)winchTarget.Vehicle != (Object)null) ? SafeVehicleName(winchTarget.Vehicle) : SafeName(winchTarget.Root));
			winchTarget.NetId = MakeNetId(winchTarget);
			target = winchTarget;
			return true;
		}

		internal static bool TryAcquireNearestPerson(Vector3 origin, float radius, out WinchTarget target, out string reason)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0006: 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_014c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			reason = null;
			Collider[] array;
			try
			{
				array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(origin, radius, -1, (QueryTriggerInteraction)2));
			}
			catch (Exception ex)
			{
				reason = "overlap query failed: " + ex.Message;
				return false;
			}
			if (array == null || array.Length == 0)
			{
				reason = "nobody within " + Mathf.RoundToInt(radius) + "m";
				return false;
			}
			NPC val = null;
			float num = float.MaxValue;
			foreach (Collider val2 in array)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				NPC val3 = null;
				try
				{
					val3 = ((Component)val2).GetComponentInParent<NPC>();
				}
				catch
				{
				}
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				try
				{
					if (val3.IsInVehicle)
					{
						continue;
					}
				}
				catch
				{
				}
				float num2;
				try
				{
					num2 = Vector3.Distance(origin, ((Component)val3).transform.position);
				}
				catch
				{
					continue;
				}
				if (!(num2 >= num))
				{
					num = num2;
					val = val3;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				reason = "nobody within " + Mathf.RoundToInt(radius) + "m";
				return false;
			}
			Vector3 val4;
			try
			{
				val4 = ((Component)val).transform.position + Vector3.up * 1f;
			}
			catch
			{
				val4 = origin;
			}
			Vector3 shotDir;
			try
			{
				Vector3 val5 = val4 - origin;
				shotDir = ((Vector3)(ref val5)).normalized;
			}
			catch
			{
				shotDir = Vector3.forward;
			}
			return TryAcquireNpc(val, val4, shotDir, out target, out reason);
		}

		private static string MakeNetId(WinchTarget t)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			try
			{
				if ((Object)(object)t.Vehicle != (Object)null)
				{
					return "V:" + ((object)t.Vehicle.GUID/*cast due to .constrained prefix*/).ToString();
				}
				if ((Object)(object)t.Draggable != (Object)null)
				{
					return "D:" + ((object)t.Draggable.GUID/*cast due to .constrained prefix*/).ToString();
				}
				if ((Object)(object)t.Npc != (Object)null)
				{
					return "N:" + ((object)t.Npc.GUID/*cast due to .constrained prefix*/).ToString() + ":" + t.LimbIndex.ToString(CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
			return null;
		}

		internal void PrepareForPull()
		{
			try
			{
				if ((Object)(object)Vehicle != (Object)null && Vehicle.isParked)
				{
					Vehicle.ExitPark(false);
					Core.Log.Msg("[Winch] " + Label + " was parked - left the lot so physics can act on it.");
				}
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Winch] unpark failed: " + ex.Message);
			}
			try
			{
				if ((Object)(object)Rb != (Object)null && !Rb.isKinematic)
				{
					Rb.WakeUp();
				}
			}
			catch
			{
			}
		}

		internal void Release()
		{
			if ((Object)(object)Npc != (Object)null)
			{
				NpcGrip.Release(Npc);
			}
		}

		internal string Describe()
		{
			string text = (((Object)(object)Npc != (Object)null) ? "person" : (((Object)(object)Vehicle != (Object)null) ? "vehicle" : (((Object)(object)Draggable != (Object)null) ? "draggable" : "rigidbody")));
			string text2 = "?";
			try
			{
				text2 = (Rb.isKinematic ? "kinematic" : "dynamic");
			}
			catch
			{
			}
			return Label + " [" + text + ", " + Mass.ToString("F0", CultureInfo.InvariantCulture) + "kg, " + text2 + "]";
		}

		private static string SafeName(Transform t)
		{
			try
			{
				return ((Object)(object)t != (Object)null) ? ((Object)((Component)t).gameObject).name : "?";
			}
			catch
			{
				return "?";
			}
		}

		private static string SafeVehicleName(LandVehicle v)
		{
			try
			{
				return string.IsNullOrEmpty(v.VehicleName) ? ((Object)((Component)v).gameObject).name : v.VehicleName;
			}
			catch
			{
				return "vehicle";
			}
		}
	}
}
namespace Yoink.Rope
{
	internal sealed class VerletRope
	{
		private const float Gravity = -9.81f;

		private const float Damping = 0.96f;

		private const int Iterations = 6;

		private const float Radius = 0.02f;

		private const float GroundProbe = 0.06f;

		private readonly Vector3[] _points;

		private readonly Vector3[] _prev;

		private readonly int _count;

		private GameObject _go;

		private LineRenderer _lr;

		private GameObject _guide;

		private Material _ropeMaterial;

		private Material _guideMaterial;

		private Texture2D _ropeTexture;

		private bool _attached;

		private float _restLength = 1f;

		private const float SlackFactor = 1.12f;

		private const float TautFactor = 0.995f;

		private const float TightenTime = 0.45f;

		private const float SlackenTime = 0.8f;

		private float _tension;

		private static Texture2D _lastTexture;

		internal VerletRope(int segments)
		{
			_count = Mathf.Clamp(segments, 4, 64);
			_points = (Vector3[])(object)new Vector3[_count];
			_prev = (Vector3[])(object)new Vector3[_count];
		}

		internal void Attach(Vector3 hook, Vector3 anchor)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_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)
			EnsureRenderer();
			if (!((Object)(object)_lr == (Object)null))
			{
				float num = Vector3.Distance(hook, anchor);
				_restLength = Mathf.Max(num * 1.15f, 0.5f);
				for (int i = 0; i < _count; i++)
				{
					float num2 = (float)i / (float)(_count - 1);
					_points[i] = Vector3.Lerp(hook, anchor, num2);
					_prev[i] = _points[i];
				}
				_attached = true;
				((Renderer)_lr).enabled = true;
				if ((Object)(object)_guide != (Object)null)
				{
					_guide.SetActive(!WinchSession.RopeEndsInModel());
				}
				Render();
			}
		}

		internal void Detach()
		{
			_attached = false;
			if ((Object)(object)_lr != (Object)null)
			{
				((Renderer)_lr).enabled = false;
			}
			if ((Object)(object)_guide != (Object)null)
			{
				_guide.SetActive(false);
			}
		}

		internal void SetEnds(Vector3 hook, Vector3 anchor)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (_attached)
			{
				_points[0] = hook;
				_points[_count - 1] = anchor;
			}
		}

		internal void Simulate(float dt, bool taut)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00da: 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_00e9: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_01e3: 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)
			if (!_attached || (Object)(object)_lr == (Object)null || dt <= 0f)
			{
				return;
			}
			Vector3 val = _points[0];
			Vector3 val2 = _points[_count - 1];
			float num = Vector3.Distance(val, val2);
			StepTension(taut, dt);
			float restLength = num * Mathf.Lerp(1.12f, 0.995f, _tension);
			_restLength = restLength;
			float num2 = _restLength / (float)(_count - 1);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(0f, -9.81f * dt * dt, 0f);
			for (int i = 1; i < _count - 1; i++)
			{
				Vector3 val4 = _points[i];
				Vector3 val5 = (val4 - _prev[i]) * 0.96f;
				_prev[i] = val4;
				_points[i] = val4 + val5 + val3;
			}
			for (int j = 0; j < 6; j++)
			{
				_points[0] = val;
				_points[_count - 1] = val2;
				for (int k = 0; k < _count - 1; k++)
				{
					Vector3 val6 = _points[k];
					Vector3 val7 = _points[k + 1];
					Vector3 val8 = val7 - val6;
					float magnitude = ((Vector3)(ref val8)).magnitude;
					if (!(magnitude < 0.0001f))
					{
						bool num3 = k == 0;
						bool flag = k + 1 == _count - 1;
						float num4 = ((num3 || flag) ? 1f : 0.5f);
						Vector3 val9 = val8 * ((magnitude - num2) / magnitude * num4);
						if (!num3)
						{
							_points[k] = val6 + val9;
						}
						if (!flag)
						{
							_points[k + 1] = val7 - val9;
						}
					}
				}
			}
			Straighten(val, val2, num);
			Collide();
			Render();
		}

		private void StepTension(bool taut, float dt)
		{
			float num = dt / Mathf.Max(0.01f, taut ? 0.45f : 0.8f);
			_tension = Mathf.MoveTowards(_tension, taut ? 1f : 0f, num);
		}

		private void Straighten(Vector3 hook, Vector3 anchor, float direct)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!(direct < 0.001f) && !(_tension <= 0.001f))
			{
				for (int i = 1; i < _count - 1; i++)
				{
					Vector3 val = Vector3.Lerp(hook, anchor, (float)i / (float)(_count - 1));
					_points[i] = Vector3.Lerp(_points[i], val, _tension);
					_prev[i] = Vector3.Lerp(_prev[i], val, _tension);
				}
			}
		}

		private void Collide()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_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_007f: 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_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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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)
			if (!Preferences.RopeCollision)
			{
				return;
			}
			RaycastHit val3 = default(RaycastHit);
			RaycastHit val4 = default(RaycastHit);
			for (int i = 1; i < _count - 1; i++)
			{
				try
				{
					Vector3 val = _prev[i];
					Vector3 val2 = _points[i] - val;
					float magnitude = ((Vector3)(ref val2)).magnitude;
					if (magnitude > 0.0005f && Physics.Raycast(val, val2 / magnitude, ref val3, magnitude + 0.02f, -5, (QueryTriggerInteraction)1))
					{
						_points[i] = ((RaycastHit)(ref val3)).point + ((RaycastHit)(ref val3)).normal * 0.02f;
						_prev[i] = _points[i];
					}
					else if (Physics.Raycast(_points[i] + Vector3.up * 0.06f, Vector3.down, ref val4, 0.08f, -5, (QueryTriggerInteraction)1))
					{
						float num = ((RaycastHit)(ref val4)).point.y + 0.02f;
						if (_points[i].y < num)
						{
							Vector3 val5 = _points[i];
							val5.y = num;
							_points[i] = val5;
							_prev[i] = val5;
						}
					}
				}
				catch
				{
				}
			}
		}

		private void Render()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_lr == (Object)null))
			{
				for (int i = 0; i < _count; i++)
				{
					_lr.SetPosition(i, _points[i]);
				}
				PlaceGuide();
			}
		}

		private void PlaceGuide()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_guide == (Object)null || _count < 2)
			{
				return;
			}
			try
			{
				Vector3 val = _points[_count - 1];
				Vector3 val2 = val - _points[_count - 2];
				if (!(((Vector3)(ref val2)).sqrMagnitude < 1E-06f))
				{
					((Vector3)(ref val2)).Normalize();
					_guide.transform.position = val + val2 * 0.015f;
					_guide.transform.rotation = Quaternion.FromToRotation(Vector3.up, val2);
				}
			}
			catch
			{
			}
		}

		internal void Destroy()
		{
			try
			{
				if ((Object)(object)_go != (Object)null)
				{
					Object.Destroy((Object)(object)_go);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_guide != (Object)null)
				{
					Object.Destroy((Object)(object)_guide);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_ropeMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)_ropeMaterial);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_guideMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)_guideMaterial);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_ropeTexture != (Object)null)
				{
					Object.Destroy((Object)(object)_ropeTexture);
				}
			}
			catch
			{
			}
			_go = null;
			_lr = null;
			_guide = null;
			_ropeMaterial = null;
			_guideMaterial = null;
			_ropeTexture = null;
			_attached = false;
		}

		private void EnsureRenderer()
		{
			//IL_0125: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if ((Object)(object)_lr != (Object)null)
			{
				return;
			}
			try
			{
				_go = new GameObject("YoinkRope");
				_lr = _go.AddComponent<LineRenderer>();
				_lr.useWorldSpace = true;
				_lr.positionCount = _count;
				_lr.widthMultiplier = 0.04f;
				_lr.numCapVertices = 4;
				_lr.numCornerVertices = 4;
				((Renderer)_lr).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)_lr).receiveShadows = false;
				_lr.textureMode = (LineTextureMode)3;
				_lr.widthCurve = TaperedWidth();
				_ropeMaterial = MakeRopeMaterial();
				_ropeTexture = _lastTexture;
				if ((Object)(object)_ropeMaterial != (Object)null)
				{
					((Renderer)_lr).material = _ropeMaterial;
					try
					{
						_lr.generateLightingData = (Object)(object)_ropeMaterial.shader != (Object)null && ((Object)_ropeMaterial.shader).name.EndsWith("Lit");
					}
					catch
					{
					}
				}
				_lr.startColor = Color.white;
				_lr.endColor = Color.white;
				BuildGuide();
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Rope] could not create the rope renderer: " + ex.Message);
				_lr = null;
			}
		}

		private void BuildGuide()
		{
			//IL_0056: 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)
			try
			{
				_guide = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)_guide).name = "YoinkRopeGuide";
				try
				{
					Collider component = _guide.GetComponent<Collider>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
				}
				catch
				{
				}
				_guide.transform.localScale = new Vector3(0.05f, 0.035f, 0.05f);
				MeshRenderer component2 = _guide.GetComponent<MeshRenderer>();
				if ((Object)(object)component2 != (Object)null)
				{
					_guideMaterial = MakeSolidMaterial(new Color(0.2f, 0.21f, 0.23f, 1f));
					if ((Object)(object)_guideMaterial != (Object)null)
					{
						((Renderer)component2).material = _guideMaterial;
					}
					((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)component2).receiveShadows = false;
				}
				_guide.SetActive(false);
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Rope] could not build the rope guide: " + ex.Message);
				_guide = null;
			}
		}

		private static Material MakeSolidMaterial(Color colour)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[3] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Unlit", "Sprites/Default" };
			for (int i = 0; i < array.Length; i++)
			{
				try
				{
					Shader val = Shader.Find(array[i]);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Material val2 = new Material(val);
					val2.color = colour;
					try
					{
						val2.SetColor("_BaseColor", colour);
					}
					catch
					{
					}
					return val2;
				}
				catch
				{
				}
			}
			return null;
		}

		private static AnimationCurve TaperedWidth()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			AnimationCurve val = new AnimationCurve();
			val.AddKey(0f, 1f);
			val.AddKey(0.92f, 1f);
			val.AddKey(1f, 0.75f);
			return val;
		}

		private static Material MakeRopeMaterial()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			string[] array = new string[3] { "Universal Render Pipeline/Unlit", "Universal Render Pipeline/Lit", "Sprites/Default" };
			Texture2D val = (_lastTexture = MakeRopeTexture());
			for (int i = 0; i < array.Length; i++)
			{
				try
				{
					Shader val2 = Shader.Find(array[i]);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					Material val3 = new Material(val2);
					if ((Object)(object)val != (Object)null)
					{
						val3.mainTexture = (Texture)(object)val;
						try
						{
							val3.SetTexture("_BaseMap", (Texture)(object)val);
						}
						catch
						{
						}
						Vector2 val4 = (val3.mainTextureScale = Vector2.one);
						try
						{
							val3.SetTextureScale("_BaseMap", val4);
						}
						catch
						{
						}
					}
					val3.color = Color.white;
					try
					{
						val3.SetColor("_BaseColor", Color.white);
					}
					catch
					{
					}
					return val3;
				}
				catch
				{
				}
			}
			Core.Log.Warning("[Rope] no usable shader found - the rope will draw with the default material.");
			return null;
		}

		private static Texture2D MakeRopeTexture()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D val = new Texture2D(96, 16, (TextureFormat)4, false);
				((Texture)val).wrapMode = (TextureWrapMode)0;
				((Texture)val).filterMode = (FilterMode)1;
				((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(0.44f, 0.36f, 0.25f, 1f);
				Color val3 = default(Color);
				((Color)(ref val3))..ctor(0.15f, 0.12f, 0.08f, 1f);
				for (int i = 0; i < 16; i++)
				{
					float num = ((float)i + 0.5f) / 16f;
					float num2 = 1f - Mathf.Abs(num * 2f - 1f);
					num2 = Mathf.Sqrt(Mathf.Clamp01(num2));
					for (int j = 0; j < 96; j++)
					{
						float num3 = ((float)j + (float)i * 0.75f) / 96f * 9f;
						float num4 = Mathf.Sin((num3 - Mathf.Floor(num3)) * (float)Math.PI);
						float num5 = Mathf.Clamp01(0.25f + 0.75f * num4) * (0.55f + 0.45f * num2);
						float num6 = (float)((j * 7 + i * 13) % 5) * 0.012f;
						Color val4 = Color.Lerp(val3, val2, Mathf.Clamp01(num5 + num6));
						val.SetPixel(j, i, val4);
					}
				}
				val.Apply(false, false);
				return val;
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Rope] could not build the rope texture, falling back to flat colour: " + ex.Message);
				return null;
			}
		}
	}
}
namespace Yoink.Net
{
	internal static class QuestRpcPatches
	{
		internal static void Apply(Harmony h)
		{
			TryPatch(h, "RpcLogic___SendQuestState", "SendStatePrefix");
			TryPatch(h, "RpcLogic___ReceiveQuestState", "ReceiveStatePrefix");
		}

		private static void TryPatch(Harmony h, string namePrefix, string prefixMethod)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = typeof(QuestManager).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.StartsWith(namePrefix, StringComparison.Ordinal));
				if (methodInfo == null)
				{
					Core.Log.Warning("[Net] could not find " + namePrefix + " - co-op winching disabled.");
					return;
				}
				MethodInfo method = typeof(QuestRpcPatches).GetMethod(prefixMethod, BindingFlags.Static | BindingFlags.NonPublic);
				h.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Net] patch " + namePrefix + " failed: " + ex.Message);
			}
		}

		private static bool SendStatePrefix(string __0)
		{
			if (YoinkMsg.TryDecode(__0, out var msg))
			{
				YoinkNet.DispatchServerIntent(msg);
				return false;
			}
			return true;
		}

		private static bool ReceiveStatePrefix(string __1)
		{
			if (YoinkMsg.TryDecode(__1, out var msg))
			{
				YoinkNet.DispatchClientState(msg);
				return false;
			}
			return true;
		}
	}
	internal static class RemotePulls
	{
		private sealed class Entry
		{
			internal string Id;

			internal Vector3 PivotLocal;

			internal Vector3 Anchor;

			internal Rigidbody Rb;

			internal Transform Root;

			internal LandVehicle Vehicle;

			internal NPC Npc;

			internal Il2CppReferenceArray<Rigidbody> Parts;
		}

		private static readonly Dictionary<string, Entry> _active = new Dictionary<string, Entry>(StringComparer.Ordinal);

		internal static int Count => _active.Count;

		internal static void Clear()
		{
			_active.Clear();
		}

		internal static void Install()
		{
			YoinkNet.OnServerIntent = OnServerIntent;
			YoinkNet.OnClientState = OnClientState;
		}

		private static void OnServerIntent(YoinkMsg m)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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)
			if (m == null)
			{
				return;
			}
			switch (m.Op)
			{
			case YoinkOp.PullStart:
			{
				Entry entry = Resolve(m.TargetId);
				if (entry == null)
				{
					Core.Log.Warning("[Net] host cannot resolve pull target '" + m.TargetId + "'.");
					break;
				}
				entry.PivotLocal = m.PivotLocal;
				entry.Anchor = m.Anchor;
				bool flag = false;
				try
				{
					flag = (Object)(object)entry.Vehicle != (Object)null && VehicleGrip.HasPlayerDriver(entry.Vehicle);
				}
				catch
				{
				}
				if (flag)
				{
					_active.Remove(m.TargetId);
					YoinkMsg m2 = new YoinkMsg
					{
						Op = YoinkOp.DriverPull,
						TargetId = m.TargetId,
						PivotLocal = m.PivotLocal,
						Anchor = m.Anchor
					};
					YoinkNet.BroadcastToAll(m2);
					ApplyDriverPullLocally(m2);
					Core.Log.Msg("[Net] '" + m.TargetId + "' is occupied - pull handed to the driver's client.");
				}
				else
				{
					if ((Object)(object)entry.Vehicle != (Object)null)
					{
						VehicleGrip.TakeShared(entry.Vehicle);
					}
					if ((Object)(object)entry.Npc != (Object)null)
					{
						NpcGrip.TryHold(entry.Npc, ((Object)(object)entry.Root != (Object)null) ? entry.Root.TransformPoint(entry.PivotLocal) : entry.Anchor, entry.Anchor);
					}
					_active[m.TargetId] = entry;
				}
				break;
			}
			case YoinkOp.PullStop:
			{
				if (_active.TryGetValue(m.TargetId, out var value))
				{
					if ((Object)(object)value.Vehicle != (Object)null)
					{
						VehicleGrip.ReleaseShared(value.Vehicle);
					}
					if ((Object)(object)value.Npc != (Object)null)
					{
						NpcGrip.Release(value.Npc);
					}
				}
				_active.Remove(m.TargetId);
				YoinkNet.BroadcastToAll(new YoinkMsg
				{
					Op = YoinkOp.DriverStop,
					TargetId = m.TargetId
				});
				StopDriverPullLocally(m.TargetId);
				break;
			}
			}
		}

		private static void OnClientState(YoinkMsg m)
		{
			if (m != null)
			{
				if (m.Op == YoinkOp.DriverPull)
				{
					ApplyDriverPullLocally(m);
				}
				else if (m.Op == YoinkOp.DriverStop)
				{
					StopDriverPullLocally(m.TargetId);
				}
			}
		}

		private static void ApplyDriverPullLocally(YoinkMsg m)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Entry entry = Resolve(m.TargetId);
			if (entry != null && !((Object)(object)entry.Vehicle == (Object)null))
			{
				bool flag = false;
				try
				{
					flag = entry.Vehicle.LocalPlayerIsDriver;
				}
				catch
				{
				}
				if (flag)
				{
					entry.PivotLocal = m.PivotLocal;
					entry.Anchor = m.Anchor;
					_active[m.TargetId] = entry;
				}
			}
		}

		private static void StopDriverPullLocally(string id)
		{
			_active.Remove(id);
		}

		internal static void FixedTick()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (_active.Count == 0)
			{
				return;
			}
			List<string> list = null;
			foreach (KeyValuePair<string, Entry> item in _active)
			{
				Entry value = item.Value;
				bool flag;
				try
				{
					flag = (Object)(object)value.Rb != (Object)null && (Object)(object)value.Root != (Object)null;
				}
				catch
				{
					flag = false;
				}
				if (!flag)
				{
					(list ?? (list = new List<string>())).Add(item.Key);
					continue;
				}
				Vector3 pivotWorld = value.Root.TransformPoint(value.PivotLocal);
				float distance;
				float alongRope;
				if ((Object)(object)value.Npc != (Object)null)
				{
					PullPhysics.ApplyToRagdoll(value.Parts, value.Rb, pivotWorld, value.Anchor, Vector3.zero, out distance, out alongRope);
				}
				else
				{
					PullPhysics.Apply(value.Rb, pivotWorld, value.Anchor, Vector3.zero, out distance, out alongRope);
				}
			}
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					_active.Remove(list[i]);
				}
			}
		}

		private static Entry Resolve(string id)
		{
			//IL_0028: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(id) || id.Length < 3)
			{
				return null;
			}
			try
			{
				string text = id.Substring(2);
				if (id[0] == 'V')
				{
					LandVehicle val = GUIDManager.GetObject<LandVehicle>(new Guid(text));
					if ((Object)(object)val == (Object)null || (Object)(object)val.Rb == (Object)null)
					{
						return null;
					}
					return new Entry
					{
						Id = id,
						Rb = val.Rb,
						Root = ((Component)val).transform,
						Vehicle = val
					};
				}
				if (id[0] == 'D')
				{
					Draggable val2 = GUIDManager.GetObject<Draggable>(new Guid(text));
					if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Rigidbody == (Object)null)
					{
						return null;
					}
					return new Entry
					{
						Id = id,
						Rb = val2.Rigidbody,
						Root = ((Component)val2).transform
					};
				}
				if (id[0] == 'N')
				{
					int num = text.LastIndexOf(':');
					if (num <= 0)
					{
						return null;
					}
					if (!int.TryParse(text.Substring(num + 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
					{
						return null;
					}
					NPC val3 = GUIDManager.GetObject<NPC>(new Guid(text.Substring(0, num)));
					if ((Object)(object)val3 == (Object)null)
					{
						return null;
					}
					Rigidbody val4 = NpcGrip.LimbAt(val3, result);
					if ((Object)(object)val4 == (Object)null)
					{
						return null;
					}
					return new Entry
					{
						Id = id,
						Rb = val4,
						Root = ((Component)val4).transform,
						Npc = val3,
						Parts = NpcGrip.PartsOf(val3)
					};
				}
			}
			catch (Exception ex)
			{
				Core.Log.Warning("[Net] resolving '" + id + "' failed: " + ex.Message);
			}
			return null;
		}
	}
	internal enum YoinkOp
	{
		PullStart = 1,
		PullStop,
		DriverPull,
		DriverStop
	}
	internal sealed class YoinkMsg
	{
		internal YoinkOp Op;

		internal string TargetId = string.Empty;

		internal Vector3 PivotLocal;

		internal Vector3 Anchor;

		private const string Prefix = "YNK";

		internal string Encode()
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string[] obj = new string[9] { "YNK", null, null, null, null, null, null, null, null };
			int op = (int)Op;
			obj[1] = op.ToString(invariantCulture);
			obj[2] = TargetId;
			obj[3] = PivotLocal.x.ToString("R", invariantCulture);
			obj[4] = PivotLocal.y.ToString("R", invariantCulture);
			obj[5] = PivotLocal.z.ToString("R", invariantCulture);
			obj[6] = Anchor.x.ToString("R", invariantCulture);
			obj[7] = Anchor.y.ToString("R", invariantCulture);
			obj[8] = Anchor.z.ToString("R", invariantCulture);
			return string.Join("|", obj);
		}

		internal static bool TryDecode(string raw, out YoinkMsg msg)
		{
			//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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due