Decompiled source of DropProne v1.1.0

Mods\DropProne.dll

Decompiled 16 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using DropProne;
using DropProne.Config;
using DropProne.Menu;
using DropProne.Patches;
using DropProne.Prone;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DropProne")]
[assembly: AssemblyDescription("Go prone in BONELAB. Crawl, take cover, stay flat.")]
[assembly: AssemblyCompany(null)]
[assembly: AssemblyProduct("DropProne")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: MelonInfo(typeof(DropProneMod), "DropProne", "1.1.0", "Rocner", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonColor(255, 90, 150, 90)]
[assembly: MelonAuthorColor(255, 120, 200, 255)]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.1.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 DropProne
{
	public sealed class DropProneMod : MelonMod
	{
		private static bool _levelReady;

		public override void OnInitializeMelon()
		{
			//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)
			Step("preferences", Prefs.Load);
			Step("patches", delegate
			{
				RigPatches.Apply(((MelonBase)this).HarmonyInstance);
			});
			Step("menu", MenuPage.Build);
			Step("level loaded hook", delegate
			{
				Hooking.OnLevelLoaded += OnLevelLoaded;
			});
			Step("level unloaded hook", delegate
			{
				Hooking.OnLevelUnloaded += OnLevelUnloaded;
			});
			((MelonBase)this).LoggerInstance.Msg("DropProne ready. Binding: " + Prefs.Bind.ToString() + ", key: " + ((object)Prefs.Key/*cast due to .constrained prefix*/).ToString() + ".");
		}

		private void Step(string name, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Init step '" + name + "' failed: " + ex);
			}
		}

		private static void OnLevelLoaded(LevelInfo info)
		{
			ProneDriver.ForceReset(rigIsAlive: false);
			RigBinding.Forget();
			ProneInput.Forget();
			Diagnostics.Stop();
			_levelReady = true;
		}

		private static void OnLevelUnloaded()
		{
			_levelReady = false;
			ProneDriver.ForceReset(rigIsAlive: false);
			RigBinding.Forget();
			ProneInput.Forget();
			Diagnostics.Stop();
		}

		public override void OnUpdate()
		{
			try
			{
				Run(Time.deltaTime);
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Update failed: " + ex);
				ProneDriver.ForceReset(rigIsAlive: true);
			}
		}

		private void Run(float dt)
		{
			if (!(dt <= 0f) && _levelReady && RigBinding.Bind(dt))
			{
				Diagnostics.Tick(dt);
				ProneInput.Tick(dt);
				if (Prefs.Enabled)
				{
					Drive();
				}
				ProneDriver.Tick(dt);
				if (RigPatches.Applied == 0)
				{
					ProneDriver.InjectCrouchInput();
				}
				if (!RigPatches.CrouchHoldPatched)
				{
					ProneDriver.DriveOffsets();
				}
			}
		}

		private void Drive()
		{
			if (Prefs.HoldMode)
			{
				if (ProneInput.Held)
				{
					ProneDriver.TryEngage("hold");
				}
				else
				{
					ProneDriver.Release("released");
				}
			}
			else if (ProneInput.Pressed)
			{
				ProneDriver.Toggle("input");
			}
		}

		public override void OnDeinitializeMelon()
		{
			try
			{
				Hooking.OnLevelLoaded -= OnLevelLoaded;
			}
			catch
			{
			}
			try
			{
				Hooking.OnLevelUnloaded -= OnLevelUnloaded;
			}
			catch
			{
			}
			try
			{
				ProneDriver.ForceReset(rigIsAlive: true);
			}
			catch
			{
			}
			try
			{
				RigBinding.Forget();
			}
			catch
			{
			}
			try
			{
				Prefs.Save();
			}
			catch
			{
			}
		}
	}
	internal static class BuildInfo
	{
		public const string Name = "DropProne";

		public const string Description = "Go prone in BONELAB. Crawl, take cover, stay flat.";

		public const string Author = "Rocner";

		public const string Company = null;

		public const string Version = "1.1.0";
	}
}
namespace DropProne.Prone
{
	internal static class CrouchLimits
	{
		private static bool _captured;

		private static SoftJointLimit _linearLimit;

		private static SoftJointLimitSpring _linearSpring;

		private static Vector3 _targetPosition;

		private static JointDrive _yDrive;

		private static float _colliderHeight;

		private static Vector3 _colliderCenter;

		public static bool Applied { get; private set; }

		public static bool Captured => _captured;

		public static float BaseLimit
		{
			get
			{
				if (!_captured)
				{
					return -1f;
				}
				return ((SoftJointLimit)(ref _linearLimit)).limit;
			}
		}

		public static void HoldExtended(float bonus)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			PhysicsRig physics = RigBinding.Physics;
			if ((Object)(object)physics == (Object)null || bonus <= 0f || !Capture(physics))
			{
				return;
			}
			try
			{
				ConfigurableJoint kneePelvisJoint = physics.kneePelvisJoint;
				if (!((Object)(object)kneePelvisJoint == (Object)null))
				{
					SoftJointLimit linearLimit = _linearLimit;
					((SoftJointLimit)(ref linearLimit)).limit = ((SoftJointLimit)(ref _linearLimit)).limit + bonus;
					kneePelvisJoint.linearLimit = linearLimit;
					Applied = true;
				}
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("Extending the knee joint failed: " + ex);
				Restore();
			}
		}

		public static void ApplySetLimit(float minMeters, float maxMeters)
		{
			PhysicsRig physics = RigBinding.Physics;
			if ((Object)(object)physics == (Object)null || !Capture(physics))
			{
				return;
			}
			try
			{
				physics.SetKneePelvisLimit(minMeters, maxMeters);
				Applied = true;
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("SetKneePelvisLimit failed: " + ex);
				Restore();
			}
		}

		public static void Restore()
		{
			//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_0048: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			if (!Applied && !_captured)
			{
				return;
			}
			PhysicsRig physics = RigBinding.Physics;
			if ((Object)(object)physics != (Object)null)
			{
				try
				{
					ConfigurableJoint kneePelvisJoint = physics.kneePelvisJoint;
					if ((Object)(object)kneePelvisJoint != (Object)null)
					{
						kneePelvisJoint.linearLimit = _linearLimit;
						kneePelvisJoint.linearLimitSpring = _linearSpring;
						kneePelvisJoint.targetPosition = _targetPosition;
						kneePelvisJoint.yDrive = _yDrive;
					}
					CapsuleCollider kneePelvisCol = physics.kneePelvisCol;
					if ((Object)(object)kneePelvisCol != (Object)null)
					{
						kneePelvisCol.height = _colliderHeight;
						kneePelvisCol.center = _colliderCenter;
					}
				}
				catch (Exception ex)
				{
					Melon<DropProneMod>.Logger.Error("Restoring crouch limits failed: " + ex);
				}
			}
			Applied = false;
			_captured = false;
		}

