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 _held = new Dictionary(); 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 list = null; foreach (KeyValuePair 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())).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 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)(object)val).Length; i++) { Rigidbody val2 = ((Il2CppArrayBase)(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 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 val = (((Object)(object)npc != (Object)null && (Object)(object)npc.Avatar != (Object)null) ? npc.Avatar.RagdollRBs : null); if (val == null || index < 0 || index >= ((Il2CppArrayBase)(object)val).Length) { return null; } return ((Il2CppArrayBase)(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 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)(object)parts).Length; i++) { Rigidbody val3 = ((Il2CppArrayBase)(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)(object)parts).Length; j++) { Rigidbody val4 = ((Il2CppArrayBase)(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 _held = new Dictionary(); 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 list = null; List list2 = null; foreach (KeyValuePair 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())).Add(item.Key); } else if (HasPlayerDriver(vehicle)) { (list2 ?? (list2 = new List())).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 list = new List(_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 occupantNPCs = v.OccupantNPCs; if (occupantNPCs == null) { return false; } for (int i = 0; i < ((Il2CppArrayBase)(object)occupantNPCs).Length; i++) { if ((Object)(object)((Il2CppArrayBase)(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 occupantNPCs = v.OccupantNPCs; for (int i = 0; i < ((Il2CppArrayBase)(object)occupantNPCs).Length; i++) { if (!((Object)(object)((Il2CppArrayBase)(object)occupantNPCs)[i] == (Object)null)) { text = NpcGrip.SafeName(((Il2CppArrayBase)(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.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.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 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)(object)Parts).Length; i++) { if ((Object)(object)((Il2CppArrayBase)(object)Parts)[i] != (Object)null) { num += ((Il2CppArrayBase)(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() != (Object)null) { reason = "that is you"; return false; } } catch { } NPC val2 = null; try { val2 = ((Component)collider).GetComponentInParent(); } 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(); } 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(); } 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(); } 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.op_Implicit((Il2CppArrayBase)(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() != (Object)null) { continue; } } catch { } try { if ((Object)(object)((Component)val3).GetComponentInParent() != (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() != (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(); } catch { } try { winchTarget.Draggable = ((Component)val2).GetComponentInParent(); } 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.op_Implicit((Il2CppArrayBase)(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(); } 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(); _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(); 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(); 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 Parts; } private static readonly Dictionary _active = new Dictionary(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 list = null; foreach (KeyValuePair 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())).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(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(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(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 to invalid IL or missing references) msg = null; if (string.IsNullOrEmpty(raw) || raw.Length < 4 || raw[0] != 'Y' || !raw.StartsWith("YNK|", StringComparison.Ordinal)) { return false; } string[] array = raw.Split('|'); if (array.Length != 9) { return false; } try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; msg = new YoinkMsg { Op = (YoinkOp)int.Parse(array[1], invariantCulture), TargetId = array[2], PivotLocal = new Vector3(float.Parse(array[3], NumberStyles.Float, invariantCulture), float.Parse(array[4], NumberStyles.Float, invariantCulture), float.Parse(array[5], NumberStyles.Float, invariantCulture)), Anchor = new Vector3(float.Parse(array[6], NumberStyles.Float, invariantCulture), float.Parse(array[7], NumberStyles.Float, invariantCulture), float.Parse(array[8], NumberStyles.Float, invariantCulture)) }; return true; } catch { msg = null; return false; } } public override string ToString() { return Op.ToString() + " " + TargetId; } } internal static class YoinkNet { internal static Action OnServerIntent; internal static Action OnClientState; private static NetworkManager Nm { get { try { return InstanceFinder.NetworkManager; } catch { return null; } } } internal static bool Online { get { NetworkManager nm = Nm; try { return (Object)(object)nm != (Object)null && (nm.IsServer || nm.IsClient); } catch { return false; } } } internal static bool IsServer { get { NetworkManager nm = Nm; try { return (Object)(object)nm != (Object)null && nm.IsServer; } catch { return false; } } } private static QuestManager Qm { get { try { return NetworkSingleton.Instance; } catch { return null; } } } internal static void SendToHost(YoinkMsg m) { try { QuestManager qm = Qm; if ((Object)(object)qm == (Object)null) { Core.Log.Warning("[Net] no QuestManager - " + m?.ToString() + " dropped."); } else { qm.SendQuestState(m.Encode(), (EQuestState)0); } } catch (Exception ex) { Core.Log.Warning("[Net] send failed: " + ex.Message); } } internal static void BroadcastToAll(YoinkMsg m) { try { QuestManager qm = Qm; if (!((Object)(object)qm == (Object)null)) { qm.ReceiveQuestState((NetworkConnection)null, m.Encode(), (EQuestState)0); } } catch (Exception ex) { Core.Log.Warning("[Net] broadcast failed: " + ex.Message); } } internal static void DispatchServerIntent(YoinkMsg m) { try { OnServerIntent?.Invoke(m); } catch (Exception ex) { Core.Log.Warning("[Net] server dispatch failed: " + ex.Message); } } internal static void DispatchClientState(YoinkMsg m) { try { if (IsServer) { OnServerIntent?.Invoke(m); } else { OnClientState?.Invoke(m); } } catch (Exception ex) { Core.Log.Warning("[Net] dispatch failed: " + ex.Message); } } } } namespace Yoink.Item { internal static class IconRenderer { private const int Size = 256; private const int Layer = 31; private static readonly Vector3 Nowhere = new Vector3(0f, -10000f, 0f); private static Sprite _cached; internal static Sprite Render(GameObject model) { //IL_0042: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00a8: 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_00c6: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown if ((Object)(object)_cached != (Object)null) { return _cached; } if ((Object)(object)model == (Object)null) { return null; } GameObject val = null; GameObject val2 = null; RenderTexture val3 = null; RenderTexture active = RenderTexture.active; try { val = Object.Instantiate(model); ((Object)val).name = "YoinkIconSubject"; val.transform.position = Nowhere; val.transform.rotation = Quaternion.identity; val.transform.localScale = Vector3.one; val.SetActive(true); SetLayerRecursively(val.transform, 31); if (!TryBounds(val.transform, out var bounds)) { return null; } val2 = new GameObject("YoinkIconRig"); val2.transform.position = Nowhere; Quaternion val4 = Quaternion.Euler(18f, 35f, 0f); Vector3 val5 = val4 * Vector3.forward; GameObject val6 = new GameObject("YoinkIconCamera"); val6.transform.SetParent(val2.transform, false); Transform transform = val6.transform; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; transform.position = center - val5 * (((Vector3)(ref extents)).magnitude * 4f + 1f); val6.transform.rotation = val4; Camera obj = val6.AddComponent(); obj.clearFlags = (CameraClearFlags)2; obj.backgroundColor = new Color(0f, 0f, 0f, 0f); obj.cullingMask = int.MinValue; obj.orthographic = true; obj.orthographicSize = ProjectedRadius(bounds, val4) * 1.12f; obj.nearClipPlane = 0.01f; extents = ((Bounds)(ref bounds)).extents; obj.farClipPlane = ((Vector3)(ref extents)).magnitude * 8f + 10f; ((Behaviour)obj).enabled = false; obj.allowHDR = false; obj.allowMSAA = false; AddLight(val2.transform, val4 * Quaternion.Euler(25f, -30f, 0f), 1.35f); AddLight(val2.transform, val4 * Quaternion.Euler(-15f, 140f, 0f), 0.55f); val3 = new RenderTexture(256, 256, 24, (RenderTextureFormat)0) { antiAliasing = 8 }; val3.Create(); obj.targetTexture = val3; obj.Render(); RenderTexture.active = val3; Texture2D val7 = new Texture2D(256, 256, (TextureFormat)5, false) { name = "YoinkIcon", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; val7.ReadPixels(new Rect(0f, 0f, 256f, 256f), 0, 0, false); val7.Apply(); _cached = Sprite.Create(val7, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f); if ((Object)(object)_cached != (Object)null) { ((Object)_cached).hideFlags = (HideFlags)61; } Core.Log.Msg("[Icon] item icon rendered from the winch model (" + 256 + "px)."); return _cached; } catch (Exception ex) { Core.Log.Warning("[Icon] could not render the item icon, falling back to a vanilla sprite: " + ex.Message); return null; } finally { RenderTexture.active = active; try { if ((Object)(object)val3 != (Object)null) { val3.Release(); Object.Destroy((Object)(object)val3); } } catch { } try { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } catch { } try { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } catch { } } } private static void AddLight(Transform parent, Quaternion rotation, float intensity) { //IL_0005: 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_0017: 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) GameObject val = new GameObject("YoinkIconLight"); val.transform.SetParent(parent, false); val.transform.rotation = rotation; Light obj = val.AddComponent(); obj.type = (LightType)1; obj.intensity = intensity; obj.cullingMask = int.MinValue; obj.shadows = (LightShadows)0; } private static float ProjectedRadius(Bounds b, Quaternion look) { //IL_0002: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001f: 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_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_007e: 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) Vector3 extents = ((Bounds)(ref b)).extents; Vector3 val = look * Vector3.right; Vector3 val2 = look * Vector3.up; float num = Mathf.Abs(val.x) * extents.x + Mathf.Abs(val.y) * extents.y + Mathf.Abs(val.z) * extents.z; float num2 = Mathf.Abs(val2.x) * extents.x + Mathf.Abs(val2.y) * extents.y + Mathf.Abs(val2.z) * extents.z; return Mathf.Max(0.01f, Mathf.Max(num, num2)); } private static bool TryBounds(Transform root, out Bounds bounds) { //IL_0001: 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_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) bounds = default(Bounds); bool flag = false; foreach (Renderer componentsInChild in ((Component)root).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild == (Object)null)) { if (!flag) { bounds = componentsInChild.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(componentsInChild.bounds); } } } return flag; } private static void SetLayerRecursively(Transform t, int layer) { if (!((Object)(object)t == (Object)null)) { ((Component)t).gameObject.layer = layer; for (int i = 0; i < t.childCount; i++) { SetLayerRecursively(t.GetChild(i), layer); } } } } internal static class WinchAim { private const float BlendTime = 0.18f; private static float _aim; private static float _velocity; internal static void Reset() { _aim = 0f; _velocity = 0f; } internal static void Tick(bool held, bool hooked) { try { float num = ((held && hooked) ? 1f : 0f); if (held || !(_aim <= 0.001f)) { _aim = Mathf.SmoothDamp(_aim, num, ref _velocity, 0.18f); if (_aim < 0.001f) { _aim = 0f; } ViewmodelAvatar instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.Animator == (Object)null)) { instance.Animator.SetFloat("Aim", _aim); } } } catch { } } } internal static class WinchEquippable { private static GameObject _bank; private static GameObject _template; private static bool _failed; internal static bool Ready => (Object)(object)_template != (Object)null; internal static void ResetSession() { try { if ((Object)(object)_bank != (Object)null) { Object.Destroy((Object)(object)_bank); } } catch { } _bank = null; _template = null; _failed = false; } internal static void EnsureInstalled(GameObject model) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) if (_failed || (Object)(object)_template != (Object)null || (Object)(object)model == (Object)null) { return; } try { ViewmodelAvatar instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.Animator == (Object)null || (Object)(object)instance.RightHandContainer == (Object)null) { return; } Equippable_AvatarViewmodel val = FindDonor(); if ((Object)(object)val == (Object)null) { _failed = true; return; } _bank = new GameObject("YoinkEquippableTemplates"); _bank.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_bank); _template = new GameObject("YoinkWinchEquippable"); _template.transform.SetParent(_bank.transform, false); _template.SetActive(true); Equippable_AvatarViewmodel obj = _template.AddComponent(); obj.AnimatorController = val.AnimatorController; obj.ViewmodelAvatarOffset = val.ViewmodelAvatarOffset; obj.ViewmodelAvatarRotationOffset = val.ViewmodelAvatarRotationOffset; obj.EquipTrigger = val.EquipTrigger ?? string.Empty; obj.EquipTime = val.EquipTime; ((Equippable_Viewmodel)obj).localPosition = ((Equippable_Viewmodel)val).localPosition; ((Equippable_Viewmodel)obj).localEulerAngles = ((Equippable_Viewmodel)val).localEulerAngles; ((Equippable_Viewmodel)obj).localScale = ((Equippable_Viewmodel)val).localScale; ((Equippable_Viewmodel)obj).AvatarEquippable = null; ((Equippable)obj).CanInteractWhenEquipped = true; ((Equippable)obj).CanPickUpWhenEquipped = true; GameObject obj2 = Object.Instantiate(model, _template.transform); ((Object)obj2).name = "YoinkWinchModel"; obj2.transform.localPosition = WinchItem.HeldPosition; obj2.transform.localRotation = Quaternion.Euler(WinchItem.HeldRotation); obj2.transform.localScale = Vector3.one * WinchItem.HeldScale; obj2.SetActive(true); if (!PointDefinitionAtTemplate(obj)) { _failed = true; } else { Core.Log.Msg("[Item] winch equippable installed - the game now holds it like a weapon."); } } catch (Exception ex) { _failed = true; Core.Log.Warning("[Item] could not install the winch equippable, falling back to the loose model: " + ex.Message); } } private static bool PointDefinitionAtTemplate(Equippable_AvatarViewmodel eq) { try { ItemDefinition item = Registry.GetItem("yoink_winch"); if ((Object)(object)item == (Object)null) { Core.Log.Warning("[Item] the winch is not in the registry yet."); return false; } StorableItemDefinition val = ((Il2CppObjectBase)item).TryCast(); if ((Object)(object)val == (Object)null) { Core.Log.Warning("[Item] the winch definition is not storable."); return false; } ((ItemDefinition)val).Equippable = (Equippable)(object)eq; ((ItemDefinition)val).EquipMode = (EEquipMode)0; return true; } catch (Exception ex) { Core.Log.Warning("[Item] could not point the definition at the equippable: " + ex.Message); return false; } } private static Equippable_AvatarViewmodel FindDonor() { string[] array = new string[4] { "m1911", "revolver", "baton", "pumpshotgun" }; for (int i = 0; i < array.Length; i++) { try { ItemDefinition item = Registry.GetItem(array[i]); if (!((Object)(object)item == (Object)null) && !((Object)(object)item.Equippable == (Object)null)) { Equippable_AvatarViewmodel component = ((Component)item.Equippable).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.AnimatorController == (Object)null)) { Core.Log.Msg("[Item] copying the held-item setup from '" + array[i] + "'."); return component; } } } catch { } } Core.Log.Warning("[Item] no vanilla held item to copy from - the winch stays a loose model in front of the camera."); return null; } } internal static class WinchItem { internal const string Id = "yoink_winch"; private static bool _registered; private static float _nextClickAt; private static bool _wasEquipped; internal static Vector3 ViewmodelPosition = new Vector3(0.1f, -0.17f, 0.15f); internal static Vector3 ViewmodelRotation = new Vector3(0f, 180f, 0f); internal static float ViewmodelScale = 0.25f; internal static bool PreferHand = false; internal static Vector3 HandPosition = new Vector3(0f, 0f, 0f); internal static Vector3 HandRotation = new Vector3(0f, 0f, 0f); internal static float HandScale = 1f; private static bool _onHand; private static RuntimeAnimatorController _borrowedAnimator; private static Vector3 _borrowedOffset; private static Vector3 _borrowedRotationOffset; internal static bool ShowArms = true; private static bool _armsRaised; internal static Vector3 MuzzleLocal = new Vector3(0f, 0.09f, -0.3f); internal static Vector3 MuzzleOverride = Vector3.zero; internal static float RopeStartDepth = 0.7f; internal static Vector2 RopeAnchorNudge = new Vector2(0.12f, 0.11f); private static Camera _viewmodelCamera; private static int _viewmodelCameraLayer = -1; private static Transform _heldModel; internal static Vector3 RigOffset = new Vector3(0f, 0.005f, 0f); private static GameObject _modelSource; private static GameObject _modelInstance; private static int _viewmodelId; private static bool _modelFailed; internal static Vector3 GripLocal = new Vector3(0f, -0.01f, -0.066f); internal static Vector3 HeldRotation = new Vector3(0f, 180f, 0f); internal static float HeldScale = 0.7f; private static bool _heldPositionOverridden; private static Vector3 _heldPosition; internal static Vector3 HeldOffset = new Vector3(0f, 0f, -0.08f); internal static bool Available => _registered; internal static Vector3 HeldPosition { get { //IL_0035: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!_heldPositionOverridden) { return -(Quaternion.Euler(HeldRotation) * GripLocal) * HeldScale + HeldOffset; } return _heldPosition; } set { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) _heldPosition = value; _heldPositionOverridden = true; } } internal static void ResetSession() { _registered = false; WinchEquippable.ResetSession(); } internal static void EnsureRegistered() { //IL_0049: 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) if (_registered) { return; } try { try { if (ItemManager.GetDefinition("yoink_winch") != (ItemDefinition)null) { _registered = true; return; } } catch { } Equippable val = ItemCreator.CreateEquippableBuilder().CreateViewmodelEquippable("YoinkWinchEquippable").WithViewmodelTransform(new Vector3(0.18f, -0.16f, 0.34f), new Vector3(0f, 200f, 0f), (Vector3?)Vector3.one) .WithInteraction(true, true) .WithAvatarEquippable("avatar/equippables/M1911", (AvatarHand)1, "RightArm_Hold_ClosedHand") .Build(); ((StorableItemDefinitionBuilderBase)(object)((StorableItemDefinitionBuilderBase)(object)((StorableItemDefinitionBuilderBase)(object)((StorableItemDefinitionBuilderBase)(object)((StorableItemDefinitionBuilderBase)(object)((StorableItemDefinitionBuilderBase)(object)ItemCreator.CreateBuilder()).WithBasicInfo("yoink_winch", "Winch", "Hooks whatever you aim at and drags it out. Right click and hold to reel.", (ItemCategory)3)).WithStackLimit(1)).WithPricing(Preferences.ShopPrice, 0.4f)).WithLegalStatus((LegalStatus)0)).WithIcon(Icon())).WithEquippable(val).Build(); _registered = true; Core.Log.Msg("[Item] winch registered ('yoink_winch')."); } catch (Exception ex) { Core.Log.Warning("[Item] winch registration failed - console commands still work: " + ex.Message); } } private static Transform PrepareHands() { //IL_0046: 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) try { ViewmodelAvatar instance = Singleton.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.RightHandContainer == (Object)null) { return null; } RuntimeAnimatorController val = BorrowedAnimator(); if ((Object)(object)val == (Object)null) { return null; } instance.SetAnimatorController(val); instance.SetVisibility(true); instance.SetOffset(_borrowedOffset); instance.SetRotationOffset(_borrowedRotationOffset); try { if ((Object)(object)instance.Animator != (Object)null) { instance.Animator.SetTrigger("Equip"); } } catch { } return instance.RightHandContainer; } catch (Exception ex) { Core.Log.Warning("[Item] could not raise the first-person arms: " + ex.Message); return null; } } private static RuntimeAnimatorController BorrowedAnimator() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_borrowedAnimator != (Object)null) { return _borrowedAnimator; } string[] array = new string[4] { "m1911", "revolver", "pumpshotgun", "baton" }; for (int i = 0; i < array.Length; i++) { try { ItemDefinition item = Registry.GetItem(array[i]); if (!((Object)(object)item == (Object)null) && !((Object)(object)item.Equippable == (Object)null)) { Equippable_AvatarViewmodel component = ((Component)item.Equippable).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.AnimatorController == (Object)null)) { _borrowedAnimator = component.AnimatorController; _borrowedOffset = component.ViewmodelAvatarOffset; _borrowedRotationOffset = component.ViewmodelAvatarRotationOffset; Core.Log.Msg("[Item] borrowed the first-person arm pose from '" + array[i] + "' (offset " + ((Vector3)(ref _borrowedOffset)).ToString("F3") + ", rot " + ((Vector3)(ref _borrowedRotationOffset)).ToString("F0") + ")."); return _borrowedAnimator; } } } catch { } } Core.Log.Warning("[Item] found no vanilla animator controller to borrow - the winch will be held without arms."); return null; } private static void RaiseArms() { //IL_002a: 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) try { ViewmodelAvatar instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null)) { RuntimeAnimatorController val = BorrowedAnimator(); if (!((Object)(object)val == (Object)null)) { instance.SetAnimatorController(val); instance.SetOffset(_borrowedOffset); instance.SetRotationOffset(_borrowedRotationOffset); instance.SetVisibility(true); _armsRaised = true; } } } catch { } } private static void KeepHandsUp() { if (!_onHand && !_armsRaised) { return; } try { ViewmodelAvatar instance = Singleton.Instance; if ((Object)(object)instance != (Object)null && !instance.IsVisible) { instance.SetVisibility(true); } } catch { } } private static void LowerHands() { try { ViewmodelAvatar instance = Singleton.Instance; if ((Object)(object)instance != (Object)null) { instance.SetVisibility(false); } } catch { } } private static Transform FindByName(Transform t, string name, int depth) { if ((Object)(object)t == (Object)null || depth > 12) { return null; } if (((Object)t).name == name) { return t; } for (int i = 0; i < t.childCount; i++) { Transform val = FindByName(t.GetChild(i), name, depth + 1); if ((Object)(object)val != (Object)null) { return val; } } return null; } internal static bool TryGetMuzzle(out Vector3 world) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_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) world = Vector3.zero; try { Transform val = HeldModel(); if ((Object)(object)val == (Object)null) { return false; } Vector3 world2; if (MuzzleOverride != Vector3.zero) { world2 = val.TransformPoint(MuzzleOverride); } else if (!TryMeasureMuzzle(out world2)) { world2 = MeasuredMuzzle(val); } world = ToRopeAnchor(world2, ((Component)val).gameObject.layer); return true; } catch { return false; } } private static Vector3 ToRopeAnchor(Vector3 onModel, int layer) { //IL_000f: 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_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) //IL_0024: 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_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_0075: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Camera val = WorldCamera(); if ((Object)(object)val == (Object)null) { return onModel; } Vector3 val2 = (ViewmodelCamera(layer, val) ?? val).WorldToScreenPoint(onModel); if (val2.z <= 0.001f) { return onModel; } val2.x += RopeAnchorNudge.x * (float)Screen.height; val2.y += RopeAnchorNudge.y * (float)Screen.height; Ray val3 = val.ScreenPointToRay(val2); float num = Vector3.Dot(((Ray)(ref val3)).direction, ((Component)val).transform.forward); float num2 = Mathf.Max(RopeStartDepth, (val.nearClipPlane + 0.05f) / Mathf.Max(num, 0.2f)); return ((Ray)(ref val3)).origin + ((Ray)(ref val3)).direction * num2; } internal static List DescribeCameras() { //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_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) CultureInfo invariantCulture = CultureInfo.InvariantCulture; List list = new List(); try { Camera val = WorldCamera(); Vector3 val2; object obj2; if (!((Object)(object)val == (Object)null)) { string[] obj = new string[9] { ((Object)val).name, " at ", null, null, null, null, null, null, null }; val2 = ((Component)val).transform.position; obj[2] = ((Vector3)(ref val2)).ToString("F2"); obj[3] = " fov "; obj[4] = val.fieldOfView.ToString("F1", invariantCulture); obj[5] = " near "; obj[6] = val.nearClipPlane.ToString("F2", invariantCulture); obj[7] = " mask 0x"; obj[8] = val.cullingMask.ToString("X"); obj2 = string.Concat(obj); } else { obj2 = "none"; } list.Add("world camera: " + (string?)obj2); int num = LayerMask.NameToLayer("Viewmodel"); list.Add("'Viewmodel' layer = " + num); Il2CppReferenceArray allCameras = Camera.allCameras; list.Add(((Il2CppArrayBase)(object)allCameras).Length + " enabled camera(s):"); for (int i = 0; i < ((Il2CppArrayBase)(object)allCameras).Length; i++) { Camera val3 = ((Il2CppArrayBase)(object)allCameras)[i]; if (!((Object)(object)val3 == (Object)null)) { bool flag = num >= 0 && (val3.cullingMask & (1 << num)) != 0; string[] obj3 = new string[11] { " ", ((Object)val3).name, " pos ", null, null, null, null, null, null, null, null }; val2 = ((Component)val3).transform.position; obj3[3] = ((Vector3)(ref val2)).ToString("F2"); obj3[4] = " fov "; obj3[5] = val3.fieldOfView.ToString("F1", invariantCulture); obj3[6] = " depth "; obj3[7] = val3.depth.ToString("F0", invariantCulture); obj3[8] = " mask 0x"; obj3[9] = val3.cullingMask.ToString("X"); obj3[10] = (flag ? " <- draws Viewmodel" : string.Empty); list.Add(string.Concat(obj3)); } } Transform val4 = HeldModel(); if ((Object)(object)val4 == (Object)null) { list.Add("no winch in hand - equip it and run this again."); return list; } string text = ((Component)val4).gameObject.layer.ToString(); val2 = val4.position; list.Add("model: layer " + text + " world pos " + ((Vector3)(ref val2)).ToString("F2")); if (!TryMeasureMuzzle(out var world)) { world = MeasuredMuzzle(val4); } string text2 = ((Vector3)(ref world)).ToString("F3"); val2 = val4.InverseTransformPoint(world); list.Add("muzzle on model: " + text2 + " local " + ((Vector3)(ref val2)).ToString("F3")); if ((Object)(object)val != (Object)null) { Camera val5 = ViewmodelCamera(((Component)val4).gameObject.layer, val) ?? val; Vector3 val6 = val5.WorldToScreenPoint(world); list.Add("projected by '" + ((Object)val5).name + "' -> screen " + ((Vector3)(ref val6)).ToString("F0") + " (screen is " + Screen.width + "x" + Screen.height + ")"); val2 = ToRopeAnchor(world, ((Component)val4).gameObject.layer); list.Add("rope anchor: " + ((Vector3)(ref val2)).ToString("F2")); } } catch (Exception ex) { list.Add("camera dump failed: " + ex.Message); } return list; } private static Camera WorldCamera() { try { PlayerCamera instance = PlayerSingleton.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.Camera != (Object)null) { return instance.Camera; } } catch { } return null; } private static Camera ViewmodelCamera(int layer, Camera world) { //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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_viewmodelCamera != (Object)null && _viewmodelCameraLayer == layer && ((Behaviour)_viewmodelCamera).enabled) { return _viewmodelCamera; } _viewmodelCamera = null; _viewmodelCameraLayer = layer; int instanceID = ((Object)world).GetInstanceID(); Vector3 position = ((Component)world).transform.position; int num = 1 << layer; Il2CppReferenceArray allCameras = Camera.allCameras; for (int i = 0; i < ((Il2CppArrayBase)(object)allCameras).Length; i++) { Camera val = ((Il2CppArrayBase)(object)allCameras)[i]; if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && ((Object)val).GetInstanceID() != instanceID && (val.cullingMask & num) != 0) { Vector3 val2 = ((Component)val).transform.position - position; if (!(((Vector3)(ref val2)).sqrMagnitude > 4f)) { _viewmodelCamera = val; Core.Log.Msg("[Item] rope anchored through the first-person camera '" + ((Object)val).name + "' (fov " + val.fieldOfView.ToString("F0", CultureInfo.InvariantCulture) + " vs world " + world.fieldOfView.ToString("F0", CultureInfo.InvariantCulture) + ")."); break; } } } return _viewmodelCamera; } catch { return null; } } private static Vector3 MeasuredMuzzle(Transform model) { //IL_0002: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_007b: 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_0084: 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_0096: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) Bounds val = default(Bounds); bool flag = false; foreach (Renderer componentsInChild in ((Component)model).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild == (Object)null)) { if (!flag) { val = componentsInChild.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(componentsInChild.bounds); } } } if (!flag) { return model.TransformPoint(MuzzleLocal); } Vector3 val2 = -model.forward; Vector3 extents = ((Bounds)(ref val)).extents; float num = Mathf.Abs(val2.x) * extents.x + Mathf.Abs(val2.y) * extents.y + Mathf.Abs(val2.z) * extents.z; return ((Bounds)(ref val)).center + val2 * num; } private static void ApplyHeldTransform() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) try { Transform val = HeldModel(); if ((Object)(object)val == (Object)null) { return; } val.localPosition = HeldPosition; val.localRotation = Quaternion.Euler(HeldRotation); val.localScale = Vector3.one * HeldScale; } catch { } ApplyRigOffset(); } private static void ApplyRigOffset() { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (RigOffset == Vector3.zero) { return; } try { ViewmodelAvatar instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && instance.IsVisible) { if ((Object)(object)_borrowedAnimator == (Object)null) { BorrowedAnimator(); } instance.SetOffset(_borrowedOffset + RigOffset); } } catch { } } internal static bool TryMuzzleScreen(out Vector2 screen) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0045: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) screen = Vector2.zero; try { Transform val = HeldModel(); Camera val2 = WorldCamera(); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } if (!TryMeasureMuzzle(out var world)) { world = MeasuredMuzzle(val); } Vector3 val3 = val2.WorldToScreenPoint(world); screen = new Vector2(val3.x, val3.y); return true; } catch { return false; } } internal static string DescribeFraming() { //IL_001a: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_006d: Unknown result type (might be due to invalid IL or missing references) CultureInfo invariantCulture = CultureInfo.InvariantCulture; string text; if (!TryMuzzleScreen(out var screen)) { text = "not held"; } else { Vector2 val = screen + new Vector2(RopeAnchorNudge.x, RopeAnchorNudge.y) * (float)Screen.height; bool flag = val.x >= 0f && val.x <= (float)Screen.width && val.y >= 0f && val.y <= (float)Screen.height; text = screen.x.ToString("F0", invariantCulture) + "," + screen.y.ToString("F0", invariantCulture) + " rope starts at " + val.x.ToString("F0", invariantCulture) + "," + val.y.ToString("F0", invariantCulture) + " of " + Screen.width + "x" + Screen.height + (flag ? "" : " << OFF SCREEN"); } return "scale " + HeldScale.ToString("F2", invariantCulture) + " rig " + ((Vector3)(ref RigOffset)).ToString("F3") + "\ntool " + ((Vector3)(ref HeldOffset)).ToString("F3") + " turn " + HeldRotation.y.ToString("F0", invariantCulture) + "/" + HeldRotation.x.ToString("F0", invariantCulture) + "deg\nrope anchor " + RopeStartDepth.ToString("F2", invariantCulture) + "m nudge " + ((Vector2)(ref RopeAnchorNudge)).ToString("F3") + "\nmuzzle on screen: " + text; } internal static void ResetFraming() { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) HeldScale = 0.7f; RigOffset = new Vector3(0f, 0.005f, 0f); HeldOffset = new Vector3(0f, 0f, -0.08f); HeldRotation = new Vector3(0f, 180f, 0f); RopeStartDepth = 0.7f; RopeAnchorNudge = new Vector2(0.12f, 0.11f); _heldPositionOverridden = false; MuzzleOverride = Vector3.zero; } internal static string DescribeHold() { //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) CultureInfo invariantCulture = CultureInfo.InvariantCulture; string[] obj = new string[9] { "hold pos=", null, null, null, null, null, null, null, null }; Vector3 heldPosition = HeldPosition; obj[1] = ((Vector3)(ref heldPosition)).ToString("F3"); obj[2] = " rot="; obj[3] = ((Vector3)(ref HeldRotation)).ToString("F0"); obj[4] = " scale="; obj[5] = HeldScale.ToString("F2", invariantCulture); obj[6] = " grip="; obj[7] = ((Vector3)(ref GripLocal)).ToString("F3"); obj[8] = (((Object)(object)HeldModel() != (Object)null) ? " [live]" : " [not held]"); return string.Concat(obj); } private static bool TryMeasureMuzzle(out Vector3 world) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) world = Vector3.zero; Transform val = HeldModel(); if ((Object)(object)val == (Object)null) { return false; } try { MeshFilter val2 = null; for (int i = 0; i < val.childCount; i++) { if (!((Object)(object)val2 == (Object)null)) { break; } Transform child = val.GetChild(i); if (((Object)child).name.IndexOf("hook", StringComparison.OrdinalIgnoreCase) >= 0) { val2 = ((Component)child).GetComponentInChildren(true); } } if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null) { return false; } Bounds bounds = val2.sharedMesh.bounds; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).min.z); world = ((Component)val2).transform.TransformPoint(val3); return true; } catch { return false; } } private static Transform HeldModel() { try { if ((Object)(object)_heldModel != (Object)null) { return _heldModel; } ViewmodelAvatar instance = Singleton.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.RightHandContainer != (Object)null) { _heldModel = FindByName(instance.RightHandContainer, "YoinkWinchModel", 0); if ((Object)(object)_heldModel != (Object)null) { return _heldModel; } } PlayerInventory instance2 = PlayerSingleton.Instance; Transform val = (((Object)(object)instance2 != (Object)null) ? instance2.EquipContainer : null); if ((Object)(object)val != (Object)null) { _heldModel = FindByName(val, "YoinkWinchModel", 0); } return _heldModel; } catch { return null; } } internal static void ForgetHeldModel() { _heldModel = null; } private static void EnsureViewmodel() { //IL_00f2: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0145: Unknown result type (might be due to invalid IL or missing references) if (_modelFailed) { return; } try { PlayerInventory instance = PlayerSingleton.Instance; Transform val = (((Object)(object)instance != (Object)null) ? instance.EquipContainer : null); if ((Object)(object)val == (Object)null) { return; } Transform val2 = (PreferHand ? PrepareHands() : null); if ((Object)(object)val2 == (Object)null && ShowArms) { RaiseArms(); } Transform val3 = (((Object)(object)val2 != (Object)null) ? val2 : val); int instanceID = ((Object)val3).GetInstanceID(); if ((!((Object)(object)_modelInstance != (Object)null) || instanceID != _viewmodelId) && !((Object)(object)EnsureModelSource() == (Object)null)) { if ((Object)(object)_modelInstance != (Object)null) { Object.Destroy((Object)(object)_modelInstance); } _onHand = (Object)(object)val2 != (Object)null; _modelInstance = Object.Instantiate(_modelSource, val3); ((Object)_modelInstance).name = "YoinkWinchModel"; _modelInstance.transform.localPosition = (_onHand ? HandPosition : ViewmodelPosition); _modelInstance.transform.localRotation = Quaternion.Euler(_onHand ? HandRotation : ViewmodelRotation); _modelInstance.transform.localScale = Vector3.one * (_onHand ? HandScale : ViewmodelScale); _modelInstance.SetActive(true); _viewmodelId = instanceID; Core.Log.Msg("[Item] winch model attached to " + (_onHand ? "the right hand." : "the equip container (no hand bone found).")); } } catch (Exception ex) { _modelFailed = true; Core.Log.Warning("[Item] could not attach the winch model (the item still works, just invisible in hand): " + ex.Message); } } internal static void RemoveViewmodel() { try { if ((Object)(object)_modelInstance != (Object)null) { Object.Destroy((Object)(object)_modelInstance); } } catch { } _modelInstance = null; _viewmodelId = 0; if (_onHand || _armsRaised) { LowerHands(); _onHand = false; _armsRaised = false; } } internal static void RefreshViewmodel() { RemoveViewmodel(); if (!WinchEquippable.Ready) { EnsureViewmodel(); } } internal static GameObject EnsureModelSource() { if ((Object)(object)_modelSource != (Object)null) { return _modelSource; } if (_modelFailed) { return null; } try { byte[] array = ReadEmbedded("Yoink.Assets.yoink_winch.glb"); if (array == null) { _modelFailed = true; return null; } _modelSource = GlbReader.Load(array, "YoinkWinchModel"); if ((Object)(object)_modelSource == (Object)null) { _modelFailed = true; return null; } _modelSource.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_modelSource); return _modelSource; } catch (Exception ex) { _modelFailed = true; Core.Log.Warning("[Item] could not load the winch model: " + ex.Message); return null; } } internal static byte[] ReadEmbeddedPublic(string resource) { return ReadEmbedded(resource); } private static byte[] ReadEmbedded(string resource) { try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource); if (stream == null) { Core.Log.Warning("[Item] embedded resource missing: " + resource); return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } return array; } catch (Exception ex) { Core.Log.Warning("[Item] reading " + resource + " failed: " + ex.Message); return null; } } internal static bool IsEquipped() { try { PlayerInventory instance = PlayerSingleton.Instance; if ((Object)(object)instance == (Object)null || !instance.isAnythingEquipped) { return false; } ItemInstance val = ((instance.equippedSlot != null) ? ((ItemSlot)instance.equippedSlot).ItemInstance : null); return val != null && (Object)(object)val.Definition != (Object)null && ((BaseItemDefinition)val.Definition).ID == "yoink_winch"; } catch { return false; } } internal static void TickControls() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) bool flag = IsEquipped(); if (_wasEquipped && !flag) { if (WinchSession.Hooked) { WinchSession.Drop(); Core.Log.Msg("[Item] winch put away - hook released."); } RemoveViewmodel(); ForgetHeldModel(); } _wasEquipped = flag; WinchAim.Tick(flag, WinchSession.Hooked); WinchSound.Tick(flag && WinchSession.Pulling, WinchSession.ReelRateSmoothed, Preferences.MaxSpeed, WinchSession.Stalled, (flag && WinchSession.Hooked) ? WinchSession.PayOutRate : 0f); if (TryGetMuzzle(out var world)) { WinchSound.FollowMuzzle(world); } if (_registered) { WinchEquippable.EnsureInstalled(EnsureModelSource()); } if (!flag) { return; } if (WinchEquippable.Ready && (Object)(object)_modelInstance != (Object)null) { RemoveViewmodel(); } ApplyHeldTransform(); if (!WinchEquippable.Ready) { EnsureViewmodel(); KeepHandsUp(); } try { if (Time.unscaledTime < _nextClickAt || GameInput.IsTyping || !Input.HookPressed()) { return; } PlayerCamera instance = PlayerSingleton.Instance; if (!((Object)(object)instance != (Object)null) || instance.activeUIElements.Count <= 0) { _nextClickAt = Time.unscaledTime + 0.25f; if (WinchSession.Hooked) { WinchSession.Drop(); return; } WinchSession.HookFromCamera(out var message); Core.Log.Msg("[Item] " + message); } } catch (Exception ex) { Core.Log.Warning("[Item] control tick failed: " + ex.Message); } } internal static bool Give(int quantity = 1) { if (!_registered) { return false; } try { ConsoleHelper.AddItemToInventory("yoink_winch", (int?)quantity); return true; } catch (Exception ex) { Core.Log.Warning("[Item] giving the winch failed: " + ex.Message); return false; } } private static Sprite Icon() { Sprite val = IconRenderer.Render(EnsureModelSource()); if ((Object)(object)val != (Object)null) { return val; } return BorrowedIcon(); } private static Sprite BorrowedIcon() { string[] array = new string[4] { "trashgrabber", "trimmers", "wateringcan", "trashbag" }; for (int i = 0; i < array.Length; i++) { try { ItemDefinition item = Registry.GetItem(array[i]); if ((Object)(object)item != (Object)null && (Object)(object)((BaseItemDefinition)item).Icon != (Object)null) { return ((BaseItemDefinition)item).Icon; } } catch { } } return null; } } internal static class WinchShop { private static bool _listed; private static bool _namesLogged; internal static void ResetSession() { _listed = false; } internal static bool EnsureListed() { if (_listed) { return true; } if (!WinchItem.Available) { return false; } try { ItemDefinition item = Registry.GetItem("yoink_winch"); if ((Object)(object)item == (Object)null) { return false; } ItemDefinition val = WrapForShops(item); if (val == (ItemDefinition)null) { return false; } float shopPrice = Preferences.ShopPrice; int num = 0; num += AddToNamed(val, shopPrice, "Hardware Store", "Hardware", "hardware"); if (num == 0) { num = AddNextTo(val, new string[4] { "trashgrabber", "trimmers", "wateringcan", "trashbag" }, shopPrice); } if (num == 0) { LogShopNamesOnce(); return false; } _listed = true; Core.Log.Msg("[Shop] winch listed in " + num + " shop(s) at $" + shopPrice.ToString("F0", CultureInfo.InvariantCulture) + "."); return true; } catch (Exception ex) { Core.Log.Warning("[Shop] listing failed: " + ex.Message); _listed = true; return false; } } private static int AddToNamed(ItemDefinition item, float price, params string[] names) { int num = 0; for (int i = 0; i < names.Length; i++) { try { Shop shopByName = ShopManager.GetShopByName(names[i]); if (shopByName == null) { continue; } if (shopByName.AddItem(item, (float?)price)) { num++; } break; } catch { } } return num; } private static int AddNextTo(ItemDefinition item, string[] anchors, float price) { for (int i = 0; i < anchors.Length; i++) { try { Shop[] array = ShopManager.FindShopsByItem(anchors[i]); if (array == null) { continue; } int num = 0; Shop[] array2 = array; foreach (Shop val in array2) { if (val != null && val.AddItem(item, (float?)price)) { num++; } } if (num <= 0) { continue; } return num; } catch { } } return 0; } private static ItemDefinition WrapForShops(ItemDefinition native) { try { if ((Object)(object)((Il2CppObjectBase)native).TryCast() != (Object)null) { Type type = typeof(ItemDefinition).Assembly.GetType("S1API.Items.StorableItemDefinition", throwOnError: false); if (type != null) { ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(StorableItemDefinition) }, null); if (constructor != null) { object obj = constructor.Invoke(new object[1] { ((Il2CppObjectBase)native).TryCast() }); ItemDefinition val = (ItemDefinition)((obj is ItemDefinition) ? obj : null); if (val != (ItemDefinition)null) { return val; } } } } } catch (Exception ex) { Core.Log.Warning("[Shop] legacy wrapper failed: " + ex.Message); } return ItemManager.GetDefinition("yoink_winch"); } private static void LogShopNamesOnce() { if (_namesLogged) { return; } _namesLogged = true; try { Shop[] allShops = ShopManager.GetAllShops(); if (allShops == null || allShops.Length == 0) { Core.Log.Msg("[Shop] no shops in the scene yet - will retry."); return; } string text = string.Empty; for (int i = 0; i < allShops.Length; i++) { if (allShops[i] != null) { text = text + ((text.Length > 0) ? ", " : string.Empty) + allShops[i].Name; } } Core.Log.Warning("[Shop] could not place the winch. Shops present: " + text); } catch (Exception ex) { Core.Log.Warning("[Shop] could not list shops: " + ex.Message); } } } } namespace Yoink.Config { internal static class Preferences { private static MelonPreferences_Category _cat; private static MelonPreferences_Entry _pullNewtons; private static MelonPreferences_Entry _maxSpeed; private static MelonPreferences_Entry _hookRange; private static MelonPreferences_Entry _breakDistance; private static MelonPreferences_Entry _stopDistance; private static MelonPreferences_Entry _ropeSegments; private static MelonPreferences_Entry _shopPrice; private static MelonPreferences_Entry _ropeCollision; private static MelonPreferences_Entry _hookPeople; private static MelonPreferences_Entry _knockdown; internal static float PullNewtons { get { return _pullNewtons?.Value ?? 40000f; } set { if (_pullNewtons != null) { _pullNewtons.Value = value; } } } internal static float MaxSpeed { get { return _maxSpeed?.Value ?? 1.5f; } set { if (_maxSpeed != null) { _maxSpeed.Value = value; } } } internal static float HookRange { get { return _hookRange?.Value ?? 15f; } set { if (_hookRange != null) { _hookRange.Value = value; } } } internal static float BreakDistance { get { return _breakDistance?.Value ?? 25f; } set { if (_breakDistance != null) { _breakDistance.Value = value; } } } internal static float StopDistance { get { return _stopDistance?.Value ?? 2.5f; } set { if (_stopDistance != null) { _stopDistance.Value = value; } } } internal static int RopeSegments => _ropeSegments?.Value ?? 20; internal static float ShopPrice { get { return _shopPrice?.Value ?? 80f; } set { if (_shopPrice != null) { _shopPrice.Value = ((value < 0f) ? 0f : value); } } } internal static bool RopeCollision => _ropeCollision?.Value ?? true; internal static bool HookPeople { get { return _hookPeople?.Value ?? true; } set { if (_hookPeople != null) { _hookPeople.Value = value; } } } internal static float Knockdown { get { return _knockdown?.Value ?? 60f; } set { if (_knockdown != null) { _knockdown.Value = ((value < 0f) ? 0f : value); } } } internal static bool TrySet(string key, float value) { switch (key) { case "pull": PullNewtons = value; return true; case "vmax": MaxSpeed = value; return true; case "range": HookRange = value; return true; case "break": BreakDistance = value; return true; case "stop": StopDistance = value; return true; case "knock": Knockdown = value; return true; default: return false; } } internal static void Initialize() { _cat = MelonPreferences.CreateCategory("Yoink", "Yoink"); _pullNewtons = _cat.CreateEntry("PullNewtons", 40000f, "Pull force (N)", "Nominal winch pull, about a four-tonne recovery winch. Real mass applies, so a loaded vehicle still moves slower than a bin.", false, false, (ValueValidator)null, (string)null); _maxSpeed = _cat.CreateEntry("MaxSpeed", 1.5f, "Maximum winch speed (m/s)", "How fast the winch reels the load in along the rope. Other motion (falling, being pushed out of a wall) is not capped.", false, false, (ValueValidator)null, (string)null); _hookRange = _cat.CreateEntry("HookRange", 15f, "Hook range (m)", "How far the hook can be fired in line of sight.", false, false, (ValueValidator)null, (string)null); _breakDistance = _cat.CreateEntry("BreakDistance", 25f, "Rope break distance (m)", "The rope snaps beyond this distance between hook and winch.", false, false, (ValueValidator)null, (string)null); _stopDistance = _cat.CreateEntry("StopDistance", 2.5f, "Stop distance (m)", "Reeling stops once the hooked point gets this close to the anchor.", false, false, (ValueValidator)null, (string)null); _ropeSegments = _cat.CreateEntry("RopeSegments", 20, "Rope segments", "Points in the rope simulation. More is smoother and slightly more expensive.", false, false, (ValueValidator)null, (string)null); _shopPrice = _cat.CreateEntry("ShopPrice", 80f, "Shop price ($)", "What the winch costs in the shop. Read once when the item is registered, so a change applies on the next load.", false, false, (ValueValidator)null, (string)null); _ropeCollision = _cat.CreateEntry("RopeCollision", true, "Rope collides with the world", "Rope slack rests on the ground instead of hanging through it. Costs a couple of short raycasts per frame while a hook is attached.", false, false, (ValueValidator)null, (string)null); _hookPeople = _cat.CreateEntry("HookPeople", true, "Hook can bite people", "The hook takes NPCs off their feet and drags them. They get back up on their own once you let go, the same way they do after a car clips them.", false, false, (ValueValidator)null, (string)null); _knockdown = _cat.CreateEntry("Knockdown", 60f, "Knockdown impulse (Ns)", "How hard a hooked person is knocked over. Uses the game's own ragdoll force, where a car hit is its speed in km/h times four.", false, false, (ValueValidator)null, (string)null); } internal static string Describe() { CultureInfo invariantCulture = CultureInfo.InvariantCulture; return "pull=" + PullNewtons.ToString("F0", invariantCulture) + "N vMax=" + MaxSpeed.ToString("F2", invariantCulture) + " range=" + HookRange.ToString("F1", invariantCulture) + " break=" + BreakDistance.ToString("F1", invariantCulture) + " stop=" + StopDistance.ToString("F1", invariantCulture); } } } namespace Yoink.Audio { internal static class WinchSound { private const int HeadTrim = 9600; private const int TailTrim = 413904; private const int CrossfadeSamples = 1440; private const float PeakTarget = 0.70795f; private const float MinRate = 0.94f; private const float MaxRate = 1.08f; private const float StrainRate = 0.46f; private static AudioClip _body; private static readonly List _clicks = new List(); private static AudioSource _motion; private static AudioSource _strain; private static AudioSource _oneShot; private static AudioLowPassFilter _strainFilter; private static GameObject _root; private static bool _failed; private static bool _engaged; private static float _motionFade; private static float _strainFade; private static float _nextClackAt; private static float _seed; private static int _lastClick = -1; private static float _pendingSecondClickAt = -1f; internal static void ResetSession() { try { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } catch { } _root = null; _motion = null; _strain = null; _oneShot = null; _strainFilter = null; _engaged = false; _motionFade = 0f; _strainFade = 0f; _failed = false; } internal static void Tick(bool engaged, float rate, float maxRate, bool stalled, float payOut) { if (_failed) { return; } try { bool flag = payOut > 0.05f && !engaged; if ((engaged || flag || _engaged || !(_motionFade <= 0f) || !(_strainFade <= 0f)) && EnsureSources()) { float dt = Mathf.Max(Time.unscaledDeltaTime, 0.0001f); if (engaged && !_engaged) { OnEngage(); } else if (!engaged && _engaged) { OnRelease(); } _engaged = engaged; bool flag2 = (engaged && !stalled) || flag; bool flag3 = engaged && stalled; _motionFade = Approach(_motionFade, flag2 ? 1f : 0f, dt, flag2 ? 0.06f : 0.06f); _strainFade = Approach(_strainFade, flag3 ? 1f : 0f, dt, flag3 ? 0.18f : 0.06f); if (flag) { DriveMotion(payOut, maxRate, 0.75f); } else { DriveMotion(rate, maxRate, 1f); } DriveStrain(); } } catch (Exception ex) { _failed = true; Core.Log.Warning("[Sound] winch audio failed: " + ex.Message); } } private static void DriveMotion(float rate, float maxRate, float loudness) { if ((Object)(object)_motion == (Object)null) { return; } if (_motionFade <= 0.001f) { if (_motion.isPlaying) { _motion.Stop(); } _motion.volume = 0f; return; } float num = Mathf.Sqrt(Mathf.Clamp01(Mathf.InverseLerp(0.05f, Mathf.Max(maxRate, 0.1f), rate))); float num2 = (Mathf.PerlinNoise(_seed, Time.unscaledTime * 0.35f) * 2f - 1f) * 0.008f; _motion.pitch = Mathf.Lerp(0.94f, 1.08f, num) + num2; _motion.volume = _motionFade * Mathf.Lerp(0.42f, 0.62f, num) * loudness; if (!_motion.isPlaying) { StartAtStroke(_motion); } } private static void DriveStrain() { if ((Object)(object)_strain == (Object)null) { return; } if (_strainFade <= 0.001f) { if (_strain.isPlaying) { _strain.Stop(); } _strain.volume = 0f; return; } float num = 1f + Mathf.Sin(Time.unscaledTime * 1.7f * (float)Math.PI * 2f) * 0.1f; _strain.pitch = 0.46f; _strain.volume = _strainFade * 0.07f * num; if (!_strain.isPlaying) { _strain.Play(); } if (Time.unscaledTime >= _nextClackAt) { _nextClackAt = Time.unscaledTime + Random.Range(0.42f, 0.68f); PlayClick(Random.Range(0.82f, 0.94f), Random.Range(0.34f, 0.5f)); } } private static void OnEngage() { PlayClick(Random.Range(0.97f, 1.03f), 0.7f); _pendingSecondClickAt = Time.unscaledTime + 0.11f; _nextClackAt = Time.unscaledTime + 0.5f; } private static void OnRelease() { PlayClick(Random.Range(0.88f, 0.96f), 0.62f); _pendingSecondClickAt = -1f; } private static void PumpPendingClick() { if (!(_pendingSecondClickAt < 0f) && !(Time.unscaledTime < _pendingSecondClickAt)) { _pendingSecondClickAt = -1f; PlayClick(Random.Range(0.97f, 1.03f), 0.62f); } } private static void PlayClick(float pitch, float volume) { if (!((Object)(object)_oneShot == (Object)null) && _clicks.Count != 0) { int index = ((_clicks.Count != 1) ? NextClickIndex() : 0); _oneShot.pitch = pitch; _oneShot.PlayOneShot(_clicks[index], volume); } } private static int NextClickIndex() { int num; do { num = Random.Range(0, _clicks.Count); } while (num == _lastClick); _lastClick = num; return num; } private static void StartAtStroke(AudioSource source) { try { if ((Object)(object)_body != (Object)null) { source.time = Random.Range(0f, _body.length * 0.9f); } source.Play(); } catch { try { source.Play(); } catch { } } } private static float Approach(float current, float target, float dt, float seconds) { if (seconds <= 0f) { return target; } float num = dt / seconds; return Mathf.MoveTowards(current, target, num); } private static bool EnsureSources() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if ((Object)(object)_motion != (Object)null) { PumpPendingClick(); return true; } if ((Object)(object)_body == (Object)null) { byte[] array = WinchItem.ReadEmbeddedPublic("Yoink.Assets.winch_crank.wav"); if (array == null) { _failed = true; return false; } if (!Decode(array)) { _failed = true; return false; } } _root = new GameObject("YoinkWinchAudio"); Object.DontDestroyOnLoad((Object)(object)_root); _seed = Random.Range(0f, 100f); _motion = MakeSource("motion", _body, loop: true, 0f); _strain = MakeSource("strain", _body, loop: true, 0f); _oneShot = MakeSource("oneshot", null, loop: false, 0f); _strainFilter = ((Component)_strain).gameObject.AddComponent(); _strainFilter.cutoffFrequency = 220f; return true; } private static AudioSource MakeSource(string name, AudioClip clip, bool loop, float volume) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(_root.transform, false); AudioSource obj = val.AddComponent(); obj.clip = clip; obj.loop = loop; obj.playOnAwake = false; obj.volume = volume; obj.spatialBlend = 0.15f; obj.dopplerLevel = 0f; obj.minDistance = 0.35f; obj.maxDistance = 6f; obj.reverbZoneMix = 0.1f; return obj; } internal static void FollowMuzzle(Vector3 world) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_root != (Object)null) { _root.transform.position = world; } } catch { } } private static bool Decode(byte[] wav) { //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) int channels; int sampleRate; float[] array = ReadPcm(wav, out channels, out sampleRate); if (array == null) { return false; } int num = Mathf.Clamp(9600, 0, array.Length - 1); int num2 = Mathf.Clamp(413904, num + 2880, array.Length); int num3 = FindZeroCrossing(array, num, num + 2400); int num4 = FindZeroCrossing(array, num2 - 2400, num2); if (num4 - num3 < 5760) { num3 = num; num4 = num2; } int num5 = num4 - num3 - 1440; if (num5 <= 0) { Core.Log.Warning("[Sound] the clip is too short to loop."); return false; } float[] array2 = new float[num5]; Array.Copy(array, num3, array2, 0, num5); for (int i = 0; i < 1440; i++) { float num6 = 0.5f - 0.5f * Mathf.Cos((float)Math.PI * ((float)i / 1440f)); float num7 = array[num3 + num5 + i]; array2[i] = num7 * (1f - num6) + array2[i] * num6; } Normalise(array2, 0.70795f); _body = AudioClip.Create("YoinkWinchLoop", array2.Length / Mathf.Max(channels, 1), Mathf.Max(channels, 1), sampleRate, false); _body.SetData(Il2CppStructArray.op_Implicit(array2), 0); AudioClip body = _body; ((Object)body).hideFlags = (HideFlags)(((Object)body).hideFlags | 0x20); ExtractClicks(array, num, num2, channels, sampleRate); Core.Log.Msg("[Sound] winch loop " + ((float)array2.Length / (float)sampleRate).ToString("F2", CultureInfo.InvariantCulture) + " s seamless, " + _clicks.Count + " ratchet click(s) extracted."); return true; } private static void ExtractClicks(float[] samples, int from, int to, int channels, int sampleRate) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = -5760; for (int i = from; i < to - 240; i += 240) { float num2 = 0f; int num3 = i; for (int j = 0; j < 240; j++) { float num4 = Mathf.Abs(samples[i + j]); if (num4 > num2) { num2 = num4; num3 = i + j; } } if (num2 > 0.5f && num3 - num >= 5760) { list.Add(num3); num = num3; if (list.Count >= 6) { break; } } } for (int k = 0; k < list.Count; k++) { int num5 = Mathf.Max(list[k] - 720, 0); int num6 = Mathf.Min(list[k] + 4080, samples.Length) - num5; if (num6 >= 480) { float[] array = new float[num6]; Array.Copy(samples, num5, array, 0, num6); int num7 = 144; for (int l = 0; l < num7 && l < num6; l++) { float num8 = (float)l / (float)num7; array[l] *= num8; array[num6 - 1 - l] *= num8; } Normalise(array, 0.63f); AudioClip val = AudioClip.Create("YoinkRatchet" + k, num6 / Mathf.Max(channels, 1), Mathf.Max(channels, 1), sampleRate, false); val.SetData(Il2CppStructArray.op_Implicit(array), 0); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20); _clicks.Add(val); } } } private static void Normalise(float[] data, float target) { float num = 0f; for (int i = 0; i < data.Length; i++) { float num2 = Mathf.Abs(data[i]); if (num2 > num) { num = num2; } } if (!(num <= 0.0001f)) { float num3 = target / num; for (int j = 0; j < data.Length; j++) { data[j] *= num3; } } } private static int FindZeroCrossing(float[] data, int from, int to) { from = Mathf.Clamp(from, 1, data.Length - 2); to = Mathf.Clamp(to, from + 1, data.Length - 1); for (int i = from; i < to; i++) { if (data[i - 1] <= 0f && data[i] > 0f) { return i; } } return from; } private static float[] ReadPcm(byte[] wav, out int channels, out int sampleRate) { channels = 0; sampleRate = 0; try { if (wav.Length < 12 || wav[0] != 82 || wav[1] != 73 || wav[2] != 70 || wav[3] != 70) { Core.Log.Warning("[Sound] not a RIFF file."); return null; } int num = 0; int num2 = 0; int num3 = -1; int num4 = 0; int num5 = 12; while (num5 + 8 <= wav.Length) { string[] obj = new string[5] { string.Empty, null, null, null, null }; char c = (char)wav[num5]; obj[1] = c.ToString(); c = (char)wav[num5 + 1]; obj[2] = c.ToString(); c = (char)wav[num5 + 2]; obj[3] = c.ToString(); c = (char)wav[num5 + 3]; obj[4] = c.ToString(); string text = string.Concat(obj); int num6 = BitConverter.ToInt32(wav, num5 + 4); int num7 = num5 + 8; if (num6 < 0 || num7 + num6 > wav.Length) { break; } if (text == "fmt ") { num2 = BitConverter.ToUInt16(wav, num7); channels = BitConverter.ToUInt16(wav, num7 + 2); sampleRate = BitConverter.ToInt32(wav, num7 + 4); num = BitConverter.ToUInt16(wav, num7 + 14); } else if (text == "data") { num3 = num7; num4 = num6; } num5 = num7 + num6 + (num6 & 1); } if (num3 < 0 || channels <= 0 || sampleRate <= 0) { Core.Log.Warning("[Sound] WAV is missing fmt or data."); return null; } int num8 = num / 8; if (num8 <= 0) { Core.Log.Warning("[Sound] unsupported bit depth " + num + "."); return null; } int num9 = num4 / num8; float[] array = new float[num9]; for (int i = 0; i < num9; i++) { int num10 = num3 + i * num8; if (num2 == 3 && num == 32) { array[i] = BitConverter.ToSingle(wav, num10); continue; } switch (num) { case 16: array[i] = (float)BitConverter.ToInt16(wav, num10) / 32768f; continue; case 32: array[i] = (float)BitConverter.ToInt32(wav, num10) / 2.1474836E+09f; continue; case 24: array[i] = (float)(wav[num10] | (wav[num10 + 1] << 8) | ((sbyte)wav[num10 + 2] << 16)) / 8388608f; continue; case 8: array[i] = (float)(wav[num10] - 128) / 128f; continue; } Core.Log.Warning("[Sound] unsupported WAV format " + num2 + "/" + num + "."); return null; } double num11 = 0.0; for (int j = 0; j < num9; j++) { num11 += (double)array[j]; } num11 /= (double)Math.Max(num9, 1); if (Math.Abs(num11) > 0.0005) { for (int k = 0; k < num9; k++) { array[k] -= (float)num11; } } return array; } catch (Exception ex) { Core.Log.Warning("[Sound] WAV decode failed: " + ex.Message); return null; } } } } namespace Yoink.Assets { internal static class GlbReader { private const uint MagicGltf = 1179937895u; private const uint ChunkJson = 1313821514u; private const uint ChunkBin = 5130562u; private static List _textures = new List(); private static Material _fallback; internal static GameObject Load(byte[] glb, string name = "GlbModel") { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown try { if (glb == null || glb.Length < 20) { Core.Log.Warning("[Glb] file is too small to be a GLB."); return null; } if (!TrySplitChunks(glb, out var json, out var bin)) { return null; } List buffers = new List { bin }; JToken obj = json["accessors"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); JToken obj2 = json["bufferViews"]; JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null); JToken obj3 = json["meshes"]; JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val == null || val2 == null || val3 == null) { Core.Log.Warning("[Glb] no meshes/accessors in the file."); return null; } _textures = ReadTextures(json, bin); JToken obj4 = json["materials"]; List materials = ReadMaterials((JArray)(object)((obj4 is JArray) ? obj4 : null)); GameObject val4 = new GameObject(name); int num = 0; JToken obj5 = json["nodes"]; JArray val5 = (JArray)(object)((obj5 is JArray) ? obj5 : null); if (val5 != null) { JToken obj6 = json["scenes"]; JArray val6 = (JArray)(object)((obj6 is JArray) ? obj6 : null); JArray val7 = (JArray)((val6 != null && ((JContainer)val6).Count > 0) ? /*isinst with value type is only supported in some contexts*/: null); if (val7 != null) { foreach (JToken item in val7) { num += BuildNode(val4.transform, val5, (int)item, val3, val, val2, buffers, materials); } } } if (num == 0) { for (int i = 0; i < ((JContainer)val3).Count; i++) { int num2 = num; Transform transform = val4.transform; JToken obj7 = val3[i]; num = num2 + BuildMesh(transform, (JObject)(object)((obj7 is JObject) ? obj7 : null), val, val2, buffers, materials, "mesh" + i); } } if (num == 0) { Core.Log.Warning("[Glb] nothing could be built from the file."); Object.Destroy((Object)(object)val4); return null; } Core.Log.Msg("[Glb] built " + num + " mesh part(s)."); return val4; } catch (Exception ex) { Core.Log.Warning("[Glb] load failed: " + ex.Message); return null; } } private static bool TrySplitChunks(byte[] glb, out JObject json, out byte[] bin) { json = null; bin = null; if (BitConverter.ToUInt32(glb, 0) != 1179937895) { Core.Log.Warning("[Glb] not a GLB file (bad magic)."); return false; } int num = 12; while (num + 8 <= glb.Length) { int num2 = (int)BitConverter.ToUInt32(glb, num); uint num3 = BitConverter.ToUInt32(glb, num + 4); int num4 = num + 8; if (num4 + num2 > glb.Length) { break; } switch (num3) { case 1313821514u: json = JObject.Parse(Encoding.UTF8.GetString(glb, num4, num2)); break; case 5130562u: bin = new byte[num2]; Buffer.BlockCopy(glb, num4, bin, 0, num2); break; } num = num4 + num2; if ((num & 3) != 0) { num += 4 - (num & 3); } } if (json == null) { Core.Log.Warning("[Glb] no JSON chunk."); return false; } if (bin == null) { Core.Log.Warning("[Glb] no BIN chunk - external buffers are not supported."); return false; } return true; } private static int BuildNode(Transform parent, JArray nodes, int index, JArray meshes, JArray accessors, JArray views, List buffers, List materials) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (index < 0 || index >= ((JContainer)nodes).Count) { return 0; } JToken obj = nodes[index]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return 0; } GameObject val2 = new GameObject(((string)val["name"]) ?? ("node" + index)); val2.transform.SetParent(parent, false); ApplyTransform(val2.transform, val); int num = 0; if (val["mesh"] != null) { int num2 = num; Transform transform = val2.transform; JToken obj2 = meshes[(int)val["mesh"]]; num = num2 + BuildMesh(transform, (JObject)(object)((obj2 is JObject) ? obj2 : null), accessors, views, buffers, materials, ((Object)val2).name); } JToken obj3 = val["children"]; JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val3 != null) { foreach (JToken item in val3) { num += BuildNode(val2.transform, nodes, (int)item, meshes, accessors, views, buffers, materials); } } return num; } private static void ApplyTransform(Transform t, JObject node) { //IL_0046: 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_00f3: Unknown result type (might be due to invalid IL or missing references) JToken obj = node["translation"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); if (val != null && ((JContainer)val).Count == 3) { t.localPosition = new Vector3((float)val[0], (float)val[1], 0f - (float)val[2]); } JToken obj2 = node["rotation"]; JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null); if (val2 != null && ((JContainer)val2).Count == 4) { t.localRotation = new Quaternion(0f - (float)val2[0], 0f - (float)val2[1], (float)val2[2], (float)val2[3]); } JToken obj3 = node["scale"]; JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val3 != null && ((JContainer)val3).Count == 3) { t.localScale = new Vector3((float)val3[0], (float)val3[1], (float)val3[2]); } } private static int BuildMesh(Transform parent, JObject mesh, JArray accessors, JArray views, List buffers, List materials, string name) { //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) if (mesh == null) { return 0; } JToken obj = mesh["primitives"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); if (val == null) { return 0; } int num = 0; for (int i = 0; i < ((JContainer)val).Count; i++) { JToken obj2 = val[i]; JObject val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null); JToken obj3 = ((val2 != null) ? val2["attributes"] : null); JObject val3 = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (((val3 != null) ? val3["POSITION"] : null) == null) { continue; } Vector3[] array = ReadVector3(accessors, views, buffers, (int)val3["POSITION"], flipZ: true); if (array == null || array.Length == 0) { continue; } Vector3[] array2 = ((val3["NORMAL"] != null) ? ReadVector3(accessors, views, buffers, (int)val3["NORMAL"], flipZ: true) : null); int[] array3 = ((val2["indices"] != null) ? ReadIndices(accessors, views, buffers, (int)val2["indices"]) : Sequential(array.Length)); if (array3 == null || array3.Length < 3) { continue; } Color[] array4 = ((val3["COLOR_0"] != null) ? ReadColours(accessors, views, buffers, (int)val3["COLOR_0"]) : null); int num2 = ((val2["material"] != null) ? ((int)val2["material"]) : (-1)); int num3; if (num2 >= 0 && num2 < materials.Count && (Object)(object)materials[num2] != (Object)null) { num3 = (((Object)(object)materials[num2].mainTexture != (Object)null) ? 1 : 0); if (num3 != 0) { array4 = null; } } else { num3 = 0; } Vector2[] array5 = ((num3 != 0 && val3["TEXCOORD_0"] != null) ? ReadVector2(accessors, views, buffers, (int)val3["TEXCOORD_0"]) : null); for (int j = 0; j + 2 < array3.Length; j += 3) { int num4 = array3[j + 1]; array3[j + 1] = array3[j + 2]; array3[j + 2] = num4; } Mesh val4 = new Mesh { name = name + "_" + i }; val4.SetVertices(ToIl2Cpp(array)); if (array2 != null && array2.Length == array.Length) { val4.SetNormals(ToIl2Cpp(array2)); } if (array2 == null || array2.Length != array.Length) { val4.RecalculateNormals(); } if (array5 != null && array5.Length == array.Length) { val4.SetUVs(0, ToIl2Cpp(array5)); } GameObject val5 = new GameObject(name + "_" + i); val5.transform.SetParent(parent, false); val5.AddComponent().mesh = val4; MeshRenderer val6 = val5.AddComponent(); Material[] array6 = ((array4 != null && array4.Length == array.Length) ? SplitByColour(val4, array3, array4) : null); if (array6 != null && array6.Length != 0) { ((Renderer)val6).materials = ToIl2CppMaterials(array6); } else { val4.SetTriangles(ToIl2CppInt(array3), 0); ((Renderer)val6).material = ((num2 >= 0 && num2 < materials.Count) ? materials[num2] : FallbackMaterial()); } val4.RecalculateBounds(); num++; } return num; } private static Material[] SplitByColour(Mesh mesh, int[] indices, Color[] colours) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) try { List list = new List(); Dictionary> dictionary = new Dictionary>(); for (int i = 0; i + 2 < indices.Length; i += 3) { int num = Pack(colours[indices[i]]); if (!dictionary.TryGetValue(num, out var value)) { value = (dictionary[num] = new List()); list.Add(num); } value.Add(indices[i]); value.Add(indices[i + 1]); value.Add(indices[i + 2]); } if (list.Count == 0) { return null; } mesh.subMeshCount = list.Count; Material[] array = (Material[])(object)new Material[list.Count]; for (int j = 0; j < list.Count; j++) { mesh.SetTriangles(ToIl2CppInt(dictionary[list[j]].ToArray()), j); Material val = NewMaterial("GlbColour" + j); SetColor(val, Unpack(list[j])); array[j] = val; } return array; } catch (Exception ex) { Core.Log.Warning("[Glb] colour split failed, falling back to one material: " + ex.Message); return null; } } private static int Pack(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(Mathf.RoundToInt(c.r * 31f), 0, 31); int num2 = Mathf.Clamp(Mathf.RoundToInt(c.g * 31f), 0, 31); int num3 = Mathf.Clamp(Mathf.RoundToInt(c.b * 31f), 0, 31); return (num << 10) | (num2 << 5) | num3; } private static Color Unpack(int key) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) return new Color((float)((key >> 10) & 0x1F) / 31f, (float)((key >> 5) & 0x1F) / 31f, (float)(key & 0x1F) / 31f, 1f); } private static Color[] ReadColours(JArray accessors, JArray views, List buffers, int index) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) JToken obj = accessors[index]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return null; } string text = (string)val["type"]; int num = ((text == "VEC4") ? 4 : ((text == "VEC3") ? 3 : 0)); if (num == 0) { return null; } int num2 = (int)val["componentType"]; int num3 = num2 switch { 5123 => 2, 5126 => 4, _ => (num2 == 5121) ? 1 : 0, }; if (num3 == 0) { Core.Log.Warning("[Glb] unsupported COLOR_0 component type " + num2 + "."); return null; } int num4 = (int)val["count"]; if (!TryResolve(val, views, buffers, out var data, out var start, out var stride, num * num3)) { return null; } Color[] array = (Color[])(object)new Color[num4]; float[] array2 = new float[4]; for (int i = 0; i < num4; i++) { int num5 = start + i * stride; array2[0] = 0f; array2[1] = 0f; array2[2] = 0f; array2[3] = 1f; for (int j = 0; j < num; j++) { int num6 = num5 + j * num3; array2[j] = num3 switch { 2 => (float)(int)BitConverter.ToUInt16(data, num6) / 65535f, 4 => BitConverter.ToSingle(data, num6), _ => (float)(int)data[num6] / 255f, }; } array[i] = new Color(array2[0], array2[1], array2[2], array2[3]); } return array; } private static int[] Sequential(int count) { int[] array = new int[count]; for (int i = 0; i < count; i++) { array[i] = i; } return array; } private static Vector3[] ReadVector3(JArray accessors, JArray views, List buffers, int index, bool flipZ) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) JToken obj = accessors[index]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return null; } if ((string)val["type"] != "VEC3") { return null; } if ((int)val["componentType"] != 5126) { return null; } int num = (int)val["count"]; if (!TryResolve(val, views, buffers, out var data, out var start, out var stride, 12)) { return null; } Vector3[] array = (Vector3[])(object)new Vector3[num]; for (int i = 0; i < num; i++) { int num2 = start + i * stride; float num3 = BitConverter.ToSingle(data, num2); float num4 = BitConverter.ToSingle(data, num2 + 4); float num5 = BitConverter.ToSingle(data, num2 + 8); array[i] = new Vector3(num3, num4, flipZ ? (0f - num5) : num5); } return array; } private static Vector2[] ReadVector2(JArray accessors, JArray views, List buffers, int index) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) JToken obj = accessors[index]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return null; } if ((string)val["type"] != "VEC2") { return null; } if ((int)val["componentType"] != 5126) { return null; } int num = (int)val["count"]; if (!TryResolve(val, views, buffers, out var data, out var start, out var stride, 8)) { return null; } Vector2[] array = (Vector2[])(object)new Vector2[num]; for (int i = 0; i < num; i++) { int num2 = start + i * stride; array[i] = new Vector2(BitConverter.ToSingle(data, num2), 1f - BitConverter.ToSingle(data, num2 + 4)); } return array; } private static int[] ReadIndices(JArray accessors, JArray views, List buffers, int index) { JToken obj = accessors[index]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return null; } int num = (int)val["componentType"]; int num2 = num switch { 5123 => 2, 5125 => 4, _ => (num == 5121) ? 1 : 0, }; if (num2 == 0) { Core.Log.Warning("[Glb] unsupported index type " + num + "."); return null; } int num3 = (int)val["count"]; if (!TryResolve(val, views, buffers, out var data, out var start, out var stride, num2)) { return null; } int[] array = new int[num3]; for (int i = 0; i < num3; i++) { int num4 = start + i * stride; array[i] = num2 switch { 2 => BitConverter.ToUInt16(data, num4), 4 => (int)BitConverter.ToUInt32(data, num4), _ => data[num4], }; } return array; } private static bool TryResolve(JObject accessor, JArray views, List buffers, out byte[] data, out int start, out int stride, int elementSize) { data = null; start = 0; stride = elementSize; if (accessor["bufferView"] == null) { return false; } JToken obj = views[(int)accessor["bufferView"]]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val == null) { return false; } int num = ((val["buffer"] != null) ? ((int)val["buffer"]) : 0); if (num < 0 || num >= buffers.Count) { return false; } data = buffers[num]; int num2 = ((val["byteOffset"] != null) ? ((int)val["byteOffset"]) : 0); int num3 = ((accessor["byteOffset"] != null) ? ((int)accessor["byteOffset"]) : 0); start = num2 + num3; if (val["byteStride"] != null) { stride = (int)val["byteStride"]; } return true; } private static List ReadTextures(JObject json, byte[] bin) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) List list = new List(); try { JToken obj = json["images"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); JToken obj2 = json["bufferViews"]; JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null); if (val == null || val2 == null) { return list; } for (int i = 0; i < ((JContainer)val).Count; i++) { JToken obj3 = val[i]; JObject val3 = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (val3 == null || val3["bufferView"] == null) { list.Add(null); continue; } JToken obj4 = val2[(int)val3["bufferView"]]; JObject val4 = (JObject)(object)((obj4 is JObject) ? obj4 : null); if (val4 == null) { list.Add(null); continue; } int srcOffset = ((val4["byteOffset"] != null) ? ((int)val4["byteOffset"]) : 0); int num = (int)val4["byteLength"]; byte[] array = new byte[num]; Buffer.BlockCopy(bin, srcOffset, array, 0, num); Texture2D val5 = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val5, Il2CppStructArray.op_Implicit(array), false)) { list.Add(null); continue; } ((Texture)val5).filterMode = (FilterMode)0; ((Texture)val5).wrapMode = (TextureWrapMode)1; ((Object)val5).hideFlags = (HideFlags)(((Object)val5).hideFlags | 0x20); list.Add(val5); } } catch (Exception ex) { Core.Log.Warning("[Glb] texture decode failed: " + ex.Message); } return list; } private static Texture2D TextureFor(JObject material) { try { JToken obj = ((material != null) ? material["pbrMetallicRoughness"] : null); JToken obj2 = ((obj is JObject) ? obj : null); JToken obj3 = ((obj2 != null) ? ((JObject)obj2)["baseColorTexture"] : null); JObject val = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (val == null || val["index"] == null) { return null; } int num = (int)val["index"]; return (num >= 0 && num < _textures.Count) ? _textures[num] : null; } catch { return null; } } private static List ReadMaterials(JArray materials) { //IL_0118: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (materials == null) { return list; } Color val6 = default(Color); for (int i = 0; i < ((JContainer)materials).Count; i++) { JToken obj = materials[i]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); Material val2 = NewMaterial(((string)((val != null) ? val["name"] : null)) ?? ("material" + i)); Color white = Color.white; JToken obj2 = ((val != null) ? val["pbrMetallicRoughness"] : null); JToken obj3 = ((obj2 is JObject) ? obj2 : null); JToken obj4 = ((obj3 != null) ? ((JObject)obj3)["baseColorFactor"] : null); JArray val3 = (JArray)(object)((obj4 is JArray) ? obj4 : null); if (val3 != null && ((JContainer)val3).Count >= 3) { ((Color)(ref white))..ctor((float)val3[0], (float)val3[1], (float)val3[2], (((JContainer)val3).Count > 3) ? ((float)val3[3]) : 1f); } SetColor(val2, white); Texture2D val4 = TextureFor(val); if ((Object)(object)val4 != (Object)null) { val2.mainTexture = (Texture)(object)val4; try { val2.SetTexture("_BaseMap", (Texture)(object)val4); } catch { } SetColor(val2, Color.white); } JToken obj6 = ((val != null) ? val["emissiveFactor"] : null); JArray val5 = (JArray)(object)((obj6 is JArray) ? obj6 : null); if (val5 != null && ((JContainer)val5).Count >= 3) { ((Color)(ref val6))..ctor((float)val5[0], (float)val5[1], (float)val5[2], 1f); if (val6.r > 0.001f || val6.g > 0.001f || val6.b > 0.001f) { try { val2.EnableKeyword("_EMISSION"); if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", val6); } } catch { } } } list.Add(val2); } return list; } private static Material FallbackMaterial() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_fallback == (Object)null) { _fallback = NewMaterial("GlbFallback"); SetColor(_fallback, Color.magenta); } return _fallback; } private static Material NewMaterial(string name) { //IL_0046: 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_004b: 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_0053: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown Shader val = null; try { val = Shader.Find("Universal Render Pipeline/Lit"); } catch { } if ((Object)(object)val == (Object)null) { try { val = Shader.Find("Standard"); } catch { } } Material val2 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(Shader.Find("Sprites/Default"))); ((Object)val2).name = name; ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20); return val2; } private static void SetColor(Material mat, Color c) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) try { if (mat.HasProperty("_BaseColor")) { mat.SetColor("_BaseColor", c); } if (mat.HasProperty("_Color")) { mat.SetColor("_Color", c); } mat.color = c; } catch { } } private static Il2CppReferenceArray ToIl2CppMaterials(Material[] values) { Il2CppReferenceArray val = new Il2CppReferenceArray((long)values.Length); for (int i = 0; i < values.Length; i++) { ((Il2CppArrayBase)(object)val)[i] = values[i]; } return val; } private static List ToIl2Cpp(Vector2[] values) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) List val = new List(values.Length); for (int i = 0; i < values.Length; i++) { val.Add(values[i]); } return val; } private static List ToIl2Cpp(Vector3[] values) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) List val = new List(values.Length); for (int i = 0; i < values.Length; i++) { val.Add(values[i]); } return val; } private static List ToIl2CppInt(int[] values) { List val = new List(values.Length); for (int i = 0; i < values.Length; i++) { val.Add(values[i]); } return val; } } }