using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using ClimbAnything;
using HarmonyLib;
using Il2CppHexabodyVR.PlayerController;
using Il2CppHurricaneVR.Framework.Core.Grabbers;
using Il2CppHurricaneVR.Framework.Core.Player;
using Il2CppHurricaneVR.Framework.Shared;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "ClimbAnything", "1.0.0", "geom2543", null)]
[assembly: MelonGame("Kubunautilus", "BrutalistickVR")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ClimbAnything")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5698a8e264bff225c921ec548117a34cb0f64c84")]
[assembly: AssemblyProduct("ClimbAnything")]
[assembly: AssemblyTitle("ClimbAnything")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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;
}
}
}
namespace ClimbAnything
{
public class Core : MelonMod
{
private class HandState
{
public HVRHexaBodyHands Hand;
public bool WasDown;
public int Wait = -1;
public ConfigurableJoint Anchor;
}
private MelonPreferences_Category _cat;
internal static MelonPreferences_Entry<bool> Enabled;
private MelonPreferences_Entry<float> _radius;
private MelonPreferences_Entry<bool> _allowDynamic;
private MelonPreferences_Entry<float> _minDynamicMass;
private MelonPreferences_Entry<float> _breakForce;
private MelonPreferences_Entry<bool> _verbose;
private static readonly Dictionary<IntPtr, HandState> Hands = new Dictionary<IntPtr, HandState>();
private static HexaBodyPlayer4 _body;
private static Transform _rig;
internal static bool IsAnchored(HVRHexaBodyHands h)
{
if ((Object)(object)h != (Object)null && Hands.TryGetValue(((Il2CppObjectBase)h).Pointer, out var value))
{
return (Object)(object)value.Anchor != (Object)null;
}
return false;
}
public override void OnInitializeMelon()
{
_cat = MelonPreferences.CreateCategory("ClimbAnything");
Enabled = _cat.CreateEntry<bool>("Enabled", true, "Enabled", (string)null, false, false, (ValueValidator)null, (string)null);
_radius = _cat.CreateEntry<float>("GrabRadius", 0.12f, "Grab radius (m)", "How close the hand must be to a surface for grip to catch it", false, false, (ValueValidator)null, (string)null);
_allowDynamic = _cat.CreateEntry<bool>("AllowDynamicObjects", false, "Climb loose objects", "Also catch on non-kinematic physics objects that have no grab handle", false, false, (ValueValidator)null, (string)null);
_minDynamicMass = _cat.CreateEntry<float>("MinDynamicMass", 40f, "Min mass of loose objects (kg)", (string)null, false, false, (ValueValidator)null, (string)null);
_breakForce = _cat.CreateEntry<float>("BreakForce", 0f, "Grip break force (N)", "0 = never slips", false, false, (ValueValidator)null, (string)null);
_verbose = _cat.CreateEntry<bool>("Verbose", true, "Verbose log", (string)null, false, false, (ValueValidator)null, (string)null);
((MelonBase)this).LoggerInstance.Msg("Loaded. Grip next to any wall, ledge or ceiling to hold on.");
}
public override void OnSceneWasInitialized(int buildIndex, string sceneName)
{
Hands.Clear();
_body = null;
_rig = null;
}
private static bool FindBody()
{
if ((Object)(object)_body != (Object)null && !((Il2CppObjectBase)_body).WasCollected && Object.op_Implicit((Object)(object)_body))
{
return true;
}
_body = Object.FindObjectOfType<HexaBodyPlayer4>();
if ((Object)(object)_body == (Object)null)
{
return false;
}
_rig = (((Object)(object)((Component)_body).transform.parent != (Object)null) ? ((Component)_body).transform.parent : ((Component)_body).transform);
Hands.Clear();
foreach (HVRHexaBodyHands componentsInChild in ((Component)_rig).GetComponentsInChildren<HVRHexaBodyHands>(true))
{
if ((Object)(object)componentsInChild != (Object)null)
{
Hands[((Il2CppObjectBase)componentsInChild).Pointer] = new HandState
{
Hand = componentsInChild
};
}
}
return true;
}
public override void OnUpdate()
{
if (!Enabled.Value || !FindBody())
{
return;
}
foreach (HandState value in Hands.Values)
{
try
{
UpdateHand(value);
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Hand update: " + ex.Message);
}
}
}
private void UpdateHand(HandState s)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
HVRHexaBodyHands hand = s.Hand;
if ((Object)(object)hand == (Object)null || ((Il2CppObjectBase)hand).WasCollected)
{
return;
}
HVRHandGrabber grabber = hand.Grabber;
if ((Object)(object)grabber == (Object)null)
{
return;
}
HVRController controller = grabber.Controller;
bool flag = (Object)(object)controller != (Object)null && controller.GripButtonState.Active;
if (flag && !s.WasDown && (Object)(object)s.Anchor == (Object)null)
{
s.Wait = 2;
}
s.WasDown = flag;
if (!flag)
{
Release(s, "grip released");
}
else if ((Object)(object)s.Anchor != (Object)null && ((HVRGrabberBase)grabber).IsGrabbing)
{
Release(s, "grabbed an item");
}
else if (s.Wait > 0)
{
s.Wait--;
}
else if (s.Wait == 0)
{
s.Wait = -1;
if (!((HVRGrabberBase)grabber).IsGrabbing && (Object)(object)((HVRGrabberBase)grabber).HoverTarget == (Object)null)
{
TryAnchor(s, grabber.IsLeftHand ? "L" : "R");
}
}
}
private void TryAnchor(HandState s, string side)
{
//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_0032: 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_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: 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_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: 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_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: 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_0107: 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)
Rigidbody rigidBody = ((HexaHandsBase)s.Hand).RigidBody;
if ((Object)(object)rigidBody == (Object)null)
{
return;
}
Vector3 worldCenterOfMass = rigidBody.worldCenterOfMass;
float num = _radius.Value * Mathf.Max(0.01f, _rig.lossyScale.x);
Collider val = null;
float num2 = float.MaxValue;
foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(worldCenterOfMass, num, -1, (QueryTriggerInteraction)1))
{
if ((Object)(object)item == (Object)null || item.isTrigger || ((Component)item).transform.IsChildOf(_rig))
{
continue;
}
Rigidbody attachedRigidbody = item.attachedRigidbody;
if (!((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic || (_allowDynamic.Value && attachedRigidbody.mass >= _minDynamicMass.Value))
{
MeshCollider val2 = ((Il2CppObjectBase)item).TryCast<MeshCollider>();
Vector3 val3;
if (!((Object)(object)val2 != (Object)null) || val2.convex)
{
val3 = item.ClosestPoint(worldCenterOfMass);
}
else
{
Bounds bounds = item.bounds;
val3 = ((Bounds)(ref bounds)).ClosestPoint(worldCenterOfMass);
}
Vector3 val4 = val3 - worldCenterOfMass;
float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
if (sqrMagnitude < num2)
{
num2 = sqrMagnitude;
val = item;
}
}
}
if (!((Object)(object)val == (Object)null))
{
ConfigurableJoint val5 = ((Component)rigidBody).gameObject.AddComponent<ConfigurableJoint>();
Rigidbody val6 = (((Joint)val5).connectedBody = val.attachedRigidbody);
((Joint)val5).autoConfigureConnectedAnchor = true;
((Joint)val5).anchor = Vector3.zero;
ConfigurableJointMotion val7 = (ConfigurableJointMotion)0;
val5.zMotion = (ConfigurableJointMotion)0;
ConfigurableJointMotion xMotion = (val5.yMotion = val7);
val5.xMotion = xMotion;
val7 = (ConfigurableJointMotion)2;
val5.angularZMotion = (ConfigurableJointMotion)2;
xMotion = (val5.angularYMotion = val7);
val5.angularXMotion = xMotion;
((Joint)val5).enableCollision = false;
((Joint)val5).enablePreprocessing = false;
if (_breakForce.Value > 0f)
{
((Joint)val5).breakForce = _breakForce.Value;
}
s.Anchor = val5;
if (_verbose.Value)
{
((MelonBase)this).LoggerInstance.Msg($"[{side}] holding '{((Object)val).name}' ({(((Object)(object)val6 == (Object)null) ? "static" : (val6.isKinematic ? "kinematic" : "dynamic"))}) at {Mathf.Sqrt(num2):F2} m");
}
}
}
private void Release(HandState s, string why)
{
if (!((Object)(object)s.Anchor == (Object)null))
{
Object.Destroy((Object)(object)s.Anchor);
s.Anchor = null;
if (_verbose.Value)
{
((MelonBase)this).LoggerInstance.Msg("Let go: " + why);
}
}
}
}
[HarmonyPatch(typeof(HVRHexaBodyHands), "GetHandState")]
internal static class HandStatePatch
{
private static void Postfix(HVRHexaBodyHands __instance, ref HandGrabState __result)
{
if (Core.Enabled.Value && Core.IsAnchored(__instance))
{
__result = (HandGrabState)3;
}
}
}
}