		public static void Forget()
		{
			Applied = false;
			_captured = false;
		}

		public static string Describe()
		{
			//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_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)
			PhysicsRig physics = RigBinding.Physics;
			if ((Object)(object)physics == (Object)null)
			{
				return "no physics rig";
			}
			try
			{
				ConfigurableJoint kneePelvisJoint = physics.kneePelvisJoint;
				CapsuleCollider kneePelvisCol = physics.kneePelvisCol;
				object obj;
				if (!((Object)(object)kneePelvisJoint != (Object)null))
				{
					obj = "n/a";
				}
				else
				{
					SoftJointLimit linearLimit = kneePelvisJoint.linearLimit;
					obj = ((SoftJointLimit)(ref linearLimit)).limit.ToString("0.000");
				}
				string value = (string)obj;
				object obj2;
				if (!((Object)(object)kneePelvisJoint != (Object)null))
				{
					obj2 = "n/a";
				}
				else
				{
					Vector3 targetPosition = kneePelvisJoint.targetPosition;
					obj2 = ((Vector3)(ref targetPosition)).ToString("F3");
				}
				string value2 = (string)obj2;
				string value3 = (((Object)(object)kneePelvisCol != (Object)null) ? kneePelvisCol.height.ToString("0.000") : "n/a");
				string value4 = (_captured ? ((SoftJointLimit)(ref _linearLimit)).limit.ToString("0.000") : "not captured");
				return $"linearLimit={value} (stock {value4}) targetPosition={value2} capsuleHeight={value3}";
			}
			catch (Exception ex)
			{
				return "unreadable (" + ex.Message + ")";
			}
		}

