Decompiled source of HTFSlide v1.6.0

plugins/HTFSlide.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("HTFSlide")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: AssemblyInformationalVersion("1.6.0")]
[assembly: AssemblyProduct("HTFSlide")]
[assembly: AssemblyTitle("HTFSlide")]
[assembly: AssemblyVersion("1.6.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 HTFSlide
{
	[BepInPlugin("com.hatsuneexo.htfslide", "HTF Slide", "1.6.0")]
	[BepInProcess("How to Fish.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.hatsuneexo.htfslide";

		internal static ManualLogSource Log;

		internal static ConfigEntry<Key> SlideKey;

		internal static ConfigEntry<float> Duration;

		internal static ConfigEntry<float> StartSpeed;

		internal static ConfigEntry<float> EndSpeed;

		internal static ConfigEntry<float> Cooldown;

		internal static ConfigEntry<bool> RequireSprint;

		internal static ConfigEntry<float> SteerControl;

		internal static ConfigEntry<float> SlideJumpBoost;

		internal static ConfigEntry<float> RampLaunchBoost;

		internal static ConfigEntry<bool> KeepSpeedInAir;

		internal static ConfigEntry<float> FullSpeedTime;

		internal static ConfigEntry<float> AirGravityMultiplier;

		internal static ConfigEntry<float> SpeedFloor;

		internal static ConfigEntry<float> SpeedCeiling;

		internal static ConfigEntry<float> LaunchScaleAtTopSpeed;

		internal static ConfigEntry<float> MinAirGravity;

		internal static ConfigEntry<float> MaxAirSeconds;

		internal static ConfigEntry<bool> ChainMomentum;

		internal static ConfigEntry<float> ChainRetention;

		internal static ConfigEntry<float> MaxSpeed;

		internal static ConfigEntry<float> MomentumGrace;

		internal static ConfigEntry<bool> SprintToggle;

		internal static ConfigEntry<Key> SprintKey;

		internal static ConfigEntry<bool> StopSprintWhenIdle;

		internal static bool SprintLatched;

		private static float _slideRequestedAt = -99f;

		private const float SlideRequestWindow = 0.25f;

		internal static bool CrouchHeld;

		private static bool _loggedCrouchHook;

		private static bool _loggedSprintHook;

		private void Awake()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Expected O, but got Unknown
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Expected O, but got Unknown
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Expected O, but got Unknown
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Expected O, but got Unknown
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Expected O, but got Unknown
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			SlideKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Slide", "SlideKey", (Key)55, "Tecla de deslizamiento. Es la misma de agacharse por defecto.");
			RequireSprint = ((BaseUnityPlugin)this).Config.Bind<bool>("Slide", "RequireSprint", true, "Exige estar esprintando para deslizarse. Si lo apagas, te deslizas desde caminar.");
			Duration = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "Duration", 1.5f, new ConfigDescription("Cuánto dura el deslizamiento, en segundos.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f), Array.Empty<object>()));
			StartSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "StartSpeed", 11f, new ConfigDescription("Velocidad al iniciar el deslizamiento.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 30f), Array.Empty<object>()));
			EndSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "EndSpeed", 4f, new ConfigDescription("Velocidad al terminar, antes de devolverte el control.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "Cooldown", 0.6f, new ConfigDescription("Segundos de espera entre deslizamientos.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			SteerControl = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "SteerControl", 0.25f, new ConfigDescription("Cuánto puedes girar mientras te deslizas. 0 = en línea recta, 1 = control total.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			SlideJumpBoost = ((BaseUnityPlugin)this).Config.Bind<float>("SlideJump", "SlideJumpBoost", 3.5f, new ConfigDescription("Impulso vertical extra al saltar mientras te deslizas. 0 lo desactiva.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>()));
			RampLaunchBoost = ((BaseUnityPlugin)this).Config.Bind<float>("SlideJump", "RampLaunchBoost", 2f, new ConfigDescription("Impulso vertical extra al despegar de un borde o rampa deslizándote, sin pulsar salto. 0 lo desactiva.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>()));
			KeepSpeedInAir = ((BaseUnityPlugin)this).Config.Bind<bool>("SlideJump", "KeepSpeedInAir", true, "Conserva la velocidad horizontal del deslizamiento durante todo el vuelo, en vez de frenarte en cuanto despegas. Puedes seguir girando: solo impide que pierdas impulso.");
			AirGravityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("SlideJump", "AirGravityMultiplier", 0.45f, new ConfigDescription("Multiplica la gravedad extra del juego mientras vuelas con impulso. 1 = gravedad original, 0.45 = vuelo más largo y flotado, 0 = solo gravedad normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			FullSpeedTime = ((BaseUnityPlugin)this).Config.Bind<float>("Slide", "FullSpeedTime", 0.25f, new ConfigDescription("Segundos a velocidad máxima antes de empezar a frenar. El resto de la duración es la deceleración. 0 = empieza a frenar desde el primer instante.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			SpeedFloor = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "SpeedFloor", 6f, new ConfigDescription("Velocidad a partir de la cual empiezan a notarse las mejoras. Por debajo de esto todo se comporta como en el juego original.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			SpeedCeiling = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "SpeedCeiling", 18f, new ConfigDescription("Velocidad a la que se alcanza el máximo efecto: salto más largo y caída más lenta.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 40f), Array.Empty<object>()));
			LaunchScaleAtTopSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "LaunchScaleAtTopSpeed", 2.5f, new ConfigDescription("Cuánto se multiplica el impulso de despegue al ir a tope de velocidad. 1 = siempre igual, 2.5 = a máxima velocidad saltas dos veces y media más.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>()));
			MinAirGravity = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "MinAirGravity", 0.12f, new ConfigDescription("Gravedad extra al ir a tope de velocidad. Cuanto más bajo, más tiempo en el aire. A velocidad baja se usa AirGravityMultiplier y se interpola entre ambos.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MaxAirSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "MaxAirSeconds", 6f, new ConfigDescription("Tope de seguridad: segundos máximos conservando impulso en el aire.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>()));
			ChainMomentum = ((BaseUnityPlugin)this).Config.Bind<bool>("Momentum", "ChainMomentum", true, "Encadenar deslizamientos conserva la velocidad que llevabas en vez de empezar de cero. Es lo que permite ir ganando ritmo en vez de reiniciarlo a cada salto.");
			ChainRetention = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "ChainRetention", 1f, new ConfigDescription("Cuánta velocidad conservas al encadenar. 1 = toda, 1.1 = ganas un 10% por enlace, 0.9 = pierdes un 10%. Por encima de 1 el ritmo sube solo hasta MaxSpeed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 1.3f), Array.Empty<object>()));
			MomentumGrace = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "MomentumGrace", 1.2f, new ConfigDescription("Segundos que el impulso sobrevive tras tocar suelo. Es la ventana que tienes para volver a saltar sin perder velocidad: más alto, más fácil encadenar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>()));
			MaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Momentum", "MaxSpeed", 22f, new ConfigDescription("Techo absoluto de velocidad. Sin esto, encadenar podría acelerar sin fin.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
			SprintToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "SprintToggle", true, "Correr con interruptor: pulsas una vez y sigues corriendo, en vez de mantener la tecla.");
			SprintKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Sprint", "SprintKey", (Key)51, "Tecla de correr. Cámbiala si reasignaste los controles.");
			StopSprintWhenIdle = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "StopSprintWhenIdle", true, "Deja de correr solo al soltar el movimiento. Si lo apagas, sigues corriendo hasta que vuelvas a pulsar la tecla.");
			Harmony val = new Harmony("com.hatsuneexo.htfslide");
			val.PatchAll(Assembly.GetExecutingAssembly());
			string[] array = (from m in val.GetPatchedMethods()
				select m.Name).Distinct().ToArray();
			Log.LogInfo((object)((array.Length != 0) ? ("Enganchado a " + string.Join(", ", array) + ".") : "AVISO: no encuentro PlayerMovement. El mod no hará nada."));
		}

		internal static bool ConsumeSlideRequest()
		{
			if (Time.time - _slideRequestedAt > 0.25f)
			{
				return false;
			}
			_slideRequestedAt = -99f;
			return true;
		}

		internal static void OnCrouchPressed()
		{
			if (!_loggedCrouchHook)
			{
				_loggedCrouchHook = true;
				Log.LogInfo((object)"Entrada de agacharse recibida del juego (los controles reasignados se respetan).");
			}
			CrouchHeld = true;
			_slideRequestedAt = Time.time;
		}

		internal static void OnCrouchReleased()
		{
			CrouchHeld = false;
		}

		internal static void OnSprintPressed()
		{
			if (!_loggedSprintHook)
			{
				_loggedSprintHook = true;
				Log.LogInfo((object)"Entrada de correr recibida del juego.");
			}
			if (SprintToggle.Value)
			{
				SprintLatched = !SprintLatched;
			}
		}

		private void Update()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (InputHooks.Active)
			{
				return;
			}
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (SprintToggle.Value)
			{
				KeyControl val = current[SprintKey.Value];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					SprintLatched = !SprintLatched;
				}
			}
			KeyControl val2 = current[SlideKey.Value];
			if (val2 != null)
			{
				if (((ButtonControl)val2).wasPressedThisFrame)
				{
					_slideRequestedAt = Time.time;
				}
				CrouchHeld = ((ButtonControl)val2).isPressed;
			}
		}

		internal static bool KeyHeld(Key key)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return false;
			}
			KeyControl val = current[key];
			if (val != null)
			{
				return ((ButtonControl)val).isPressed;
			}
			return false;
		}

		internal static bool KeyPressedThisFrame(Key key)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return false;
			}
			KeyControl val = current[key];
			if (val != null)
			{
				return ((ButtonControl)val).wasPressedThisFrame;
			}
			return false;
		}
	}
	internal static class Movement
	{
		internal static PropertyInfo Velocity;

		internal static PropertyInfo Grounded;

		internal static PropertyInfo Sprinting;

		internal static FieldInfo CrouchInput;

		internal static FieldInfo SprintInput;

		internal static FieldInfo MoveInputField;

		internal static FieldInfo Rig;

		internal static FieldInfo CurMoveSpeed;

		internal static FieldInfo TargetMoveSpeed;

		internal static FieldInfo ExtraGravity;

		internal static Type Type;

		internal static bool Resolve()
		{
			if (Type != null)
			{
				if (Velocity != null)
				{
					return Grounded != null;
				}
				return false;
			}
			Type = AccessTools.TypeByName("PlayerMovement");
			if (Type == null)
			{
				return false;
			}
			Velocity = AccessTools.Property(Type, "Velocity");
			Grounded = AccessTools.Property(Type, "Grounded");
			Sprinting = AccessTools.Property(Type, "Sprinting");
			CrouchInput = AccessTools.Field(Type, "_crouchInput");
			SprintInput = AccessTools.Field(Type, "_sprintInput");
			MoveInputField = AccessTools.Field(Type, "_moveInput");
			Rig = AccessTools.Field(Type, "_rig");
			CurMoveSpeed = AccessTools.Field(Type, "_curMoveSpeed");
			TargetMoveSpeed = AccessTools.Field(Type, "_targetMoveSpeed");
			ExtraGravity = AccessTools.Field(Type, "_extraGravityForce");
			if (Velocity != null && Grounded != null)
			{
				return Velocity.CanWrite;
			}
			return false;
		}

		internal static bool IsLocal(object instance)
		{
			NetworkBehaviour val = (NetworkBehaviour)((instance is NetworkBehaviour) ? instance : null);
			if (val != null)
			{
				return val.IsOwner;
			}
			return true;
		}

		private static Rigidbody GetRig(object m)
		{
			object? obj = Rig?.GetValue(m);
			return (Rigidbody)((obj is Rigidbody) ? obj : null);
		}

		internal static Vector3 GetVelocity(object m)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody rig = GetRig(m);
			if ((Object)(object)rig != (Object)null)
			{
				return rig.linearVelocity;
			}
			return (Vector3)Velocity.GetValue(m);
		}

		internal static void SetVelocity(object m, Vector3 v)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			Rigidbody rig = GetRig(m);
			if ((Object)(object)rig != (Object)null)
			{
				rig.linearVelocity = v;
				if (Velocity != null && Velocity.CanWrite)
				{
					Velocity.SetValue(m, v);
				}
			}
			else
			{
				Velocity.SetValue(m, v);
			}
		}

		internal static bool IsGrounded(object m)
		{
			return (bool)Grounded.GetValue(m);
		}

		internal static void SetMoveSpeed(object m, float speed)
		{
			CurMoveSpeed?.SetValue(m, speed);
		}
	}
	[HarmonyPatch]
	internal static class SprintTogglePatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			if (!Movement.Resolve() || TargetMethod() == null)
			{
				return false;
			}
			if (Movement.SprintInput == null)
			{
				Plugin.Log.LogWarning((object)"No encuentro _sprintInput: el interruptor de correr queda desactivado.");
				return false;
			}
			return true;
		}

		private static void Prefix(object __instance)
		{
			//IL_004e: 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)
			if (!Plugin.SprintToggle.Value || __instance == null || !Movement.IsLocal(__instance) || SlidePatch.IsSliding || !Plugin.SprintLatched)
			{
				return;
			}
			try
			{
				if (Plugin.StopSprintWhenIdle.Value && Movement.MoveInputField != null)
				{
					Vector2 val = (Vector2)Movement.MoveInputField.GetValue(__instance);
					if (((Vector2)(ref val)).sqrMagnitude < 0.01f)
					{
						Plugin.SprintLatched = false;
						return;
					}
				}
				Movement.SprintInput.SetValue(__instance, true);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Interruptor de correr desactivado: " + ex.Message));
				Plugin.SprintToggle.Value = false;
			}
		}
	}
	[HarmonyPatch]
	internal static class SlidePatch
	{
		private static bool _sliding;

		private static float _elapsed;

		private static float _lastEnd = -99f;

		private static Vector3 _direction;

		private static float _currentSpeed;

		private static bool _airborne;

		private static float _airSpeed;

		private static Vector3 _airDirection;

		private static float _airStarted;

		private static float _originalGravity;

		private static bool _gravityChanged;

		private const float MaxAirMomentum = 4f;

		private static float _momentumSpeed;

		private static float _momentumUntil;

		internal static bool IsSliding => _sliding;

		internal static Vector3 Direction => _direction;

		internal static float CurrentSpeed => _currentSpeed;

		internal static bool CanResumeMomentum
		{
			get
			{
				if (_momentumSpeed > Plugin.SpeedFloor.Value)
				{
					return Time.time < _momentumUntil;
				}
				return false;
			}
		}

		internal static float SpeedFactor(float speed)
		{
			float value = Plugin.SpeedFloor.Value;
			float num = Mathf.Max(value + 0.01f, Plugin.SpeedCeiling.Value);
			return Mathf.Clamp01((speed - value) / (num - value));
		}

		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			if (!Movement.Resolve())
			{
				Plugin.Log.LogWarning((object)"PlayerMovement cambió: Velocity o Grounded no están donde esperaba.");
				return false;
			}
			return TargetMethod() != null;
		}

		internal static void ResumeMomentum(object movement)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_002d: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = Movement.GetVelocity(movement);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(velocity.x, 0f, velocity.z);
			Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : _direction);
			_momentumSpeed = Mathf.Clamp(_momentumSpeed * Plugin.ChainRetention.Value, 0f, Plugin.MaxSpeed.Value);
			Movement.SetVelocity(movement, val2 * _momentumSpeed + Vector3.up * velocity.y);
			Movement.SetMoveSpeed(movement, _momentumSpeed);
			BeginAirMomentum(movement, _momentumSpeed, val2);
		}

		internal static float LaunchMultiplier(float speed)
		{
			return Mathf.Lerp(1f, Plugin.LaunchScaleAtTopSpeed.Value, SpeedFactor(speed));
		}

		internal static void EndSlide(object movement)
		{
			_sliding = false;
			_lastEnd = Time.time;
			if (movement != null)
			{
				Movement.SetMoveSpeed(movement, _currentSpeed);
				Movement.CrouchInput?.SetValue(movement, Plugin.CrouchHeld);
			}
		}

		private static void Postfix(object __instance)
		{
			if (__instance == null || !Movement.IsLocal(__instance))
			{
				return;
			}
			try
			{
				Tick(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Deslizamiento desactivado: " + ex.Message));
				_sliding = false;
			}
		}

		internal static void BeginAirMomentum(object movement, float speed, Vector3 direction)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			if (Plugin.KeepSpeedInAir.Value)
			{
				_airborne = true;
				_airSpeed = Mathf.Min(speed, Plugin.MaxSpeed.Value);
				_momentumSpeed = _airSpeed;
				_momentumUntil = Time.time + Plugin.MomentumGrace.Value;
				_airDirection = ((((Vector3)(ref direction)).sqrMagnitude > 0.01f) ? ((Vector3)(ref direction)).normalized : Vector3.forward);
				_airStarted = Time.time;
				float num = Mathf.Lerp(Plugin.AirGravityMultiplier.Value, Plugin.MinAirGravity.Value, SpeedFactor(speed));
				if (!(Movement.ExtraGravity == null) && !_gravityChanged && !(num >= 0.999f))
				{
					_originalGravity = (float)Movement.ExtraGravity.GetValue(movement);
					Movement.ExtraGravity.SetValue(movement, _originalGravity * num);
					_gravityChanged = true;
				}
			}
		}

		private static void EndAirMomentum(object movement)
		{
			_airborne = false;
			if (movement != null)
			{
				Movement.SetMoveSpeed(movement, _airSpeed);
			}
			_momentumUntil = Time.time + Plugin.MomentumGrace.Value;
			if (_gravityChanged && !(Movement.ExtraGravity == null))
			{
				Movement.ExtraGravity.SetValue(movement, _originalGravity);
				_gravityChanged = false;
			}
		}

		private static void Tick(object movement)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0069: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_008b: 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)
			//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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: 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_0278: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Movement.IsGrounded(movement);
			Vector3 velocity = Movement.GetVelocity(movement);
			Vector3 horizontal = default(Vector3);
			((Vector3)(ref horizontal))..ctor(velocity.x, 0f, velocity.z);
			if (_airborne)
			{
				if (flag || Time.time - _airStarted > Plugin.MaxAirSeconds.Value)
				{
					EndAirMomentum(movement);
				}
				else
				{
					Vector3 val = ((((Vector3)(ref horizontal)).sqrMagnitude > 0.01f) ? ((Vector3)(ref horizontal)).normalized : _airDirection);
					if (((Vector3)(ref horizontal)).magnitude < _airSpeed)
					{
						Movement.SetVelocity(movement, val * _airSpeed + Vector3.up * velocity.y);
					}
					Movement.SetMoveSpeed(movement, _airSpeed);
				}
			}
			if (!_sliding)
			{
				if (ShouldStart(movement, flag, horizontal))
				{
					_sliding = true;
					_elapsed = 0f;
					_direction = ((Vector3)(ref horizontal)).normalized;
					float magnitude = ((Vector3)(ref horizontal)).magnitude;
					float num = (Plugin.ChainMomentum.Value ? (magnitude * Plugin.ChainRetention.Value) : 0f);
					_currentSpeed = Mathf.Clamp(Mathf.Max(Plugin.StartSpeed.Value, num), Plugin.StartSpeed.Value, Plugin.MaxSpeed.Value);
				}
				return;
			}
			if (!flag)
			{
				Launch(movement, velocity);
				return;
			}
			_elapsed += Time.fixedDeltaTime;
			if (!Plugin.CrouchHeld || _elapsed >= Plugin.Duration.Value)
			{
				EndSlide(movement);
				return;
			}
			float value = Plugin.SteerControl.Value;
			if (value > 0f && ((Vector3)(ref horizontal)).sqrMagnitude > 0.01f)
			{
				Vector3 val2 = Vector3.Slerp(_direction, ((Vector3)(ref horizontal)).normalized, value);
				_direction = ((Vector3)(ref val2)).normalized;
			}
			float num2 = Mathf.Clamp01(_elapsed / Plugin.Duration.Value);
			float num3 = Mathf.Clamp01(Plugin.FullSpeedTime.Value / Mathf.Max(0.01f, Plugin.Duration.Value));
			num3 = Mathf.Min(num3, 0.9f);
			float num4 = ((num2 <= num3) ? 0f : Mathf.InverseLerp(num3, 1f, num2));
			float num5 = 1f - (1f - num4) * (1f - num4);
			_currentSpeed = Mathf.Lerp(Plugin.StartSpeed.Value, Plugin.EndSpeed.Value, num5);
			Movement.SetVelocity(movement, _direction * _currentSpeed + Vector3.up * velocity.y);
			Movement.SetMoveSpeed(movement, _currentSpeed);
			Movement.CrouchInput?.SetValue(movement, true);
		}

		private static void Launch(object movement, Vector3 velocity)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			float num = Plugin.RampLaunchBoost.Value * LaunchMultiplier(_currentSpeed);
			Vector3 val = (Vector3)(Plugin.KeepSpeedInAir.Value ? (_direction * _currentSpeed) : new Vector3(velocity.x, 0f, velocity.z));
			float num2 = velocity.y;
			if (num > 0f && num2 > -1f)
			{
				num2 += num;
			}
			Movement.SetVelocity(movement, val + Vector3.up * num2);
			BeginAirMomentum(movement, _currentSpeed, _direction);
			EndSlide(movement);
		}

		private static bool ShouldStart(object movement, bool grounded, Vector3 horizontal)
		{
			if (!grounded)
			{
				return false;
			}
			if (Time.time - _lastEnd < Plugin.Cooldown.Value)
			{
				return false;
			}
			if (((Vector3)(ref horizontal)).sqrMagnitude < 0.5f)
			{
				return false;
			}
			if (Plugin.RequireSprint.Value && Movement.Sprinting != null && !(bool)Movement.Sprinting.GetValue(movement))
			{
				return false;
			}
			return Plugin.ConsumeSlideRequest();
		}
	}
	[HarmonyPatch]
	internal static class SlideJumpPatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "Jump", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			if (Movement.Resolve())
			{
				return TargetMethod() != null;
			}
			return false;
		}

		private static void Postfix(object __instance)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (__instance == null || !Movement.IsLocal(__instance))
			{
				return;
			}
			if (!SlidePatch.IsSliding)
			{
				if (!Plugin.KeepSpeedInAir.Value || !SlidePatch.CanResumeMomentum)
				{
					return;
				}
				try
				{
					SlidePatch.ResumeMomentum(__instance);
					return;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Impulso encadenado desactivado: " + ex.Message));
					return;
				}
			}
			try
			{
				Vector3 velocity = Movement.GetVelocity(__instance);
				Vector3 val = (Vector3)(Plugin.KeepSpeedInAir.Value ? (SlidePatch.Direction * SlidePatch.CurrentSpeed) : new Vector3(velocity.x, 0f, velocity.z));
				float num = Plugin.SlideJumpBoost.Value * SlidePatch.LaunchMultiplier(SlidePatch.CurrentSpeed);
				Movement.SetVelocity(__instance, val + Vector3.up * (velocity.y + num));
				SlidePatch.BeginAirMomentum(__instance, SlidePatch.CurrentSpeed, SlidePatch.Direction);
				SlidePatch.EndSlide(__instance);
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogError((object)("Salto con impulso desactivado: " + ex2.Message));
			}
		}
	}
	internal static class InputHooks
	{
		private static int _found;

		internal static bool Active => _found >= 2;

		internal static void Found()
		{
			_found++;
		}
	}
	[HarmonyPatch]
	internal static class CrouchPressedPatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "CrouchInput", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			if (TargetMethod() == null)
			{
				return false;
			}
			InputHooks.Found();
			return true;
		}

		private static void Postfix(object __instance)
		{
			if (__instance != null && Movement.IsLocal(__instance))
			{
				Plugin.OnCrouchPressed();
			}
		}
	}
	[HarmonyPatch]
	internal static class CrouchReleasedPatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "CrouchInputCanceled", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			if (TargetMethod() == null)
			{
				return false;
			}
			InputHooks.Found();
			return true;
		}

		private static void Postfix(object __instance)
		{
			if (__instance != null && Movement.IsLocal(__instance))
			{
				Plugin.OnCrouchReleased();
			}
		}
	}
	[HarmonyPatch]
	internal static class SprintPressedPatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("PlayerMovement");
			if (!(type == null))
			{
				return AccessTools.Method(type, "SprintInput", (Type[])null, (Type[])null);
			}
			return null;
		}

		private static bool Prepare()
		{
			return TargetMethod() != null;
		}

		private static void Postfix(object __instance)
		{
			if (__instance != null && Movement.IsLocal(__instance))
			{
				Plugin.OnSprintPressed();
			}
		}
	}
}