using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using GamepadLocomotion;
using HarmonyLib;
using MelonLoader;
using Microsoft.CodeAnalysis;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Main), "GamepadLocomotion", "1.4.0", "Jake", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GamepadLocomotion")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GamepadLocomotion")]
[assembly: AssemblyTitle("GamepadLocomotion")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 GamepadLocomotion
{
public class Main : MelonMod
{
private struct XInputGamepad
{
public ushort Buttons;
public byte LeftTrigger;
public byte RightTrigger;
public short LeftStickX;
public short LeftStickY;
public short RightStickX;
public short RightStickY;
}
private struct XInputState
{
public uint PacketNumber;
public XInputGamepad Gamepad;
}
private const uint ERROR_SUCCESS = 0u;
private const ushort DPAD_UP = 1;
private const ushort DPAD_DOWN = 2;
private const ushort DPAD_LEFT = 4;
private const ushort DPAD_RIGHT = 8;
private const ushort BUTTON_A = 4096;
private const ushort BUTTON_START = 16;
private bool controllerConnected;
private bool playerReady;
private bool setupComplete;
private object openControllerRig;
private object physicsRig;
private object leftController;
private static Type vector2Type;
private static ConstructorInfo vector2Constructor;
private MethodInfo secondaryThumbstickMethod;
private static Type vector3Type;
private static ConstructorInfo vector3Constructor;
private PropertyInfo groundVelocityProperty;
private const float MOVE_SPEED = 3f;
private FieldInfo thumbstickAxisField;
private PropertyInfo thumbstickAxisProperty;
private object torso;
private object rbChest;
private object directionMasterTransform;
private MethodInfo addForceMethod;
private MethodInfo isSleepingMethod;
private MethodInfo quaternionVector3MultiplyMethod;
private Type forceModeType;
private object forceModeAcceleration;
private const float FORCE_MULTIPLIER = 12f;
private PropertyInfo axisPrimaryProperty;
private PropertyInfo axisPrimaryDirtyProperty;
private PropertyInfo primaryStickProperty;
private PropertyInfo primaryStickTouchProperty;
private Harmony harmony;
private bool patchApplied;
private bool onMarrowReadyPatchApplied;
private static Main instance;
private object xrControllerLeft;
private PropertyInfo joystick2DAxisProperty;
private bool xrControllerFound;
private readonly Stopwatch deltaClock = new Stopwatch();
private bool scannedOnce;
private bool aButtonWasDown;
private bool startButtonWasDown;
private PropertyInfo quickmenuEnabledProperty;
private PropertyInfo bButtonProperty;
private PropertyInfo bButtonDownProperty;
private PropertyInfo bButtonUpProperty;
private object xrControllerRight;
private PropertyInfo aButtonProperty;
private PropertyInfo aButtonDownProperty;
private PropertyInfo aButtonUpProperty;
private int velocityLogCounter;
private static float currentX;
private static float currentY;
private static float currentRightX;
private static float currentRightY;
private static bool loggedFirstCall;
[DllImport("XInput1_4.dll", CallingConvention = CallingConvention.StdCall)]
private static extern uint XInputGetState(uint userIndex, out XInputState state);
public override void OnInitializeMelon()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
MelonLogger.Msg("");
MelonLogger.Msg("======================================");
MelonLogger.Msg(" GamepadLocomotion 1.4.0");
MelonLogger.Msg(" BoneLib.Player based rig access");
MelonLogger.Msg("======================================");
MelonLogger.Msg("[Gamepad] Waiting for XInput controller...");
instance = this;
harmony = new Harmony("com.jake.gamepadlocomotion");
try
{
Type type = FindType("Il2CppSLZ.Marrow.OpenControllerRig");
if (type == null)
{
MelonLogger.Error("[Setup] OpenControllerRig type not found for OnMarrowReady patch.");
return;
}
MethodInfo method = type.GetMethod("OnMarrowReady", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
MelonLogger.Error("[Setup] OnMarrowReady method not found.");
return;
}
MethodInfo method2 = typeof(Main).GetMethod("OnMarrowReadyPostfix", BindingFlags.Static | BindingFlags.NonPublic);
harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
onMarrowReadyPatchApplied = true;
MelonLogger.Msg("[Setup] OnMarrowReady patched - will re-sync on every level load.");
}
catch (Exception ex)
{
MelonLogger.Error("[Setup] OnMarrowReady patch error: " + ex.Message);
}
}
private static void OnMarrowReadyPostfix()
{
try
{
instance?.TriggerRefresh("OnMarrowReady");
}
catch
{
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
TriggerRefresh("Scene loaded: " + sceneName);
}
private void TriggerRefresh(string reason)
{
MelonLogger.Msg("[Player] " + reason + " - re-acquiring rig references.");
playerReady = false;
setupComplete = false;
openControllerRig = null;
physicsRig = null;
leftController = null;
torso = null;
rbChest = null;
directionMasterTransform = null;
xrControllerLeft = null;
xrControllerRight = null;
xrControllerFound = false;
}
public override void OnUpdate()
{
CheckController();
if (!playerReady)
{
FindPlayer();
}
else if (!setupComplete)
{
SetupMovement();
}
else if (!controllerConnected)
{
currentX = 0f;
currentY = 0f;
}
else
{
UpdateStickValues();
}
}
private bool GetControllerState(out XInputState state)
{
return XInputGetState(0u, out state) == 0;
}
private void CheckController()
{
XInputState state;
bool controllerState = GetControllerState(out state);
if (controllerState && !controllerConnected)
{
controllerConnected = true;
MelonLogger.Msg("[Gamepad] XInput controller detected.");
}
if (!controllerState && controllerConnected)
{
controllerConnected = false;
MelonLogger.Msg("[Gamepad] Controller disconnected.");
}
}
private void FindPlayer()
{
try
{
Type type = FindType("BoneLib.Player");
if (type == null)
{
MelonLogger.Error("[Player] BoneLib.Player type was not found. Is BoneLib loaded?");
return;
}
object staticPropertyValue = GetStaticPropertyValue(type, "ControllerRig");
if (staticPropertyValue != null)
{
openControllerRig = staticPropertyValue;
object staticPropertyValue2 = GetStaticPropertyValue(type, "PhysicsRig");
physicsRig = staticPropertyValue2;
object obj = GetStaticPropertyValue(type, "LeftController");
if (obj == null)
{
obj = GetInstancePropertyValue(staticPropertyValue, "leftController") ?? GetInstanceFieldValue(staticPropertyValue, "leftController");
}
leftController = obj;
playerReady = true;
MelonLogger.Msg("");
MelonLogger.Msg("[Player] ControllerRig found via BoneLib.Player.");
MelonLogger.Msg("[Player] PhysicsRig: " + ((physicsRig != null) ? "found" : "NOT found"));
MelonLogger.Msg("[Player] leftController: " + ((leftController != null) ? "found" : "NOT found"));
}
}
catch (Exception ex)
{
MelonLogger.Error("[Player] " + ex.Message);
}
}
private void SetupMovement()
{
//IL_07bc: Unknown result type (might be due to invalid IL or missing references)
//IL_07c3: Unknown result type (might be due to invalid IL or missing references)
//IL_07d0: Expected O, but got Unknown
//IL_07d0: Expected O, but got Unknown
try
{
Type type = openControllerRig.GetType();
MelonLogger.Msg("[Movement] Rig = " + type.FullName);
vector2Type = FindType("UnityEngine.Vector2");
if (vector2Type == null)
{
MelonLogger.Error("[Movement] UnityEngine.Vector2 was not found.");
return;
}
vector2Constructor = vector2Type.GetConstructor(new Type[2]
{
typeof(float),
typeof(float)
});
if (vector2Constructor == null)
{
MelonLogger.Error("[Movement] Vector2 constructor not found.");
return;
}
MelonLogger.Msg("[Movement] Vector2 interface ready.");
vector3Type = FindType("UnityEngine.Vector3");
if (vector3Type != null)
{
vector3Constructor = vector3Type.GetConstructor(new Type[3]
{
typeof(float),
typeof(float),
typeof(float)
});
}
if (physicsRig != null)
{
groundVelocityProperty = FindProperty(physicsRig.GetType(), "groundVelocity");
MelonLogger.Msg("[Movement] groundVelocity: " + ((groundVelocityProperty != null) ? "found" : "not found"));
}
if (leftController != null)
{
Type type2 = leftController.GetType();
thumbstickAxisField = type2.GetField("_thumbstickAxis", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
thumbstickAxisProperty = FindProperty(type2, "_thumbstickAxis") ?? FindProperty(type2, "thumbstickAxis");
MelonLogger.Msg("[Movement] leftController type: " + type2.FullName);
MelonLogger.Msg("[Movement] _thumbstickAxis field: " + ((thumbstickAxisField != null) ? "found" : "not found"));
MelonLogger.Msg("[Movement] _thumbstickAxis property: " + ((thumbstickAxisProperty != null) ? "found" : "not found"));
if (!scannedOnce)
{
ScanForKeywordMethods(type2, "thumbstick");
ScanForKeywordMethods(type2, "axis");
ScanForKeywordMethods(type2, "Menu");
}
}
else
{
MelonLogger.Msg("[Movement] leftController not available - cannot set _thumbstickAxis.");
}
if (physicsRig != null)
{
torso = GetInstancePropertyValue(physicsRig, "torso") ?? GetInstanceFieldValue(physicsRig, "torso");
MelonLogger.Msg("[Movement] torso: " + ((torso != null) ? "found" : "not found"));
if (torso != null)
{
rbChest = GetInstancePropertyValue(torso, "rbChest") ?? GetInstanceFieldValue(torso, "rbChest");
MelonLogger.Msg("[Movement] rbChest: " + ((rbChest != null) ? "found" : "not found"));
}
}
directionMasterTransform = GetInstancePropertyValue(openControllerRig, "directionMasterTransform") ?? GetInstanceFieldValue(openControllerRig, "directionMasterTransform");
MelonLogger.Msg("[Movement] directionMasterTransform: " + ((directionMasterTransform != null) ? "found" : "not found"));
if (rbChest != null)
{
Type type3 = rbChest.GetType();
Type type4 = FindType("UnityEngine.Quaternion");
forceModeType = FindType("UnityEngine.ForceMode");
if (type4 != null && vector3Type != null)
{
quaternionVector3MultiplyMethod = type4.GetMethod("op_Multiply", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { type4, vector3Type }, null);
}
if (forceModeType != null)
{
addForceMethod = type3.GetMethod("AddForce", BindingFlags.Instance | BindingFlags.Public, null, new Type[2] { vector3Type, forceModeType }, null);
forceModeAcceleration = Enum.ToObject(forceModeType, 5);
}
isSleepingMethod = type3.GetMethod("IsSleeping", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
MelonLogger.Msg("[Movement] AddForce method: " + ((addForceMethod != null) ? "found" : "not found"));
MelonLogger.Msg("[Movement] Quaternion*Vector3 operator: " + ((quaternionVector3MultiplyMethod != null) ? "found" : "not found"));
object instancePropertyValue = GetInstancePropertyValue(rbChest, "isKinematic");
object instancePropertyValue2 = GetInstancePropertyValue(rbChest, "mass");
MelonLogger.Msg("[Movement] rbChest.isKinematic: " + ((instancePropertyValue != null) ? instancePropertyValue.ToString() : "?"));
MelonLogger.Msg("[Movement] rbChest.mass: " + ((instancePropertyValue2 != null) ? instancePropertyValue2.ToString() : "?"));
}
if (!scannedOnce)
{
scannedOnce = true;
ScanForKeywordMethods(type, "Primary");
ScanForKeywordMethods(type, "Jump");
ScanForKeywordMethods(type, "Menu");
Type type5 = FindType("BoneLib.Player");
if (type5 != null)
{
object staticPropertyValue = GetStaticPropertyValue(type5, "RigManager");
if (staticPropertyValue != null)
{
MelonLogger.Msg("[Scan] RigManager type: " + staticPropertyValue.GetType().FullName);
ScanForKeywordMethods(staticPropertyValue.GetType(), "Menu");
}
}
if (physicsRig != null)
{
Type type6 = physicsRig.GetType();
MelonLogger.Msg("[Scan] PhysicsRig type: " + type6.FullName);
ScanForKeywordMethods(type6, "Primary");
ScanForKeywordMethods(type6, "Jump");
ScanForKeywordMethods(type6, "Move");
ScanForKeywordMethods(type6, "Velocity");
ScanForKeywordMethods(type6, "Menu");
}
else
{
MelonLogger.Msg("[Scan] PhysicsRig was not available to scan.");
}
}
axisPrimaryProperty = FindProperty(type, "_axisPrimary") ?? FindProperty(type, "axisPrimary");
axisPrimaryDirtyProperty = FindProperty(type, "_axisPrimaryDirty") ?? FindProperty(type, "axisPrimaryDirty");
primaryStickProperty = FindProperty(type, "_primaryStick") ?? FindProperty(type, "primaryStick");
primaryStickTouchProperty = FindProperty(type, "_primaryStickTouch") ?? FindProperty(type, "primaryStickTouch");
MelonLogger.Msg("[Movement] Direct axisPrimary: " + ((axisPrimaryProperty != null) ? "found" : "not found"));
quickmenuEnabledProperty = FindProperty(type, "quickmenuEnabled");
MelonLogger.Msg("[Movement] quickmenuEnabled: " + ((quickmenuEnabledProperty != null) ? "found - START button will toggle it" : "not found"));
MethodInfo method = type.GetMethod("GetPrimaryAxis", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
if (method == null)
{
MelonLogger.Error("[Movement] GetPrimaryAxis() was not found on " + type.FullName);
}
else if (!patchApplied)
{
MethodInfo method2 = typeof(Main).GetMethod("PrimaryAxisPostfix", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo method3 = typeof(Main).GetMethod("PrimaryAxisPrefix", BindingFlags.Static | BindingFlags.NonPublic);
harmony.Patch((MethodBase)method, new HarmonyMethod(method3), new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
patchApplied = true;
MelonLogger.Msg("[Movement] GetPrimaryAxis() patched.");
}
try
{
Type type7 = FindType("Il2CppSLZ.Marrow.Utilities.MarrowGame");
if (type7 == null)
{
MelonLogger.Error("[XR2] Il2CppSLZ.Marrow.Utilities.MarrowGame not found.");
}
else
{
object staticPropertyValue2 = GetStaticPropertyValue(type7, "xr");
if (staticPropertyValue2 == null)
{
MelonLogger.Error("[XR2] MarrowGame.xr returned null.");
}
else
{
xrControllerLeft = GetInstancePropertyValue(staticPropertyValue2, "LeftController");
if (xrControllerLeft == null)
{
MelonLogger.Error("[XR2] XRApi.LeftController is null.");
}
else
{
joystick2DAxisProperty = FindProperty(xrControllerLeft.GetType(), "Joystick2DAxis");
xrControllerFound = joystick2DAxisProperty != null;
MelonLogger.Msg("[XR2] XRController type: " + xrControllerLeft.GetType().FullName);
MelonLogger.Msg("[XR2] Joystick2DAxis property: " + (xrControllerFound ? "found" : "not found"));
Type type8 = xrControllerLeft.GetType();
bButtonProperty = FindProperty(type8, "BButton");
bButtonDownProperty = FindProperty(type8, "BButtonDown");
bButtonUpProperty = FindProperty(type8, "BButtonUp");
MelonLogger.Msg("[XR2] BButton properties: " + ((bButtonProperty != null && bButtonDownProperty != null && bButtonUpProperty != null) ? "found - START opens radial menu" : "not found"));
xrControllerRight = GetInstancePropertyValue(staticPropertyValue2, "RightController");
if (xrControllerRight != null)
{
Type type9 = xrControllerRight.GetType();
aButtonProperty = FindProperty(type9, "AButton");
aButtonDownProperty = FindProperty(type9, "AButtonDown");
aButtonUpProperty = FindProperty(type9, "AButtonUp");
MelonLogger.Msg("[XR2] AButton properties: " + ((aButtonProperty != null && aButtonDownProperty != null && aButtonUpProperty != null) ? "found - A button jumps" : "not found"));
}
else
{
MelonLogger.Error("[XR2] XRApi.RightController is null.");
}
}
}
}
}
catch (Exception ex)
{
MelonLogger.Error("[XR2] Setup error: " + ex.Message);
}
secondaryThumbstickMethod = type.GetMethod("ProcessSecondaryThumbstick", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
{
vector2Type,
typeof(float)
}, null);
if (secondaryThumbstickMethod == null)
{
MelonLogger.Error("[Movement] ProcessSecondaryThumbstick(Vector2, float) was not found.");
}
else
{
MelonLogger.Msg("[Movement] ProcessSecondaryThumbstick found.");
MelonLogger.Msg("[Movement] RIGHT STICK -> rotation");
if (!deltaClock.IsRunning)
{
deltaClock.Start();
}
}
MelonLogger.Msg("[Movement] LEFT STICK -> primary axis");
MelonLogger.Msg("[Movement] DPAD -> primary axis backup");
setupComplete = true;
MelonLogger.Msg("[Movement] Setup complete.");
}
catch (Exception ex2)
{
MelonLogger.Error("[Movement] Setup error: " + ex2.Message);
}
}
private static void ScanForKeywordMethods(Type startType, string keyword)
{
try
{
MelonLogger.Msg("[Scan] Searching " + startType.FullName + " and base classes for \"" + keyword + "\" methods...");
Type type = startType;
int num = 0;
while (type != null && type != typeof(object))
{
MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo[] array = methods;
foreach (MethodInfo methodInfo in array)
{
if (methodInfo.Name.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
string text = "";
for (int j = 0; j < parameters.Length; j++)
{
if (j > 0)
{
text += ", ";
}
text += parameters[j].ParameterType.Name;
}
MelonLogger.Msg("[Scan] " + type.Name + "." + methodInfo.Name + "(" + text + ") -> " + methodInfo.ReturnType.Name);
num++;
}
type = type.BaseType;
}
MelonLogger.Msg("[Scan] Done. " + num + " match(es).");
}
catch (Exception ex)
{
MelonLogger.Error("[Scan] " + ex.Message);
}
}
private static void PrimaryAxisPrefix()
{
if (!loggedFirstCall)
{
loggedFirstCall = true;
MelonLogger.Msg("[Movement] CONFIRMED: GetPrimaryAxis() was called by the game.");
}
}
private static void PrimaryAxisPostfix(ref object __result)
{
try
{
if (!(vector2Constructor == null))
{
__result = vector2Constructor.Invoke(new object[2] { currentX, currentY });
}
}
catch
{
}
}
private void UpdateStickValues()
{
try
{
if (!GetControllerState(out var state))
{
currentX = 0f;
currentY = 0f;
return;
}
float num = NormalizeStick(state.Gamepad.LeftStickX);
float num2 = NormalizeStick(state.Gamepad.LeftStickY);
ushort buttons = state.Gamepad.Buttons;
if ((buttons & 4) != 0)
{
num = -1f;
}
if ((buttons & 8) != 0)
{
num = 1f;
}
if ((buttons & 2) != 0)
{
num2 = -1f;
}
if ((buttons & 1) != 0)
{
num2 = 1f;
}
if (Math.Abs(num) < 0.12f)
{
num = 0f;
}
if (Math.Abs(num2) < 0.12f)
{
num2 = 0f;
}
currentX = num;
currentY = num2;
if (groundVelocityProperty != null && vector3Constructor != null && physicsRig != null)
{
object value = vector3Constructor.Invoke(new object[3]
{
num * 3f,
0f,
num2 * 3f
});
groundVelocityProperty.SetValue(physicsRig, value);
}
if (leftController != null && vector2Constructor != null && (thumbstickAxisField != null || thumbstickAxisProperty != null))
{
object value2 = vector2Constructor.Invoke(new object[2] { num, num2 });
if (thumbstickAxisField != null)
{
thumbstickAxisField.SetValue(leftController, value2);
}
else
{
thumbstickAxisProperty.SetValue(leftController, value2);
}
}
if (xrControllerFound && xrControllerLeft != null && vector2Constructor != null)
{
object value3 = vector2Constructor.Invoke(new object[2] { num, num2 });
joystick2DAxisProperty.SetValue(xrControllerLeft, value3);
}
if (addForceMethod != null && rbChest != null && directionMasterTransform != null && vector3Constructor != null)
{
object obj = vector3Constructor.Invoke(new object[3] { num, 0f, num2 });
object instancePropertyValue = GetInstancePropertyValue(directionMasterTransform, "rotation");
object obj2 = obj;
if (instancePropertyValue != null && quaternionVector3MultiplyMethod != null)
{
obj2 = quaternionVector3MultiplyMethod.Invoke(null, new object[2] { instancePropertyValue, obj });
}
Type type = obj2.GetType();
float num3 = (float)type.GetField("x").GetValue(obj2);
float num4 = (float)type.GetField("y").GetValue(obj2);
float num5 = (float)type.GetField("z").GetValue(obj2);
object obj3 = vector3Constructor.Invoke(new object[3]
{
num3 * 12f,
num4 * 12f,
num5 * 12f
});
addForceMethod.Invoke(rbChest, new object[2] { obj3, forceModeAcceleration });
velocityLogCounter++;
if (velocityLogCounter >= 60)
{
velocityLogCounter = 0;
object instancePropertyValue2 = GetInstancePropertyValue(rbChest, "velocity");
object instancePropertyValue3 = GetInstancePropertyValue(rbChest, "isKinematic");
object obj4 = null;
if (isSleepingMethod != null)
{
try
{
obj4 = isSleepingMethod.Invoke(rbChest, null);
}
catch
{
}
}
MelonLogger.Msg("[Movement] rbChest.velocity: " + ((instancePropertyValue2 != null) ? instancePropertyValue2.ToString() : "?") + " | kinematic: " + ((instancePropertyValue3 != null) ? instancePropertyValue3.ToString() : "?") + " | sleeping: " + ((obj4 != null) ? obj4.ToString() : "?") + " | input: " + num.ToString("F2") + "," + num2.ToString("F2"));
}
}
if (axisPrimaryProperty != null && vector2Constructor != null)
{
object value4 = vector2Constructor.Invoke(new object[2] { num, num2 });
axisPrimaryProperty.SetValue(openControllerRig, value4);
}
bool flag = num != 0f || num2 != 0f;
if (axisPrimaryDirtyProperty != null)
{
axisPrimaryDirtyProperty.SetValue(openControllerRig, true);
}
if (primaryStickProperty != null)
{
primaryStickProperty.SetValue(openControllerRig, flag);
}
if (primaryStickTouchProperty != null)
{
primaryStickTouchProperty.SetValue(openControllerRig, flag);
}
float value5 = NormalizeStick(state.Gamepad.RightStickX);
float value6 = NormalizeStick(state.Gamepad.RightStickY);
if (Math.Abs(value5) < 0.15f)
{
value5 = 0f;
}
if (Math.Abs(value6) < 0.15f)
{
value6 = 0f;
}
currentRightX = value5;
currentRightY = value6;
bool flag2 = (buttons & 0x1000) != 0;
bool flag3 = flag2 && !aButtonWasDown;
bool flag4 = !flag2 && aButtonWasDown;
if (aButtonProperty != null && aButtonDownProperty != null && aButtonUpProperty != null && xrControllerRight != null)
{
aButtonProperty.SetValue(xrControllerRight, flag2);
aButtonDownProperty.SetValue(xrControllerRight, flag3);
aButtonUpProperty.SetValue(xrControllerRight, flag4);
if (flag3)
{
MelonLogger.Msg("[Movement] A pressed -> jump.");
}
}
aButtonWasDown = flag2;
bool flag5 = (buttons & 0x10) != 0;
bool flag6 = flag5 && !startButtonWasDown;
bool flag7 = !flag5 && startButtonWasDown;
if (bButtonProperty != null && bButtonDownProperty != null && bButtonUpProperty != null && xrControllerRight != null)
{
bButtonProperty.SetValue(xrControllerRight, flag5);
bButtonDownProperty.SetValue(xrControllerRight, flag6);
bButtonUpProperty.SetValue(xrControllerRight, flag7);
if (flag6)
{
MelonLogger.Msg("[Movement] START pressed -> radial menu.");
}
}
startButtonWasDown = flag5;
if (secondaryThumbstickMethod != null && vector2Constructor != null && openControllerRig != null)
{
float num6 = (float)deltaClock.Elapsed.TotalSeconds;
deltaClock.Restart();
object obj6 = vector2Constructor.Invoke(new object[2] { currentRightX, currentRightY });
secondaryThumbstickMethod.Invoke(openControllerRig, new object[2] { obj6, num6 });
}
}
catch (Exception ex)
{
MelonLogger.Error("[Movement] " + ex.Message);
torso = null;
rbChest = null;
directionMasterTransform = null;
leftController = null;
thumbstickAxisField = null;
thumbstickAxisProperty = null;
secondaryThumbstickMethod = null;
xrControllerLeft = null;
xrControllerRight = null;
xrControllerFound = false;
}
}
private float NormalizeStick(short value)
{
if (value >= 0)
{
return (float)value / 32767f;
}
return (float)value / 32768f;
}
private static PropertyInfo FindProperty(Type type, string name)
{
return type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
private static object GetStaticPropertyValue(Type type, string name)
{
try
{
PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (property == null)
{
return null;
}
return property.GetValue(null);
}
catch
{
return null;
}
}
private static object GetInstancePropertyValue(object instance, string name)
{
if (instance == null)
{
return null;
}
try
{
PropertyInfo propertyInfo = FindProperty(instance.GetType(), name);
if (propertyInfo == null)
{
return null;
}
return propertyInfo.GetValue(instance);
}
catch
{
return null;
}
}
private static object GetInstanceFieldValue(object instance, string name)
{
if (instance == null)
{
return null;
}
try
{
FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null)
{
return null;
}
return field.GetValue(instance);
}
catch
{
return null;
}
}
private static Type FindType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
try
{
Type type = assembly.GetType(fullName);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
}
}