		private static bool Capture(PhysicsRig rig)
		{
			//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_0026: 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_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_0041: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			if (_captured)
			{
				return true;
			}
			try
			{
				ConfigurableJoint kneePelvisJoint = rig.kneePelvisJoint;
				if ((Object)(object)kneePelvisJoint != (Object)null)
				{
					_linearLimit = kneePelvisJoint.linearLimit;
					_linearSpring = kneePelvisJoint.linearLimitSpring;
					_targetPosition = kneePelvisJoint.targetPosition;
					_yDrive = kneePelvisJoint.yDrive;
				}
				CapsuleCollider kneePelvisCol = rig.kneePelvisCol;
				if ((Object)(object)kneePelvisCol != (Object)null)
				{
					_colliderHeight = kneePelvisCol.height;
					_colliderCenter = kneePelvisCol.center;
				}
				_captured = true;
				return true;
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("Reading crouch limits failed, leaving them alone: " + ex);
				return false;
			}
		}
	}
	internal static class Diagnostics
	{
		private const float MinUsefulTravel = 0.15f;

		private static float _watch;

		private static readonly bool[] _lastLeft = new bool[4];

		private static readonly bool[] _lastRight = new bool[4];

		private static readonly string[] ButtonNames = new string[4] { "Thumbstick", "A", "B", "Menu" };

		private static float _calibrate;

		private static bool _seeded;

		private static float _heightLow;

		private static float _heightHigh;

		private static float _crouchAtLow;

		private static float _crouchAtHigh;

		private static float _offsetAtLow;

		private static float _offsetAtHigh;

		private static float _targetAtLow;

		private static float _targetAtHigh;

		public static bool Watching => _watch > 0f;

		public static bool Calibrating => _calibrate > 0f;

		public static bool HasSuggestion { get; private set; }

		public static float SuggestedCrouchDrive { get; private set; }

		public static float SuggestedFeetOffset { get; private set; }

		public static void Report()
		{
			//IL_01d8: 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_0337: Unknown result type (might be due to invalid IL or missing references)
			Instance logger = Melon<DropProneMod>.Logger;
			logger.Msg("---- DropProne rig report ----");
			logger.Msg($"prone: engaged={ProneDriver.Engaged} depth={ProneDriver.Depth:0.00} limitsApplied={CrouchLimits.Applied}");
			if (!RigBinding.Ready)
			{
				logger.Msg("rig: not bound (load into a level first)");
				logger.Msg("------------------------------");
				return;
			}
			float num = RigBinding.HeadHeight();
			logger.Msg($"body: headAboveFeet={((num < 0f) ? "n/a" : (num.ToString("0.000") + "m"))} grounded={RigBinding.Grounded()} fallen={RigBinding.Fallen()}");
			try
			{
				PhysicsRig physics = RigBinding.Physics;
				logger.Msg($"physics: footSupported={physics.footSupported:0.000} pelvisHeightMult={physics.pelvisHeightMult:0.000} footballRadius={physics.footballRadius:0.000}");
			}
			catch (Exception ex)
			{
				logger.Msg("physics: unreadable (" + ex.Message + ")");
			}
			try
			{
				RemapRig remap = RigBinding.Remap;
				logger.Msg($"remap: vertState={remap.vertState} travState={remap.travState}");
				logger.Msg($"remap: crouchTarget={remap._crouchTarget:0.000} feetOffset={remap._feetOffset:0.000} crouchSpeedLimit={remap._crouchSpeedLimit:0.000} spineCrouchOff={remap._spineCrouchOff:0.000}");
			}
			catch (Exception ex2)
			{
				logger.Msg("remap: unreadable (" + ex2.Message + ")");
			}
			logger.Msg("speed: " + ProneDriver.DescribeSpeed());
			try
			{
				OpenControllerRig controller = RigBinding.Controller;
				if ((Object)(object)controller != (Object)null)
				{
					logger.Msg($"controller: crouch={((ControllerRig)controller)._crouch:0.000} crouchInput={((ControllerRig)controller)._crouchInput} vrVertState={controller.vrVertState}");
				}
			}
			catch (Exception ex3)
			{
				logger.Msg("controller: unreadable (" + ex3.Message + ")");
			}
			logger.Msg("kneePelvis: " + CrouchLimits.Describe());
			logger.Msg("------------------------------");
		}

		public static void Calibrate(float seconds)
		{
			if (!RigBinding.Ready)
			{
				Melon<DropProneMod>.Logger.Warning("No rig yet — load into a level first.");
				return;
			}
			if (ProneDriver.Active)
			{
				Melon<DropProneMod>.Logger.Warning("Stand up first — while prone the mod is writing these fields itself.");
				return;
			}
			_calibrate = seconds;
			_seeded = false;
			HasSuggestion = false;
			Melon<DropProneMod>.Logger.Msg($"Calibrating for {seconds:0}s: stand up all the way, then crouch as low as the game lets you.");
		}

		public static void ApplySuggestion()
		{
			if (!HasSuggestion)
			{
				Melon<DropProneMod>.Logger.Warning("Nothing to apply — run Calibrate first.");
				return;
			}
			Prefs.CrouchDrive = SuggestedCrouchDrive;
			Prefs.ProneFeetOffset = SuggestedFeetOffset;
			Prefs.ProneCrouchTarget = SuggestedFeetOffset;
			Prefs.Save();
			Melon<DropProneMod>.Logger.Msg($"Applied: Crouch Drive = {SuggestedCrouchDrive:0.00}, Feet Offset = {SuggestedFeetOffset:0.000}.");
		}

		public static void WatchInputs(float seconds)
		{
			_watch = seconds;
			Array.Clear(_lastLeft, 0, _lastLeft.Length);
			Array.Clear(_lastRight, 0, _lastRight.Length);
			Melon<DropProneMod>.Logger.Msg($"Watching controller inputs for {seconds:0}s — press things.");
		}

		public static void Tick(float dt)
		{
			TickWatch(dt);
			TickCalibrate(dt);
		}

		public static void Stop()
		{
			_watch = 0f;
			_calibrate = 0f;
		}

		private static void TickCalibrate(float dt)
		{
			if (!(_calibrate <= 0f))
			{
				_calibrate -= dt;
				Sample();
				if (_calibrate <= 0f)
				{
					Finish();
				}
			}
		}

		private static void Sample()
		{
			float num = RigBinding.HeadHeight();
			if (num <= 0f)
			{
				return;
			}
			float crouch;
			float feetOffset;
			float crouchTarget;
			try
			{
				OpenControllerRig controller = RigBinding.Controller;
				RemapRig remap = RigBinding.Remap;
				if ((Object)(object)controller == (Object)null || (Object)(object)remap == (Object)null)
				{
					return;
				}
				crouch = ((ControllerRig)controller)._crouch;
				feetOffset = remap._feetOffset;
				crouchTarget = remap._crouchTarget;
			}
			catch
			{
				return;
			}
			if (!_seeded)
			{
				_seeded = true;
				_heightLow = (_heightHigh = num);
				_crouchAtLow = (_crouchAtHigh = crouch);
				_offsetAtLow = (_offsetAtHigh = feetOffset);
				_targetAtLow = (_targetAtHigh = crouchTarget);
				return;
			}
			if (num < _heightLow)
			{
				_heightLow = num;
				_crouchAtLow = crouch;
				_offsetAtLow = feetOffset;
				_targetAtLow = crouchTarget;
			}
			if (num > _heightHigh)
			{
				_heightHigh = num;
				_crouchAtHigh = crouch;
				_offsetAtHigh = feetOffset;
				_targetAtHigh = crouchTarget;
			}
		}

		private static void Finish()
		{
			Instance logger = Melon<DropProneMod>.Logger;
			logger.Msg("---- DropProne calibration ----");
			if (!_seeded)
			{
				logger.Msg("No samples captured.");
				logger.Msg("-------------------------------");
				return;
			}
			float num = _heightHigh - _heightLow;
			logger.Msg($"headAboveFeet: tallest {_heightHigh:0.000}m, lowest {_heightLow:0.000}m (travel {num:0.000}m)");
			logger.Msg($"crouch:        standing {_crouchAtHigh:0.000}, crouched {_crouchAtLow:0.000}");
			logger.Msg($"feetOffset:    standing {_offsetAtHigh:0.000}, crouched {_offsetAtLow:0.000}");
			logger.Msg($"crouchTarget:  standing {_targetAtHigh:0.000}, crouched {_targetAtLow:0.000}");
			logger.Msg("kneePelvis:    " + CrouchLimits.Describe());
			if (num < 0.15f)
			{
				logger.Msg($"Only {num:0.000}m of travel seen — stand fully then crouch fully and run it again.");
				logger.Msg("-------------------------------");
				return;
			}
			SuggestedFeetOffset = _offsetAtLow + (_offsetAtLow - _offsetAtHigh) * 0.55f;
			SuggestedCrouchDrive = (Mathf.Approximately(_crouchAtLow, 0f) ? Prefs.CrouchDrive : (_crouchAtLow * 1.4f));
			HasSuggestion = true;
			logger.Msg($"suggested Crouch Drive = {SuggestedCrouchDrive:0.00}");
			logger.Msg($"suggested Feet Offset  = {SuggestedFeetOffset:0.000}");
			logger.Msg("Use 'Apply Suggested' in the Calibrate page to write them in.");
			logger.Msg("-------------------------------");
		}

		private static void TickWatch(float dt)
		{
			if (!(_watch <= 0f))
			{
				_watch -= dt;
				if (_watch <= 0f)
				{
					Melon<DropProneMod>.Logger.Msg("Input watch finished.");
					return;
				}
				SampleButtons(RigBinding.LeftController, _lastLeft, "left");
				SampleButtons(RigBinding.RightController, _lastRight, "right");
			}
		}

		private static void SampleButtons(BaseController controller, bool[] last, string hand)
		{
			if ((Object)(object)controller == (Object)null)
			{
				return;
			}
			bool[] array = new bool[4];
			try
			{
				array[0] = controller.GetThumbStick();
				array[1] = controller.GetAButton();
				array[2] = controller.GetBButton();
				array[3] = controller.GetMenuButton();
			}
			catch
			{
				return;
			}
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] != last[i])
				{
					last[i] = array[i];
					if (array[i])
					{
						Melon<DropProneMod>.Logger.Msg("input: " + hand + " " + ButtonNames[i]);
					}
				}
			}
		}
	}
	internal static class ProneDriver
	{
		private const float AirborneGrace = 0.4f;

		private static bool _speedCaptured;

		private static bool _touchedRig;

		private static float _baseMaxVelocity;

		private static float _airborneTimer;

		private static int _captureFrame = -1;

		public static float PlayerCrouch { get; private set; }

		public static bool Engaged { get; private set; }

		public static float Depth { get; private set; }

		public static bool Active => Depth > 0.001f;

		public static bool Toggle(string source)
		{
			if (!Engaged)
			{
				return TryEngage(source);
			}
			return Release(source);
		}

		public static bool TryEngage(string source)
		{
			if (!Prefs.Enabled)
			{
				return false;
			}
			if (Engaged)
			{
				return true;
			}
			if (!RigBinding.Ready)
			{
				Melon<DropProneMod>.Logger.Warning("No player rig yet, cannot go prone.");
				return false;
			}
			if (Prefs.StandWhenAirborne && !RigBinding.Grounded())
			{
				if (Prefs.LogEvents)
				{
					Melon<DropProneMod>.Logger.Msg("Not prone: airborne.");
				}
				return false;
			}
			Engaged = true;
			_airborneTimer = 0f;
			CaptureSpeed();
			if (Prefs.UseSetLimit)
			{
				CrouchLimits.ApplySetLimit(Prefs.ProneMin, Prefs.ProneMax);
			}
			if (Prefs.LogEvents)
			{
				Melon<DropProneMod>.Logger.Msg("Prone (" + source + ").");
			}
			return true;
		}

		public static bool Release(string reason)
		{
			if (!Engaged)
			{
				return false;
			}
			Engaged = false;
			if (Prefs.LogEvents)
			{
				Melon<DropProneMod>.Logger.Msg("Standing (" + reason + ").");
			}
			return true;
		}

		public static void Tick(float dt)
		{
			if (Engaged)
			{
				Safety(dt);
			}
			float num = (Engaged ? 1f : 0f);
			float num2 = (Engaged ? Prefs.EnterTime : Prefs.ExitTime);
			Depth = Mathf.MoveTowards(Depth, num, dt / Mathf.Max(0.01f, num2));
			if (RigBinding.Ready)
			{
				if (Active)
				{
					HoldDown();
				}
				else if (_touchedRig)
				{
					LetGo();
				}
			}
		}

		public static void InjectCrouchInput()
		{
			if (!Active || !Prefs.DriveCrouchInput)
			{
				return;
			}
			ControllerRig controller = (ControllerRig)(object)RigBinding.Controller;
			if ((Object)(object)controller == (Object)null)
			{
				return;
			}
			try
			{
				if (_captureFrame != Time.frameCount)
				{
					_captureFrame = Time.frameCount;
					PlayerCrouch = controller._crouch;
				}
				float num = Prefs.CrouchDrive * Depth;
				controller._crouch = ((num < 0f) ? Mathf.Min(PlayerCrouch, num) : Mathf.Max(PlayerCrouch, num));
				controller._crouchInput = true;
			}
			catch
			{
			}
		}

		public static void DriveOffsets()
		{
			if (!Active || !Prefs.ForceFeetOffset)
			{
				return;
			}
			RemapRig remap = RigBinding.Remap;
			if ((Object)(object)remap == (Object)null)
			{
				return;
			}
			try
			{
				remap._feetOffset = Mathf.Lerp(remap._feetOffset, Prefs.ProneFeetOffset, Depth);
				remap._crouchTarget = Mathf.Lerp(remap._crouchTarget, Prefs.ProneCrouchTarget, Depth);
				_touchedRig = true;
			}
			catch
			{
			}
		}

		public static void ForceReset(bool rigIsAlive)
		{
			Engaged = false;
			Depth = 0f;
			_airborneTimer = 0f;
			if (rigIsAlive)
			{
				LetGo();
				return;
			}
			CrouchLimits.Forget();
			_speedCaptured = false;
			_touchedRig = false;
		}

		public static string DescribeSpeed()
		{
			RemapRig remap = RigBinding.Remap;
			if ((Object)(object)remap == (Object)null)
			{
				return "no remap rig";
			}
			try
			{
				string value = (_speedCaptured ? _baseMaxVelocity.ToString("0.00") : "not captured");
				return $"maxVelocity={remap.maxVelocity:0.00} currentMax={remap.currentMaxVelocity:0.00} baseline={value}";
			}
			catch (Exception ex)
			{
				return "unreadable (" + ex.Message + ")";
			}
		}

		private static void Safety(float dt)
		{
			if (RigBinding.Fallen())
			{
				Release("ragdolled");
			}
			else
			{
				if (!Prefs.StandWhenAirborne)
				{
					return;
				}
				if (RigBinding.Grounded())
				{
					_airborneTimer = 0f;
					return;
				}
				_airborneTimer += dt;
				if (_airborneTimer > 0.4f)
				{
					Release("airborne");
				}
			}
		}

		private static void HoldDown()
		{
			RemapRig remap = RigBinding.Remap;
			if ((Object)(object)remap == (Object)null)
			{
				return;
			}
			if (Prefs.ExtendJoint)
			{
				CrouchLimits.HoldExtended(Prefs.JointBonus * Depth);
			}
			try
			{
				if (_speedCaptured)
				{
					remap.maxVelocity = Mathf.Lerp(_baseMaxVelocity, Prefs.CrawlSpeed, Depth);
				}
				if (Prefs.SetVertState && Depth > 0.6f)
				{
					remap.vertState = (VertState)3;
					OpenControllerRig controller = RigBinding.Controller;
					if ((Object)(object)controller != (Object)null)
					{
						controller.vrVertState = (VrVertState)4;
					}
				}
				_touchedRig = true;
			}
			catch
			{
			}
		}

		private static void LetGo()
		{
			RemapRig remap = RigBinding.Remap;
			if ((Object)(object)remap != (Object)null)
			{
				try
				{
					if (_speedCaptured)
					{
						remap.maxVelocity = _baseMaxVelocity;
					}
					if (Prefs.SetVertState)
					{
						remap.vertState = (VertState)0;
					}
					OpenControllerRig controller = RigBinding.Controller;
					if ((Object)(object)controller != (Object)null && Prefs.SetVertState)
					{
						controller.vrVertState = (VrVertState)0;
					}
				}
				catch
				{
				}
			}
			CrouchLimits.Restore();
			_speedCaptured = false;
			_touchedRig = false;
		}

		private static void CaptureSpeed()
		{
			if (_speedCaptured)
			{
				return;
			}
			RemapRig remap = RigBinding.Remap;
			if ((Object)(object)remap == (Object)null)
			{
				return;
			}
			try
			{
				_baseMaxVelocity = remap.maxVelocity;
				_speedCaptured = _baseMaxVelocity > 0.01f;
			}
			catch
			{
			}
		}
	}
	internal static class ProneInput
	{
		private enum ButtonKind
		{
			Stick,
			A,
			B
		}

		private const float CrouchThreshold = 0.85f;

		private static float _crouchHeld;

		private static bool _crouchFired;

		public static bool Pressed { get; private set; }

		public static bool Held { get; private set; }

		public static void Tick(float dt)
		{
			//IL_0028: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			Pressed = false;
			Held = false;
			try
			{
				ReadBinding(dt);
			}
			catch
			{
				_crouchHeld = 0f;
				_crouchFired = false;
			}
			try
			{
				if ((int)Prefs.Key != 0)
				{
					if (Input.GetKeyDown(Prefs.Key))
					{
						Pressed = true;
					}
					if (Input.GetKey(Prefs.Key))
					{
						Held = true;
					}
				}
			}
			catch
			{
			}
		}

		public static void Forget()
		{
			_crouchHeld = 0f;
			_crouchFired = false;
			Pressed = false;
			Held = false;
		}

		private static void ReadBinding(float dt)
		{
			switch (Prefs.Bind)
			{
			case ProneBind.LeftStickClick:
				ReadButton(RigBinding.LeftController, ButtonKind.Stick);
				break;
			case ProneBind.RightStickClick:
				ReadButton(RigBinding.RightController, ButtonKind.Stick);
				break;
			case ProneBind.LeftBButton:
				ReadButton(RigBinding.LeftController, ButtonKind.B);
				break;
			case ProneBind.RightBButton:
				ReadButton(RigBinding.RightController, ButtonKind.B);
				break;
			case ProneBind.LeftAButton:
				ReadButton(RigBinding.LeftController, ButtonKind.A);
				break;
			case ProneBind.RightAButton:
				ReadButton(RigBinding.RightController, ButtonKind.A);
				break;
			case ProneBind.HoldCrouch:
				ReadHoldCrouch(dt);
				break;
			}
		}

		private static void ReadButton(BaseController controller, ButtonKind kind)
		{
			if ((Object)(object)controller == (Object)null)
			{
				return;
			}
			switch (kind)
			{
			case ButtonKind.Stick:
				if (controller.GetThumbStickDown())
				{
					Pressed = true;
				}
				if (controller.GetThumbStick())
				{
					Held = true;
				}
				break;
			case ButtonKind.A:
				if (controller.GetAButtonDown())
				{
					Pressed = true;
				}
				if (controller.GetAButton())
				{
					Held = true;
				}
				break;
			case ButtonKind.B:
				if (controller.GetBButtonDown())
				{
					Pressed = true;
				}
				if (controller.GetBButton())
				{
					Held = true;
				}
				break;
			}
		}

		private static void ReadHoldCrouch(float dt)
		{
			ControllerRig controller = (ControllerRig)(object)RigBinding.Controller;
			if ((Object)(object)controller == (Object)null)
			{
				_crouchHeld = 0f;
				_crouchFired = false;
				return;
			}
			if (Mathf.Abs(ProneDriver.Active ? ProneDriver.PlayerCrouch : controller._crouch) < 0.85f)
			{
				_crouchHeld = 0f;
				_crouchFired = false;
				return;
			}
			Held = true;
			_crouchHeld += dt;
			if (!(_crouchHeld < Prefs.HoldCrouchTime) && !_crouchFired)
			{
				_crouchFired = true;
				Pressed = true;
			}
		}
	}
	internal static class RigBinding
	{
		private static float _retry;

		public static RigManager Manager { get; private set; }

		public static PhysicsRig Physics { get; private set; }

		public static RemapRig Remap { get; private set; }

		public static OpenControllerRig Controller { get; private set; }

		public static BaseController LeftController { get; private set; }

		public static BaseController RightController { get; private set; }

		public static bool Ready
		{
			get
			{
				if ((Object)(object)Physics != (Object)null)
				{
					return (Object)(object)Remap != (Object)null;
				}
				return false;
			}
		}

		public static void Forget()
		{
			Manager = null;
			Physics = null;
			Remap = null;
			Controller = null;
			LeftController = null;
			RightController = null;
			_retry = 0f;
		}

		public static bool Bind(float dt)
		{
			if (Ready)
			{
				return true;
			}
			_retry -= dt;
			if (_retry > 0f)
			{
				return false;
			}
			_retry = 0.5f;
			try
			{
				Manager = Player.RigManager;
				Physics = Player.PhysicsRig;
				Remap = Player.RemapRig;
				Controller = Player.ControllerRig;
				LeftController = Player.LeftController;
				RightController = Player.RightController;
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("Binding the player rig failed: " + ex);
				Forget();
				return false;
			}
			return Ready;
		}

		public static float HeadHeight()
		{
			//IL_0055: 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)
			try
			{
				Transform head = Player.Head;
				PhysicsRig physics = Physics;
				if ((Object)(object)head == (Object)null || (Object)(object)physics == (Object)null)
				{
					return -1f;
				}
				Transform val = (((Object)(object)physics.feet != (Object)null) ? physics.feet.transform : null);
				if ((Object)(object)val == (Object)null)
				{
					return -1f;
				}
				return head.position.y - val.position.y;
			}
			catch
			{
				return -1f;
			}
		}

		public static bool Grounded()
		{
			try
			{
				PhysicsRig physics = Physics;
				return (Object)(object)physics != (Object)null && physics.footSupported > 0.25f;
			}
			catch
			{
				return true;
			}
		}

		public static bool Fallen()
		{
			try
			{
				PhysicsRig physics = Physics;
				return (Object)(object)physics != (Object)null && physics.manualFallenState;
			}
			catch
			{
				return false;
			}
		}
	}
}
namespace DropProne.Patches
{
	internal static class RigPatches
	{
		public static int Applied { get; private set; }

