Decompiled source of TwinStickArmSprint v1.1.4

TwinStickArmSprint.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("TwinStickArmSprint")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5addff770db5e84a7d115cc3cb8bb1c0f76ef301")]
[assembly: AssemblyProduct("TwinStickArmSprint")]
[assembly: AssemblyTitle("TwinStickArmSprint")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 TwinStickArmSprint
{
	public class Patch
	{
		public class HandState
		{
			public Quaternion pointerRotation_0;

			public Quaternion pointerRotation_1;

			public int baseSpeedLeft;

			public int baseSpeedRight;

			public CoreControlMode coreControlMode;

			public bool isInStreamlinedMode_0;

			public bool isInStreamlinedMode_1;

			public bool touchpadNorthPressed_0;

			public bool touchpadNorthPressed_1;

			public bool touchpadWestPressed;

			public bool touchpadEastPressed;
		}

		private static readonly MethodInfo miHandUpdateArmSwinger = typeof(FVRMovementManager).GetMethod("HandUpdateArmSwinger", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo miHandUpdateTwinstick = typeof(FVRMovementManager).GetMethod("HandUpdateTwinstick", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo miAXButtonCheck = typeof(FVRMovementManager).GetMethod("AXButtonCheck", BindingFlags.Instance | BindingFlags.NonPublic);

		public static readonly Dictionary<float, int[]> SpeedMap = new Dictionary<float, int[]>
		{
			{
				3.6f,
				new int[2] { 5, 5 }
			},
			{
				3f,
				new int[2] { 5, 4 }
			},
			{
				2.55f,
				new int[2] { 5, 3 }
			},
			{
				2.4f,
				new int[2] { 4, 4 }
			},
			{
				2.175f,
				new int[2] { 5, 2 }
			},
			{
				2.025f,
				new int[2] { 5, 1 }
			},
			{
				1.95f,
				new int[2] { 4, 3 }
			},
			{
				1.8f,
				new int[2] { 5, 0 }
			},
			{
				1.575f,
				new int[2] { 4, 2 }
			},
			{
				1.5f,
				new int[2] { 3, 3 }
			},
			{
				1.425f,
				new int[2] { 4, 1 }
			},
			{
				1.2f,
				new int[2] { 4, 0 }
			},
			{
				1.125f,
				new int[2] { 3, 2 }
			},
			{
				0.975f,
				new int[2] { 3, 1 }
			},
			{
				0.75f,
				new int[2] { 2, 2 }
			},
			{
				0.6f,
				new int[2] { 2, 1 }
			},
			{
				0.45f,
				new int[2] { 1, 1 }
			},
			{
				0.375f,
				new int[2] { 2, 0 }
			},
			{
				0.225f,
				new int[2] { 1, 0 }
			},
			{
				0f,
				new int[2]
			}
		};

		public static int GetMovementHand(FVRMovementManager instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			int num = ((!instance.Hands[0].IsThisTheRightHand) ? 1 : 0);
			if ((int)GM.Options.MovementOptions.TwinStickLeftRightState != 1)
			{
				return 1 - num;
			}
			return num;
		}

		[HarmonyPatch(typeof(FVRMovementManager), "ShouldFlushTouchpad")]
		[HarmonyPostfix]
		public static void Patch_ShouldFlushTouchpad(FVRMovementManager __instance, bool ___m_isLeftHandActive, bool ___m_isRightHandActive, FVRViveHand hand, ref bool __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			if (!hand.IsInStreamlinedMode && (int)hand.CMode != 3 && (int)hand.CMode != 2 && (int)__instance.Mode == 4)
			{
				bool flag = hand.IsThisTheRightHand;
				if ((int)GM.Options.MovementOptions.TwinStickLeftRightState == 1)
				{
					flag = !flag;
				}
				if (___m_isLeftHandActive && !flag)
				{
					__result = true;
				}
				if (___m_isRightHandActive && flag)
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(FVRMovementManager), "UpdateMovementWithHand")]
		[HarmonyPrefix]
		public static bool Patch_HandMovementUpdate(FVRMovementManager __instance, ref Vector3 ___worldTPAxis, bool ___m_sprintingEngaged, FVRViveHand hand, out HandState __state)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: 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_00e6: Invalid comparison between Unknown and I4
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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_0175: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			__state = new HandState();
			if ((int)__instance.Mode == 4)
			{
				if (Plugin.HeadArmswinger == null || !Plugin.HeadArmswinger.Value)
				{
					if ((int)__instance.Hands[0].CMode == 1)
					{
						__state.coreControlMode = GM.Options.ControlOptions.CCM;
						__state.isInStreamlinedMode_0 = __instance.Hands[0].IsInStreamlinedMode;
						__state.isInStreamlinedMode_1 = __instance.Hands[1].IsInStreamlinedMode;
						GM.Options.ControlOptions.CCM = (CoreControlMode)1;
						__instance.Hands[0].IsInStreamlinedMode = true;
						__instance.Hands[1].IsInStreamlinedMode = true;
					}
					if (((int)GM.Options.MovementOptions.TwinStickLeftRightState == 1) ^ hand.IsThisTheRightHand)
					{
						miHandUpdateArmSwinger.Invoke(__instance, new object[1] { hand });
					}
					if ((int)__instance.Hands[0].CMode == 1)
					{
						GM.Options.ControlOptions.CCM = __state.coreControlMode;
						__instance.Hands[0].IsInStreamlinedMode = __state.isInStreamlinedMode_0;
						__instance.Hands[1].IsInStreamlinedMode = __state.isInStreamlinedMode_1;
					}
					TwinStickSnapturnMode twinStickSnapturnState = GM.Options.MovementOptions.TwinStickSnapturnState;
					GM.Options.MovementOptions.TwinStickSnapturnState = (TwinStickSnapturnMode)0;
					miHandUpdateTwinstick.Invoke(__instance, new object[1] { hand });
					if (___m_sprintingEngaged && GM.Options.MovementOptions.TPLocoSpeedIndex < 5)
					{
						Vector3 normalized = ((Vector3)(ref ___worldTPAxis)).normalized;
						if (((Vector3)(ref ___worldTPAxis)).magnitude > ((Vector3)(ref normalized)).magnitude * 2f)
						{
							___worldTPAxis -= normalized * 2f;
						}
					}
					GM.Options.MovementOptions.TwinStickSnapturnState = twinStickSnapturnState;
				}
				else
				{
					miHandUpdateArmSwinger.Invoke(__instance, new object[1] { hand });
					Vector3 forward = GM.CurrentPlayerBody.Head.forward;
					forward.y = 0f;
					((Vector3)(ref forward)).Normalize();
					___worldTPAxis = forward;
				}
				miAXButtonCheck.Invoke(__instance, new object[1] { hand });
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(FVRMovementManager), "UpdateSmoothLocomotion")]
		[HarmonyPrefix]
		public static void Patch_SmoothLocomotionUpdate(FVRMovementManager __instance, Vector3 ___worldTPAxis, bool ___m_isRightHandActive, out HandState __state)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Invalid comparison between Unknown and I4
			//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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: 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_0133: Invalid comparison between Unknown and I4
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: 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_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Invalid comparison between Unknown and I4
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: 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_01e5: Invalid comparison between Unknown and I4
			__state = new HandState();
			if ((int)__instance.Mode != 4)
			{
				return;
			}
			if (Plugin.HeadArmswinger == null || !Plugin.HeadArmswinger.Value)
			{
				int movementHand = GetMovementHand(__instance);
				if ((int)__instance.Hands[0].CMode == 1 && ___m_isRightHandActive)
				{
					__state.coreControlMode = GM.Options.ControlOptions.CCM;
					__state.isInStreamlinedMode_0 = __instance.Hands[0].IsInStreamlinedMode;
					__state.isInStreamlinedMode_1 = __instance.Hands[1].IsInStreamlinedMode;
					__state.touchpadNorthPressed_0 = __instance.Hands[0].Input.TouchpadNorthPressed;
					__state.touchpadNorthPressed_1 = __instance.Hands[1].Input.TouchpadNorthPressed;
					__state.touchpadWestPressed = __instance.Hands[movementHand].Input.TouchpadWestPressed;
					__state.touchpadEastPressed = __instance.Hands[movementHand].Input.TouchpadEastPressed;
					GM.Options.ControlOptions.CCM = (CoreControlMode)1;
					__instance.Hands[0].IsInStreamlinedMode = true;
					__instance.Hands[1].IsInStreamlinedMode = true;
				}
				if ((int)__instance.Hands[0].CMode == 3 || (int)__instance.Hands[0].CMode == 2)
				{
					__instance.Hands[movementHand].Input.Secondary2AxisWestPressed = false;
					__instance.Hands[movementHand].Input.Secondary2AxisEastPressed = false;
				}
				else if (__instance.Hands[0].IsInStreamlinedMode)
				{
					__instance.Hands[movementHand].Input.TouchpadWestPressed = false;
					__instance.Hands[movementHand].Input.TouchpadEastPressed = false;
				}
				ref bool reference = ref __instance.Hands[0].Input.BYButtonPressed;
				ref bool reference2 = ref __instance.Hands[1].Input.BYButtonPressed;
				if (__instance.Hands[0].IsInStreamlinedMode)
				{
					if ((int)__instance.Hands[0].CMode == 3 || (int)__instance.Hands[0].CMode == 2)
					{
						reference = ref __instance.Hands[0].Input.Secondary2AxisNorthPressed;
						reference2 = ref __instance.Hands[1].Input.Secondary2AxisNorthPressed;
					}
					else
					{
						reference = ref __instance.Hands[0].Input.TouchpadNorthPressed;
						reference2 = ref __instance.Hands[1].Input.TouchpadNorthPressed;
					}
				}
				float magnitude = ((Vector3)(ref ___worldTPAxis)).magnitude;
				reference = magnitude > 0f;
				reference2 = magnitude > 0f;
				__state.pointerRotation_0 = __instance.Hands[0].PointingTransform.localRotation;
				__state.pointerRotation_1 = __instance.Hands[1].PointingTransform.localRotation;
				__state.baseSpeedLeft = GM.Options.MovementOptions.ArmSwingerBaseSpeed_Left;
				__state.baseSpeedRight = GM.Options.MovementOptions.ArmSwingerBaseSpeed_Right;
				if (!(magnitude > 0f))
				{
					return;
				}
				__instance.Hands[0].PointingTransform.forward = ((Vector3)(ref ___worldTPAxis)).normalized;
				__instance.Hands[1].PointingTransform.forward = ((Vector3)(ref ___worldTPAxis)).normalized;
				{
					foreach (float key in SpeedMap.Keys)
					{
						if (magnitude > key)
						{
							GM.Options.MovementOptions.ArmSwingerBaseSpeed_Left = SpeedMap[key][0];
							GM.Options.MovementOptions.ArmSwingerBaseSpeed_Right = SpeedMap[key][1];
							break;
						}
					}
					return;
				}
			}
			__state.baseSpeedLeft = GM.Options.MovementOptions.ArmSwingerBaseSpeed_Left;
			__state.baseSpeedRight = GM.Options.MovementOptions.ArmSwingerBaseSpeed_Right;
			__state.pointerRotation_0 = __instance.Hands[0].PointingTransform.localRotation;
			__state.pointerRotation_1 = __instance.Hands[1].PointingTransform.localRotation;
			__instance.Hands[0].PointingTransform.forward = ((Vector3)(ref ___worldTPAxis)).normalized;
			__instance.Hands[1].PointingTransform.forward = ((Vector3)(ref ___worldTPAxis)).normalized;
		}

		[HarmonyPatch(typeof(FVRMovementManager), "UpdateSmoothLocomotion")]
		[HarmonyPostfix]
		public static void Patch_SmoothLocomotionUpdateEnd(FVRMovementManager __instance, bool ___m_isRightHandActive, HandState __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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)
			if ((int)__instance.Mode == 4)
			{
				if ((Plugin.HeadArmswinger == null || !Plugin.HeadArmswinger.Value) && (int)__instance.Hands[0].CMode == 1 && ___m_isRightHandActive)
				{
					int movementHand = GetMovementHand(__instance);
					GM.Options.ControlOptions.CCM = __state.coreControlMode;
					__instance.Hands[0].IsInStreamlinedMode = __state.isInStreamlinedMode_0;
					__instance.Hands[1].IsInStreamlinedMode = __state.isInStreamlinedMode_1;
					__instance.Hands[0].Input.TouchpadNorthPressed = __state.touchpadNorthPressed_0;
					__instance.Hands[1].Input.TouchpadNorthPressed = __state.touchpadNorthPressed_1;
					__instance.Hands[movementHand].Input.TouchpadWestPressed = __state.touchpadWestPressed;
					__instance.Hands[movementHand].Input.TouchpadEastPressed = __state.touchpadEastPressed;
				}
				__instance.Hands[0].PointingTransform.localRotation = __state.pointerRotation_0;
				__instance.Hands[1].PointingTransform.localRotation = __state.pointerRotation_1;
				GM.Options.MovementOptions.ArmSwingerBaseSpeed_Left = __state.baseSpeedLeft;
				GM.Options.MovementOptions.ArmSwingerBaseSpeed_Right = __state.baseSpeedRight;
			}
		}

		[HarmonyPatch(typeof(FVRPointableButton), "Awake")]
		[HarmonyPostfix]
		public static void Patch_FixDashName(FVRPointableButton __instance)
		{
			Text component = ((Component)__instance).GetComponent<Text>();
			if ((Object)(object)component != (Object)null && component.text == "Armswinger")
			{
				if (Plugin.HeadArmswinger == null || !Plugin.HeadArmswinger.Value)
				{
					component.text = "TS Arm Sprint";
				}
				else
				{
					component.text = "Head Armswinger";
				}
			}
		}
	}
	[BepInPlugin("dll.h3vr.odekak.twinstickarmsprint", "TwinStick Arm Sprint", "1.1.3")]
	[BepInProcess("h3vr.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> HeadArmswinger;

		public void Start()
		{
			LoadConfigFile();
			Harmony.CreateAndPatchAll(typeof(Patch), (string)null);
		}

		private void LoadConfigFile()
		{
			HeadArmswinger = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Head-Based Armswinger", false, "If true, act like regular Armswinger (no TwinStick), except use head direction instead of controller direction.");
		}
	}
	internal static class PluginInfo
	{
		internal const string NAME = "TwinStick Arm Sprint";

		internal const string GUID = "dll.h3vr.odekak.twinstickarmsprint";

		internal const string VERSION = "1.1.3";
	}
}