Decompiled source of SmoothLocomotion v1.0.0

SmoothLocomotion.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using TheLabModdingLib;
using UnityEngine;
using UnityEngine.SceneManagement;
using Valve.VR.InteractionSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SmoothLocomotion;

[BepInPlugin("com.thelab.smoothlocomotion", "SmoothLocomotion", "1.0.0")]
public class SmoothLocomotionMod : BaseUnityPlugin
{
	private ConfigEntry<bool> configEnabled;

	private ConfigEntry<float> configMoveSpeed;

	private ConfigEntry<bool> configSnapTurn;

	private ConfigEntry<float> configSnapTurnAngle;

	private ConfigEntry<float> configDeadzone;

	private ConfigEntry<bool> configNoClip;

	private ConfigEntry<float> configGravityScale;

	private float moveSpeed = 2f;

	private float snapTurnAngle = 45f;

	private float deadzone = 0.2f;

	private bool smoothLocomotionEnabled = true;

	private bool snapTurningEnabled = true;

	private bool noClip = false;

	private float gravityScale = 1f;

	private Vector2 lastRightStick;

	private CharacterController _cc;

	private int _lastIgnoreFrame = -1;

	private float _verticalVelocity = 0f;

	private float _maxHeadHeight = 0f;

	private void Awake()
	{
		configEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable smooth locomotion");
		configMoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MoveSpeed", 2f, "Movement speed (units/sec)");
		configSnapTurn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SnapTurnEnabled", true, "Enable snap turning");
		configSnapTurnAngle = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SnapTurnAngle", 45f, "Snap turn angle (degrees)");
		configDeadzone = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Deadzone", 0.2f, "Thumbstick deadzone");
		configNoClip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NoClip", false, "Disable collision when moving");
		configGravityScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GravityScale", 1f, "Gravity multiplier (1 = normal)");
		smoothLocomotionEnabled = configEnabled.Value;
		moveSpeed = configMoveSpeed.Value;
		snapTurningEnabled = configSnapTurn.Value;
		snapTurnAngle = configSnapTurnAngle.Value;
		deadzone = configDeadzone.Value;
		noClip = configNoClip.Value;
		gravityScale = configGravityScale.Value;
		configEnabled.SettingChanged += delegate
		{
			smoothLocomotionEnabled = configEnabled.Value;
		};
		configMoveSpeed.SettingChanged += delegate
		{
			moveSpeed = configMoveSpeed.Value;
		};
		configSnapTurn.SettingChanged += delegate
		{
			snapTurningEnabled = configSnapTurn.Value;
		};
		configSnapTurnAngle.SettingChanged += delegate
		{
			snapTurnAngle = configSnapTurnAngle.Value;
		};
		configDeadzone.SettingChanged += delegate
		{
			deadzone = configDeadzone.Value;
		};
		configGravityScale.SettingChanged += delegate
		{
			gravityScale = configGravityScale.Value;
		};
		configNoClip.SettingChanged += delegate
		{
			noClip = configNoClip.Value;
			if (noClip && (Object)(object)_cc != (Object)null)
			{
				Object.Destroy((Object)(object)_cc);
				_cc = null;
			}
			if (!noClip)
			{
				_cc = null;
			}
		};
		InputAPI.Initialize();
		SceneManager.sceneLoaded += OnSceneLoaded;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[SmoothLocomotion] Initialized.");
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		_cc = null;
		_maxHeadHeight = 0f;
		_verticalVelocity = 0f;
		if (smoothLocomotionEnabled)
		{
			try
			{
				PlayerAPI.SetTeleportEnabled(false);
			}
			catch
			{
			}
		}
	}

	private void Update()
	{
		if (!smoothLocomotionEnabled)
		{
			return;
		}
		try
		{
			if (!((Object)(object)PlayerAPI.VRPlayerInstance == (Object)null))
			{
				EnsureCC();
				ProcessSmoothMovement();
				ProcessSnapTurning();
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[SmoothLocomotion] Update error: " + ex.Message));
		}
	}

	private void EnsureCC()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		if (!noClip && !((Object)(object)_cc != (Object)null))
		{
			Transform trackingOrigin = PlayerAPI.TrackingOrigin;
			if (!((Object)(object)trackingOrigin == (Object)null))
			{
				_cc = ((Component)trackingOrigin).gameObject.AddComponent<CharacterController>();
				_cc.height = 1.5f;
				_cc.center = new Vector3(0f, 0.75f, 0f);
				_cc.radius = 0.2f;
				_cc.skinWidth = 0.01f;
				_cc.minMoveDistance = 0.001f;
			}
		}
	}