		public static bool CrouchHoldPatched { get; private set; }

		public static void Apply(Harmony harmony)
		{
			if (harmony != null)
			{
				Patch(harmony, typeof(OpenControllerRig), "OnEarlyUpdate", "AfterControllerUpdate");
				Patch(harmony, typeof(OpenControllerRig), "OnUpdate", "AfterControllerUpdate");
				if (Applied == 0)
				{
					Patch(harmony, typeof(ControllerRig), "OnUpdate", "AfterControllerUpdate");
				}
				CrouchHoldPatched = Patch(harmony, typeof(RemapRig), "CrouchHold", "AfterCrouchHold");
				if (Applied == 0)
				{
					Melon<DropProneMod>.Logger.Error("No rig hooks landed. Prone will still try to drive the rig from OnUpdate, but it may fight the game.");
				}
			}
		}

		private static bool Patch(Harmony harmony, Type type, string method, string postfixName)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Melon<DropProneMod>.Logger.Warning(type.Name + "." + method + " not found, skipping that hook.");
					return false;
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(RigPatches), postfixName, (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Applied++;
				Melon<DropProneMod>.Logger.Msg($"Hooked {type.Name}.{method}.");
				return true;
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error($"Patching {type.Name}.{method} failed: " + ex);
				return false;
			}
		}

