Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Yoink v1.2.0
Yoink.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
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