	private void IgnoreHandColliders()
	{
		if ((Object)(object)_cc == (Object)null || Time.frameCount == _lastIgnoreFrame)
		{
			return;
		}
		_lastIgnoreFrame = Time.frameCount;
		foreach (VRHand allHand in PlayerAPI.GetAllHands())
		{
			if ((Object)(object)allHand == (Object)null)
			{
				continue;
			}
			Collider[] componentsInChildren = ((Component)allHand).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)_cc)
				{
					Physics.IgnoreCollision((Collider)(object)_cc, val, true);
				}
			}
		}
	}

	private void SyncCCUnderCamera()
	{
		//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_004e: 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_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_006e: 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_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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)
		if (!((Object)(object)_cc == (Object)null))
		{
			Transform trackingOrigin = PlayerAPI.TrackingOrigin;
			Transform hMDTransform = PlayerAPI.HMDTransform;
			if (!((Object)(object)trackingOrigin == (Object)null) && !((Object)(object)hMDTransform == (Object)null))
			{
				Vector3 val = trackingOrigin.InverseTransformPoint(hMDTransform.position);
				Vector3 val2 = trackingOrigin.InverseTransformDirection(hMDTransform.forward);
				_maxHeadHeight = Mathf.Max(new float[3] { _maxHeadHeight, val.y, 0.3f });
				_cc.center = new Vector3(val.x, _maxHeadHeight * 0.5f, val.z) - val2 * 0.1f;
				_cc.height = _maxHeadHeight;
			}
		}
	}

	private void ProcessSmoothMovement()
	{
		//IL_01c2: 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_004b: 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)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: 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_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: 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_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: 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_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: 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_0108: 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_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: 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_0163: 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_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		IgnoreHandColliders();
		SyncCCUnderCamera();
		Transform trackingOrigin = PlayerAPI.TrackingOrigin;
		Transform hMDTransform = PlayerAPI.HMDTransform;
		if ((Object)(object)trackingOrigin == (Object)null || (Object)(object)hMDTransform == (Object)null)
		{
			return;
		}
		Vector3 val;
		if ((Object)(object)_cc != (Object)null)
		{
			float num = Physics.gravity.y * gravityScale;
			float deltaTime = Time.deltaTime;
			if (_cc.isGrounded && _verticalVelocity < 0f)
			{
				_verticalVelocity = -2f * gravityScale;
			}
			else if (!_cc.isGrounded)
			{
				_verticalVelocity += num * deltaTime;
			}
			Vector2 leftThumbstickAxisNormalized = InputAPI.GetLeftThumbstickAxisNormalized();
			if (((Vector2)(ref leftThumbstickAxisNormalized)).magnitude > deadzone)
			{
				val = Vector3.ProjectOnPlane(hMDTransform.forward, Vector3.up);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				val = Vector3.ProjectOnPlane(hMDTransform.right, Vector3.up);
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				val = normalized * leftThumbstickAxisNormalized.y + normalized2 * leftThumbstickAxisNormalized.x;
				Vector3 normalized3 = ((Vector3)(ref val)).normalized;
				float num2 = moveSpeed * Mathf.Clamp01(((Vector2)(ref leftThumbstickAxisNormalized)).magnitude);
				_cc.Move(normalized3 * num2 * deltaTime + new Vector3(0f, _verticalVelocity * deltaTime, 0f));
			}
			else
			{
				_cc.Move(new Vector3(0f, _verticalVelocity * deltaTime, 0f));
			}
		}
		else
		{
			Vector2 leftThumbstickAxisNormalized2 = InputAPI.GetLeftThumbstickAxisNormalized();
			if (((Vector2)(ref leftThumbstickAxisNormalized2)).magnitude > deadzone)
			{
				val = Vector3.ProjectOnPlane(hMDTransform.forward, Vector3.up);
				Vector3 normalized4 = ((Vector3)(ref val)).normalized;
				val = Vector3.ProjectOnPlane(hMDTransform.right, Vector3.up);
				Vector3 normalized5 = ((Vector3)(ref val)).normalized;
				val = normalized4 * leftThumbstickAxisNormalized2.y + normalized5 * leftThumbstickAxisNormalized2.x;
				Vector3 normalized6 = ((Vector3)(ref val)).normalized;
				float num3 = moveSpeed * Mathf.Clamp01(((Vector2)(ref leftThumbstickAxisNormalized2)).magnitude);
				trackingOrigin.position += normalized6 * num3 * Time.deltaTime;
			}
		}
	}

	private void ProcessSnapTurning()
	{
		//IL_0013: 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_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_0069: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: 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)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		if (!snapTurningEnabled)
		{
			return;
		}
		Vector2 rightThumbstickAxisNormalized = InputAPI.GetRightThumbstickAxisNormalized();
		if (((Vector2)(ref rightThumbstickAxisNormalized)).magnitude < deadzone)
		{
			lastRightStick = Vector2.zero;
			return;
		}
		Transform trackingOrigin = PlayerAPI.TrackingOrigin;
		Transform hMDTransform = PlayerAPI.HMDTransform;
		if (!((Object)(object)trackingOrigin == (Object)null) && !((Object)(object)hMDTransform == (Object)null))
		{
			if (rightThumbstickAxisNormalized.x < -0.5f && lastRightStick.x >= -0.5f)
			{
				trackingOrigin.RotateAround(hMDTransform.position, Vector3.up, 0f - snapTurnAngle);
			}
			else if (rightThumbstickAxisNormalized.x > 0.5f && lastRightStick.x <= 0.5f)
			{
				trackingOrigin.RotateAround(hMDTransform.position, Vector3.up, snapTurnAngle);
			}
			lastRightStick = rightThumbstickAxisNormalized;
		}
	}
}