		private static void AfterControllerUpdate()
		{
			ProneDriver.InjectCrouchInput();
		}

		private static void AfterCrouchHold()
		{
			ProneDriver.DriveOffsets();
		}
	}
}
namespace DropProne.Menu
{
	internal static class MenuPage
	{
		private static readonly Color Accent = new Color(0.4f, 0.68f, 0.4f);

		private static readonly string[] BindNames = new string[8] { "Menu / key only", "Left stick click", "Right stick click", "Left B button", "Right B button", "Left A button", "Right A button", "Hold crouch" };

		public static void Build()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Page root;
			try
			{
				root = Page.Root.CreatePage("Drop Prone", Accent, 0, true);
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("BoneMenu root page failed: " + ex);
				return;
			}
			Section("main", delegate
			{
				BuildMain(root);
			});
			Section("feel", delegate
			{
				BuildFeel(root);
			});
			Section("depth", delegate
			{
				BuildDepth(root);
			});
			Section("diagnostics", delegate
			{
				BuildDiagnostics(root);
			});
		}

		private static void Section(string name, Action build)
		{
			try
			{
				build();
			}
			catch (Exception ex)
			{
				Melon<DropProneMod>.Logger.Error("BoneMenu section '" + name + "' failed: " + ex);
			}
		}

		private static void BuildMain(Page root)
		{
			//IL_0006: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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)
			root.CreateBool("Enabled", Accent, Prefs.Enabled, (Action<bool>)delegate(bool value)
			{
				Prefs.Enabled = value;
				Prefs.Save();
				if (!value)
				{
					ProneDriver.Release("disabled");
				}
			});
			root.CreateFunction("Go Prone / Stand", Accent, (Action)delegate
			{
				ProneDriver.Toggle("menu");
			});
			root.CreateInt("Binding", Accent, (int)Prefs.Bind, 1, 0, 7, (Action<int>)delegate(int value)
			{
				Prefs.Bind = (ProneBind)value;
				Prefs.Save();
				ProneInput.Forget();
				Melon<DropProneMod>.Logger.Msg("Binding: " + BindNames[Mathf.Clamp(value, 0, 7)]);
			});
			root.CreateBool("Hold Instead Of Toggle", Accent, Prefs.HoldMode, (Action<bool>)delegate(bool value)
			{
				Prefs.HoldMode = value;
				Prefs.Save();
				ProneDriver.Release("binding changed");
			});
			root.CreateFloat("Hold Crouch Time", Accent, Prefs.HoldCrouchTime, 0.05f, 0.1f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.HoldCrouchTime = value;
				Prefs.Save();
			});
		}

		private static void BuildFeel(Page root)
		{
			//IL_0006: 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_005c: 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_00e4: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			Page obj = root.CreatePage("Feel", Accent, 0, true);
			obj.CreateFloat("Crawl Speed", Accent, Prefs.CrawlSpeed, 0.05f, 0.05f, 6f, (Action<float>)delegate(float value)
			{
				Prefs.CrawlSpeed = value;
				Prefs.Save();
			});
			obj.CreateFloat("Drop Time", Accent, Prefs.EnterTime, 0.05f, 0.05f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.EnterTime = value;
				Prefs.Save();
			});
			obj.CreateFloat("Stand Time", Accent, Prefs.ExitTime, 0.05f, 0.05f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.ExitTime = value;
				Prefs.Save();
			});
			obj.CreateBool("Stand When Airborne", Accent, Prefs.StandWhenAirborne, (Action<bool>)delegate(bool value)
			{
				Prefs.StandWhenAirborne = value;
				Prefs.Save();
			});
			obj.CreateBool("Set Prone Vert State", Accent, Prefs.SetVertState, (Action<bool>)delegate(bool value)
			{
				Prefs.SetVertState = value;
				Prefs.Save();
			});
			obj.CreateBool("Log Events", Accent, Prefs.LogEvents, (Action<bool>)delegate(bool value)
			{
				Prefs.LogEvents = value;
				Prefs.Save();
			});
		}

		private static void BuildDepth(Page root)
		{
			//IL_0006: 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_004d: 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_00c6: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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)
			Page obj = root.CreatePage("Depth", Accent, 0, true);
			obj.CreateBool("Drive Crouch Input", Accent, Prefs.DriveCrouchInput, (Action<bool>)delegate(bool value)
			{
				Prefs.DriveCrouchInput = value;
				Prefs.Save();
			});
			obj.CreateFloat("Crouch Drive", Accent, Prefs.CrouchDrive, 0.1f, -4f, 4f, (Action<float>)delegate(float value)
			{
				Prefs.CrouchDrive = value;
				Prefs.Save();
			});
			obj.CreateBool("Extend Knee Joint", Accent, Prefs.ExtendJoint, (Action<bool>)delegate(bool value)
			{
				Prefs.ExtendJoint = value;
				Prefs.Save();
				if (!value)
				{
					CrouchLimits.Restore();
				}
			});
			obj.CreateFloat("Joint Travel Bonus", Accent, Prefs.JointBonus, 0.05f, 0f, 1.5f, (Action<float>)delegate(float value)
			{
				Prefs.JointBonus = value;
				Prefs.Save();
			});
			obj.CreateBool("Force Feet Offset", Accent, Prefs.ForceFeetOffset, (Action<bool>)delegate(bool value)
			{
				Prefs.ForceFeetOffset = value;
				Prefs.Save();
			});
			obj.CreateFloat("Prone Feet Offset", Accent, Prefs.ProneFeetOffset, 0.05f, -3f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.ProneFeetOffset = value;
				Prefs.Save();
			});
			obj.CreateFloat("Prone Crouch Target", Accent, Prefs.ProneCrouchTarget, 0.05f, -3f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.ProneCrouchTarget = value;
				Prefs.Save();
			});
			obj.CreateFunction("Restore Joint", Accent, (Action)CrouchLimits.Restore);
			BuildLegacy(obj);
		}

		private static void BuildLegacy(Page depth)
		{
			//IL_0006: 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_004d: 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)
			Page obj = depth.CreatePage("SetKneePelvisLimit", Accent, 0, true);
			obj.CreateBool("Use SetKneePelvisLimit", Accent, Prefs.UseSetLimit, (Action<bool>)delegate(bool value)
			{
				Prefs.UseSetLimit = value;
				Prefs.Save();
				if (!value)
				{
					CrouchLimits.Restore();
				}
			});
			obj.CreateFloat("Prone Min", Accent, Prefs.ProneMin, 0.02f, 0f, 1.2f, (Action<float>)delegate(float value)
			{
				Prefs.ProneMin = value;
				Prefs.Save();
				Reapply();
			});
			obj.CreateFloat("Prone Max", Accent, Prefs.ProneMax, 0.05f, 0.2f, 3f, (Action<float>)delegate(float value)
			{
				Prefs.ProneMax = value;
				Prefs.Save();
				Reapply();
			});
		}

		private static void BuildDiagnostics(Page root)
		{
			//IL_0006: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			Page obj = root.CreatePage("Diagnostics", Accent, 0, true);
			obj.CreateFunction("Calibrate (12s)", Accent, (Action)delegate
			{
				Diagnostics.Calibrate(12f);
			});
			obj.CreateFunction("Apply Suggested", Accent, (Action)Diagnostics.ApplySuggestion);
			obj.CreateFunction("Report Rig State", Accent, (Action)Diagnostics.Report);
			obj.CreateFunction("Watch Inputs (10s)", Accent, (Action)delegate
			{
				Diagnostics.WatchInputs(10f);
			});
			obj.CreateFunction("Stop", Accent, (Action)Diagnostics.Stop);
		}

		private static void Reapply()
		{
			if (CrouchLimits.Applied && Prefs.UseSetLimit)
			{
				CrouchLimits.Restore();
				CrouchLimits.ApplySetLimit(Prefs.ProneMin, Prefs.ProneMax);
			}
		}
	}
}
namespace DropProne.Config
{
	internal enum ProneBind
	{
		MenuAndKeyOnly,
		LeftStickClick,
		RightStickClick,
		LeftBButton,
		RightBButton,
		LeftAButton,
		RightAButton,
		HoldCrouch
	}
	internal static class Prefs
	{
		private static MelonPreferences_Category _category;

		private static MelonPreferences_Entry<bool> _enabled;

		private static MelonPreferences_Entry<int> _bind;

		private static MelonPreferences_Entry<bool> _holdMode;

		private static MelonPreferences_Entry<int> _key;

		private static MelonPreferences_Entry<float> _holdCrouchTime;

		private static MelonPreferences_Entry<float> _enterTime;

		private static MelonPreferences_Entry<float> _exitTime;

		private static MelonPreferences_Entry<float> _crawlSpeed;

		private static MelonPreferences_Entry<bool> _driveCrouchInput;

		private static MelonPreferences_Entry<float> _crouchDrive;

		private static MelonPreferences_Entry<bool> _extendJoint;

		private static MelonPreferences_Entry<float> _jointBonus;

		private static MelonPreferences_Entry<bool> _useSetLimit;

		private static MelonPreferences_Entry<float> _proneMin;

		private static MelonPreferences_Entry<float> _proneMax;

		private static MelonPreferences_Entry<bool> _forceFeetOffset;

		private static MelonPreferences_Entry<float> _proneFeetOffset;

		private static MelonPreferences_Entry<float> _proneCrouchTarget;

		private static MelonPreferences_Entry<bool> _setVertState;

		private static MelonPreferences_Entry<bool> _standWhenAirborne;

		private static MelonPreferences_Entry<bool> _logEvents;

		public static bool Enabled
		{
			get
			{
				return _enabled?.Value ?? true;
			}
			set
			{
				if (_enabled != null)
				{
					_enabled.Value = value;
				}
			}
		}

		public static ProneBind Bind
		{
			get
			{
				return (ProneBind)Mathf.Clamp(_bind?.Value ?? 1, 0, 7);
			}
			set
			{
				if (_bind != null)
				{
					_bind.Value = (int)value;
				}
			}
		}

		public static bool HoldMode
		{
			get
			{
				return _holdMode?.Value ?? false;
			}
			set
			{
				if (_holdMode != null)
				{
					_holdMode.Value = value;
				}
			}
		}

		public static KeyCode Key
		{
			get
			{
				MelonPreferences_Entry<int> key = _key;
				if (key != null)
				{
					return (KeyCode)key.Value;
				}
				return (KeyCode)99;
			}
			set
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Expected I4, but got Unknown
				if (_key != null)
				{
					_key.Value = (int)value;
				}
			}
		}

		public static float HoldCrouchTime
		{
			get
			{
				return Mathf.Clamp(_holdCrouchTime?.Value ?? 0.55f, 0.1f, 3f);
			}
			set
			{
				if (_holdCrouchTime != null)
				{
					_holdCrouchTime.Value = value;
				}
			}
		}

		public static float EnterTime
		{
			get
			{
				return Mathf.Clamp(_enterTime?.Value ?? 0.45f, 0.05f, 3f);
			}
			set
			{
				if (_enterTime != null)
				{
					_enterTime.Value = value;
				}
			}
		}

		public static float ExitTime
		{
			get
			{
				return Mathf.Clamp(_exitTime?.Value ?? 0.35f, 0.05f, 3f);
			}
			set
			{
				if (_exitTime != null)
				{
					_exitTime.Value = value;
				}
			}
		}

		public static float CrawlSpeed
		{
			get
			{
				return Mathf.Clamp(_crawlSpeed?.Value ?? 0.7f, 0.05f, 6f);
			}
			set
			{
				if (_crawlSpeed != null)
				{
					_crawlSpeed.Value = value;
				}
			}
		}

		public static bool DriveCrouchInput
		{
			get
			{
				return _driveCrouchInput?.Value ?? true;
			}
			set
			{
				if (_driveCrouchInput != null)
				{
					_driveCrouchInput.Value = value;
				}
			}
		}

		public static float CrouchDrive
		{
			get
			{
				return Mathf.Clamp(_crouchDrive?.Value ?? (-1.4f), -4f, 4f);
			}
			set
			{
				if (_crouchDrive != null)
				{
					_crouchDrive.Value = value;
				}
			}
		}

		public static bool ExtendJoint
		{
			get
			{
				return _extendJoint?.Value ?? true;
			}
			set
			{
				if (_extendJoint != null)
				{
					_extendJoint.Value = value;
				}
			}
		}

		public static float JointBonus
		{
			get
			{
				return Mathf.Clamp(_jointBonus?.Value ?? 0.35f, 0f, 1.5f);
			}
			set
			{
				if (_jointBonus != null)
				{
					_jointBonus.Value = value;
				}
			}
		}

		public static bool UseSetLimit
		{
			get
			{
				return _useSetLimit?.Value ?? false;
			}
			set
			{
				if (_useSetLimit != null)
				{
					_useSetLimit.Value = value;
				}
			}
		}

		public static float ProneMin
		{
			get
			{
				return Mathf.Clamp(_proneMin?.Value ?? 0.12f, 0f, 1.2f);
			}
			set
			{
				if (_proneMin != null)
				{
					_proneMin.Value = value;
				}
			}
		}

		public static float ProneMax
		{
			get
			{
				return Mathf.Clamp(_proneMax?.Value ?? 1.6f, 0.2f, 3f);
			}
			set
			{
				if (_proneMax != null)
				{
					_proneMax.Value = value;
				}
			}
		}

		public static bool ForceFeetOffset
		{
			get
			{
				return _forceFeetOffset?.Value ?? true;
			}
			set
			{
				if (_forceFeetOffset != null)
				{
					_forceFeetOffset.Value = value;
				}
			}
		}

		public static float ProneFeetOffset
		{
			get
			{
				return Mathf.Clamp(_proneFeetOffset?.Value ?? (-1.15f), -3f, 3f);
			}
			set
			{
				if (_proneFeetOffset != null)
				{
					_proneFeetOffset.Value = value;
				}
			}
		}

		public static float ProneCrouchTarget
		{
			get
			{
				return Mathf.Clamp(_proneCrouchTarget?.Value ?? (-1.15f), -3f, 3f);
			}
			set
			{
				if (_proneCrouchTarget != null)
				{
					_proneCrouchTarget.Value = value;
				}
			}
		}

		public static bool SetVertState
		{
			get
			{
				return _setVertState?.Value ?? true;
			}
			set
			{
				if (_setVertState != null)
				{
					_setVertState.Value = value;
				}
			}
		}

		public static bool StandWhenAirborne
		{
			get
			{
				return _standWhenAirborne?.Value ?? true;
			}
			set
			{
				if (_standWhenAirborne != null)
				{
					_standWhenAirborne.Value = value;
				}
			}
		}

		public static bool LogEvents
		{
			get
			{
				return _logEvents?.Value ?? true;
			}
			set
			{
				if (_logEvents != null)
				{
					_logEvents.Value = value;
				}
			}
		}

		public static void Load()
		{
			_category = MelonPreferences.CreateCategory("DropProne");
			_enabled = _category.CreateEntry<bool>("Enabled", true, "Enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			_bind = _category.CreateEntry<int>("Bind", 1, "Controller Binding", (string)null, false, false, (ValueValidator)null, (string)null);
			_holdMode = _category.CreateEntry<bool>("HoldMode", false, "Hold Instead Of Toggle", (string)null, false, false, (ValueValidator)null, (string)null);
			_key = _category.CreateEntry<int>("Key", 99, "Keyboard Key", (string)null, false, false, (ValueValidator)null, (string)null);
			_holdCrouchTime = _category.CreateEntry<float>("HoldCrouchTime", 0.55f, "Hold Crouch Time (s)", (string)null, false, false, (ValueValidator)null, (string)null);
			_enterTime = _category.CreateEntry<float>("EnterTime", 0.45f, "Drop Time (s)", (string)null, false, false, (ValueValidator)null, (string)null);
			_exitTime = _category.CreateEntry<float>("ExitTime", 0.35f, "Stand Time (s)", (string)null, false, false, (ValueValidator)null, (string)null);
			_crawlSpeed = _category.CreateEntry<float>("CrawlSpeed2", 0.7f, "Crawl Speed", (string)null, false, false, (ValueValidator)null, (string)null);
			_driveCrouchInput = _category.CreateEntry<bool>("DriveCrouchInput", true, "Drive Crouch Input", (string)null, false, false, (ValueValidator)null, (string)null);
			_crouchDrive = _category.CreateEntry<float>("CrouchDrive", -1.4f, "Crouch Drive", (string)null, false, false, (ValueValidator)null, (string)null);
			_extendJoint = _category.CreateEntry<bool>("ExtendJoint", true, "Extend Knee Joint", (string)null, false, false, (ValueValidator)null, (string)null);
			_jointBonus = _category.CreateEntry<float>("JointBonus", 0.35f, "Joint Travel Bonus (m)", (string)null, false, false, (ValueValidator)null, (string)null);
			_useSetLimit = _category.CreateEntry<bool>("UseSetLimit", false, "Use SetKneePelvisLimit", (string)null, false, false, (ValueValidator)null, (string)null);
			_proneMin = _category.CreateEntry<float>("ProneMin", 0.12f, "Prone Min (m)", (string)null, false, false, (ValueValidator)null, (string)null);
			_proneMax = _category.CreateEntry<float>("ProneMax", 1.6f, "Prone Max (m)", (string)null, false, false, (ValueValidator)null, (string)null);
			_forceFeetOffset = _category.CreateEntry<bool>("ForceFeetOffset", true, "Force Feet Offset", (string)null, false, false, (ValueValidator)null, (string)null);
			_proneFeetOffset = _category.CreateEntry<float>("ProneFeetOffset", -1.15f, "Prone Feet Offset", (string)null, false, false, (ValueValidator)null, (string)null);
			_proneCrouchTarget = _category.CreateEntry<float>("ProneCrouchTarget", -1.15f, "Prone Crouch Target", (string)null, false, false, (ValueValidator)null, (string)null);
			_setVertState = _category.CreateEntry<bool>("SetVertState", true, "Set Prone Vert State", (string)null, false, false, (ValueValidator)null, (string)null);
			_standWhenAirborne = _category.CreateEntry<bool>("StandWhenAirborne", true, "Stand When Airborne", (string)null, false, false, (ValueValidator)null, (string)null);
			_logEvents = _category.CreateEntry<bool>("LogEvents", true, "Log Events", (string)null, false, false, (ValueValidator)null, (string)null);
		}

		public static void Save()
		{
			try
			{
				MelonPreferences_Category category = _category;
				if (category != null)
				{
					category.SaveToFile(false);
				}
			}
			catch
			{
			}
		}
	}
}