Decompiled source of Skate v0.1.1

Skate.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Slip")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Slip")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e6771caa-ecbe-4f16-8aa1-55920e8f44ca")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Skate;

[HarmonyPatch(typeof(Bodypart), "OnCollisionEnter", new Type[] { typeof(Collision) })]
public static class PlayerCollisionKnockback
{
	private sealed class CrashProfile
	{
		public string Tier;

		public float FallTime;

		public float HorizontalForce;

		public float UpwardForce;

		public float Radius;

		public float Pitch;

		public float Volume;
	}

	[HarmonyPatch(typeof(CharacterMovement), "FixedUpdate")]
	private static class VelocityTrackingPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance)
		{
			//IL_0072: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component.data == (Object)null) && !((Object)(object)((MonoBehaviourPun)component).photonView == (Object)null))
			{
				if (!TryGetActualAverageVelocity(component, out var averageVelocity))
				{
					averageVelocity = component.data.avarageVelocity;
				}
				LastVelocities[((MonoBehaviourPun)component).photonView.ViewID] = averageVelocity;
			}
		}
	}

	[HarmonyPatch(typeof(Character), "RPCA_AddForceAtPosition", new Type[]
	{
		typeof(Vector3),
		typeof(Vector3),
		typeof(float)
	})]
	private static class CrashSoundPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Vector3 force, Vector3 point, float radius)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_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 (TryGetCrashSoundProfile(radius, out var pitch, out var volume) && (!(Time.unscaledTime - lastImpactSoundTime < 0.1f) || !(Vector3.Distance(point, lastImpactSoundPosition) < 3f)))
			{
				lastImpactSoundTime = Time.unscaledTime;
				lastImpactSoundPosition = point;
				PlayImpactSound(point, pitch, volume);
			}
		}
	}

	private const float MinimumImpactSpeed = 4f;

	private const float MediumImpactStart = 6f;

	private const float HeavyImpactStart = 9f;

	private const float SevereImpactStart = 12f;

	private const float SevereImpactFullSpeed = 18f;

	private const float OppositeDirectionDot = -0.35f;

	private const float HeadOnTransferScale = 0.5f;

	private const float CollisionCooldown = 0.55f;

	private const float LaunchVelocityWeight = 0.85f;

	private const float SeparationWeight = 0.15f;

	private const float LightHorizontalMin = 60f;

	private const float LightHorizontalMax = 90f;

	private const float LightUpMin = 25f;

	private const float LightUpMax = 45f;

	private const float LightFallMin = 0.7f;

	private const float LightFallMax = 1f;

	private const float MediumHorizontalMin = 100f;

	private const float MediumHorizontalMax = 150f;

	private const float MediumUpMin = 60f;

	private const float MediumUpMax = 90f;

	private const float MediumFallMin = 1.2f;

	private const float MediumFallMax = 1.6f;

	private const float HeavyHorizontalMin = 170f;

	private const float HeavyHorizontalMax = 240f;

	private const float HeavyUpMin = 100f;

	private const float HeavyUpMax = 150f;

	private const float HeavyFallMin = 1.6f;

	private const float HeavyFallMax = 2.1f;

	private const float SevereHorizontalMin = 260f;

	private const float SevereHorizontalMax = 380f;

	private const float SevereUpMin = 160f;

	private const float SevereUpMax = 240f;

	private const float SevereFallMin = 2.2f;

	private const float SevereFallMax = 3f;

	private const float LightRadius = 4.101f;

	private const float MediumRadius = 4.202f;

	private const float HeavyRadius = 4.303f;

	private const float SevereRadius = 4.404f;

	private const float RadiusMarkerTolerance = 0.01f;

	private const float SoundDuplicateTime = 0.1f;

	private const float SoundDuplicateDistance = 3f;

	private static readonly ManualLogSource LogSource = Logger.CreateLogSource("Skate.PlayerCrash");

	private static readonly Dictionary<long, float> PairCooldowns = new Dictionary<long, float>();

	private static readonly Dictionary<int, Vector3> LastVelocities = new Dictionary<int, Vector3>();

	private static SFX_Instance impactSfx;

	private static float nextSfxSearchTime;

	private static float lastImpactSoundTime = -100f;

	private static Vector3 lastImpactSoundPosition;

	[HarmonyPrefix]
	private static void Prefix(Bodypart __instance, Collision __0)
	{
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: 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)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || __0 == null)
		{
			return;
		}
		Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
		if ((Object)(object)componentInParent == (Object)null || !componentInParent.IsLocal || (Object)(object)componentInParent.data == (Object)null || componentInParent.data.dead || !componentInParent.IsPlayerControlled)
		{
			return;
		}
		Character val = ResolveOtherCharacter(__0, componentInParent);
		if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null || val.data.dead || !val.IsPlayerControlled || (Object)(object)((MonoBehaviourPun)componentInParent).photonView == (Object)null || (Object)(object)((MonoBehaviourPun)val).photonView == (Object)null)
		{
			return;
		}
		int viewID = ((MonoBehaviourPun)componentInParent).photonView.ViewID;
		int viewID2 = ((MonoBehaviourPun)val).photonView.ViewID;
		if (viewID <= 0 || viewID2 <= 0)
		{
			return;
		}
		long num = MakePairKey(viewID, viewID2);
		if (PairCooldowns.TryGetValue(num, out var value) && Time.time < value)
		{
			return;
		}
		Vector3 bestVelocity = GetBestVelocity(componentInParent);
		Vector3 bestVelocity2 = GetBestVelocity(val);
		Vector3 val2 = Flatten(bestVelocity);
		Vector3 val3 = Flatten(bestVelocity2);
		float magnitude = ((Vector3)(ref val2)).magnitude;
		float magnitude2 = ((Vector3)(ref val3)).magnitude;
		if (!(magnitude < 0.05f) || !(magnitude2 < 0.05f))
		{
			float directionDot = GetDirectionDot(val2, val3);
			Vector3 contactPoint = GetContactPoint(__0, componentInParent, val);
			if (magnitude > 0.05f && magnitude2 > 0.05f && directionDot <= -0.35f)
			{
				HandleHeadOnCollision(componentInParent, val, bestVelocity, bestVelocity2, magnitude, magnitude2, directionDot, contactPoint, num);
			}
			else
			{
				HandleDirectionalCollision(componentInParent, val, bestVelocity, bestVelocity2, val2, val3, magnitude, magnitude2, directionDot, contactPoint, num);
			}
		}
	}

	private static void HandleDirectionalCollision(Character self, Character other, Vector3 selfVelocity, Vector3 otherVelocity, Vector3 selfFlat, Vector3 otherFlat, float selfSpeed, float otherSpeed, float directionDot, Vector3 contactPoint, long pairKey)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//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_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: 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_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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_0065: 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_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: 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_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Flatten(other.Center - self.Center);
		if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
		{
			val = Flatten(contactPoint - self.Center);
		}
		if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
		{
			return;
		}
		((Vector3)(ref val)).Normalize();
		float num = Vector3.Dot(selfFlat - otherFlat, val);
		Character val2;
		Character val3;
		Vector3 val4;
		float num2;
		if (num > 0f)
		{
			val2 = self;
			val3 = other;
			val4 = selfVelocity;
			num2 = num;
		}
		else
		{
			val2 = other;
			val3 = self;
			val4 = otherVelocity;
			num2 = 0f - num;
		}
		if (!((Object)(object)val2 != (Object)(object)self))
		{
			if (num2 < 4f)
			{
				LogSource.LogInfo((object)("[PlayerCrash][NO-CRASH] mode=DIRECTIONAL selfSpeed=" + selfSpeed.ToString("F2") + " otherSpeed=" + otherSpeed.ToString("F2") + " closing=" + num2.ToString("F2") + " dot=" + directionDot.ToString("F2")));
				return;
			}
			PairCooldowns[pairKey] = Time.time + 0.55f;
			CrashProfile crashProfile = GetCrashProfile(num2);
			Vector3 launchDirection = GetLaunchDirection(val2, val3, val4);
			Vector3 force = launchDirection * crashProfile.HorizontalForce + Vector3.up * crashProfile.UpwardForce;
			BroadcastCrash(val3, force, contactPoint, crashProfile);
			LogSource.LogInfo((object)("[PlayerCrash][CRASH] mode=DIRECTIONAL tier=" + crashProfile.Tier + " attacker=" + ((MonoBehaviourPun)val2).photonView.ViewID + " victim=" + ((MonoBehaviourPun)val3).photonView.ViewID + " attackerSpeed=" + HorizontalSpeed(val4).ToString("F2") + " victimSpeed=" + HorizontalSpeed(((Object)(object)val3 == (Object)(object)self) ? selfVelocity : otherVelocity).ToString("F2") + " impact=" + num2.ToString("F2") + " horizontalForce=" + crashProfile.HorizontalForce.ToString("F1") + " upForce=" + crashProfile.UpwardForce.ToString("F1") + " fall=" + crashProfile.FallTime.ToString("F2")));
		}
	}

	private static void HandleHeadOnCollision(Character self, Character other, Vector3 selfVelocity, Vector3 otherVelocity, float selfSpeed, float otherSpeed, float directionDot, Vector3 contactPoint, long pairKey)
	{
		//IL_0078: 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)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: 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_00a4: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: 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)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		if (!IsHeadOnAuthority(self, other))
		{
			return;
		}
		float num = otherSpeed * 0.5f;
		float num2 = selfSpeed * 0.5f;
		if (!(num < 4f) || !(num2 < 4f))
		{
			PairCooldowns[pairKey] = Time.time + 0.55f;
			if (num >= 4f)
			{
				CrashProfile crashProfile = GetCrashProfile(num);
				Vector3 launchDirection = GetLaunchDirection(other, self, otherVelocity);
				Vector3 force = launchDirection * crashProfile.HorizontalForce + Vector3.up * crashProfile.UpwardForce;
				BroadcastCrash(self, force, contactPoint, crashProfile);
			}
			if (num2 >= 4f)
			{
				CrashProfile crashProfile2 = GetCrashProfile(num2);
				Vector3 launchDirection2 = GetLaunchDirection(self, other, selfVelocity);
				Vector3 force2 = launchDirection2 * crashProfile2.HorizontalForce + Vector3.up * crashProfile2.UpwardForce;
				BroadcastCrash(other, force2, contactPoint, crashProfile2);
			}
			LogSource.LogInfo((object)("[PlayerCrash][HEAD-ON] authority=" + ((MonoBehaviourPun)self).photonView.ViewID + " selfSpeed=" + selfSpeed.ToString("F2") + " otherSpeed=" + otherSpeed.ToString("F2") + " selfImpact=" + num.ToString("F2") + " otherImpact=" + num2.ToString("F2") + " transfer=" + 0.5f.ToString("F2") + " dot=" + directionDot.ToString("F2")));
		}
	}

	private static bool IsHeadOnAuthority(Character self, Character other)
	{
		if ((Object)(object)self == (Object)null || (Object)(object)other == (Object)null || !self.IsLocal)
		{
			return false;
		}
		if ((Object)(object)((MonoBehaviourPun)self).photonView == (Object)null || (Object)(object)((MonoBehaviourPun)other).photonView == (Object)null)
		{
			return false;
		}
		if (((MonoBehaviourPun)self).photonView.Owner != null && ((MonoBehaviourPun)other).photonView.Owner != null)
		{
			return ((MonoBehaviourPun)self).photonView.Owner.ActorNumber < ((MonoBehaviourPun)other).photonView.Owner.ActorNumber;
		}
		return ((MonoBehaviourPun)self).photonView.ViewID < ((MonoBehaviourPun)other).photonView.ViewID;
	}

	private static void BroadcastCrash(Character victim, Vector3 force, Vector3 point, CrashProfile profile)
	{
		//IL_0060: 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)
		if (!((Object)(object)victim == (Object)null) && !((Object)(object)((MonoBehaviourPun)victim).photonView == (Object)null) && profile != null)
		{
			((MonoBehaviourPun)victim).photonView.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { profile.FallTime });
			((MonoBehaviourPun)victim).photonView.RPC("RPCA_AddForceAtPosition", (RpcTarget)0, new object[3] { force, point, profile.Radius });
		}
	}

	private static CrashProfile GetCrashProfile(float impactSpeed)
	{
		CrashProfile crashProfile = new CrashProfile();
		if (impactSpeed < 6f)
		{
			float num = Mathf.InverseLerp(4f, 6f, impactSpeed);
			crashProfile.Tier = "LIGHT";
			crashProfile.HorizontalForce = Mathf.Lerp(60f, 90f, num);
			crashProfile.UpwardForce = Mathf.Lerp(25f, 45f, num);
			crashProfile.FallTime = Mathf.Lerp(0.7f, 1f, num);
			crashProfile.Radius = 4.101f;
			crashProfile.Pitch = Mathf.Lerp(1f, 0.92f, num);
			crashProfile.Volume = Mathf.Lerp(0.7f, 0.82f, num);
			return crashProfile;
		}
		if (impactSpeed < 9f)
		{
			float num2 = Mathf.InverseLerp(6f, 9f, impactSpeed);
			crashProfile.Tier = "MEDIUM";
			crashProfile.HorizontalForce = Mathf.Lerp(100f, 150f, num2);
			crashProfile.UpwardForce = Mathf.Lerp(60f, 90f, num2);
			crashProfile.FallTime = Mathf.Lerp(1.2f, 1.6f, num2);
			crashProfile.Radius = 4.202f;
			crashProfile.Pitch = Mathf.Lerp(0.9f, 0.82f, num2);
			crashProfile.Volume = Mathf.Lerp(0.82f, 0.92f, num2);
			return crashProfile;
		}
		if (impactSpeed < 12f)
		{
			float num3 = Mathf.InverseLerp(9f, 12f, impactSpeed);
			crashProfile.Tier = "HEAVY";
			crashProfile.HorizontalForce = Mathf.Lerp(170f, 240f, num3);
			crashProfile.UpwardForce = Mathf.Lerp(100f, 150f, num3);
			crashProfile.FallTime = Mathf.Lerp(1.6f, 2.1f, num3);
			crashProfile.Radius = 4.303f;
			crashProfile.Pitch = Mathf.Lerp(0.8f, 0.7f, num3);
			crashProfile.Volume = Mathf.Lerp(0.92f, 1f, num3);
			return crashProfile;
		}
		float num4 = Mathf.InverseLerp(12f, 18f, impactSpeed);
		crashProfile.Tier = "SEVERE";
		crashProfile.HorizontalForce = Mathf.Lerp(260f, 380f, num4);
		crashProfile.UpwardForce = Mathf.Lerp(160f, 240f, num4);
		crashProfile.FallTime = Mathf.Lerp(2.2f, 3f, num4);
		crashProfile.Radius = 4.404f;
		crashProfile.Pitch = Mathf.Lerp(0.68f, 0.58f, num4);
		crashProfile.Volume = 1f;
		return crashProfile;
	}

	private static Character ResolveOtherCharacter(Collision collision, Character self)
	{
		Character val = null;
		if ((Object)(object)collision.rigidbody != (Object)null)
		{
			val = ((Component)collision.rigidbody).GetComponentInParent<Character>();
		}
		if ((Object)(object)val == (Object)null && (Object)(object)collision.collider != (Object)null)
		{
			val = ((Component)collision.collider).GetComponentInParent<Character>();
		}
		if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)self)
		{
			return null;
		}
		return val;
	}

	private static Vector3 GetBestVelocity(Character character)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null)
		{
			return Vector3.zero;
		}
		if ((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && LastVelocities.TryGetValue(((MonoBehaviourPun)character).photonView.ViewID, out var value))
		{
			return value;
		}
		if (TryGetActualAverageVelocity(character, out var averageVelocity))
		{
			return averageVelocity;
		}
		if ((Object)(object)character.data != (Object)null)
		{
			return character.data.avarageVelocity;
		}
		return Vector3.zero;
	}

	private static bool TryGetActualAverageVelocity(Character character, out Vector3 averageVelocity)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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)
		averageVelocity = Vector3.zero;
		if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return false;
		}
		Vector3 val = Vector3.zero;
		int num = 0;
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val2 = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Rig == (Object)null) && !val2.Rig.isKinematic)
			{
				val += val2.Rig.linearVelocity;
				num++;
			}
		}
		if (num <= 0)
		{
			return false;
		}
		averageVelocity = val / (float)num;
		return true;
	}

	private static Vector3 GetLaunchDirection(Character attacker, Character victim, Vector3 attackerVelocity)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_008a: 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_00a2: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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)
		Vector3 val = Flatten(attackerVelocity);
		if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
		{
			((Vector3)(ref val)).Normalize();
		}
		Vector3 val2 = Flatten(victim.Center - attacker.Center);
		if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
		{
			((Vector3)(ref val2)).Normalize();
		}
		Vector3 val3 = val * 0.85f + val2 * 0.15f;
		if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
		{
			val3 = val2;
		}
		if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
		{
			val3 = val;
		}
		if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
		{
			val3 = Vector3.forward;
		}
		val3.y = 0f;
		return ((Vector3)(ref val3)).normalized;
	}

	private static float GetDirectionDot(Vector3 a, Vector3 b)
	{
		//IL_002f: 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)
		if (((Vector3)(ref a)).sqrMagnitude < 0.0001f || ((Vector3)(ref b)).sqrMagnitude < 0.0001f)
		{
			return 1f;
		}
		return Vector3.Dot(((Vector3)(ref a)).normalized, ((Vector3)(ref b)).normalized);
	}

	private static Vector3 GetContactPoint(Collision collision, Character self, Character other)
	{
		//IL_002a: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		if (collision != null && collision.contactCount > 0)
		{
			return ((ContactPoint)(ref collision.contacts[0])).point;
		}
		return Vector3.Lerp(self.Center, other.Center, 0.5f);
	}

	private static Vector3 Flatten(Vector3 value)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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)
		value.y = 0f;
		return value;
	}

	private static float HorizontalSpeed(Vector3 value)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Flatten(value);
		return ((Vector3)(ref val)).magnitude;
	}

	private static long MakePairKey(int a, int b)
	{
		uint num = (uint)Mathf.Min(a, b);
		uint num2 = (uint)Mathf.Max(a, b);
		return (long)(((ulong)num << 32) | num2);
	}

	private static bool TryGetCrashSoundProfile(float radius, out float pitch, out float volume)
	{
		pitch = 1f;
		volume = 1f;
		if (Mathf.Abs(radius - 4.101f) <= 0.01f)
		{
			pitch = 0.96f;
			volume = 0.75f;
			return true;
		}
		if (Mathf.Abs(radius - 4.202f) <= 0.01f)
		{
			pitch = 0.86f;
			volume = 0.85f;
			return true;
		}
		if (Mathf.Abs(radius - 4.303f) <= 0.01f)
		{
			pitch = 0.75f;
			volume = 0.95f;
			return true;
		}
		if (Mathf.Abs(radius - 4.404f) <= 0.01f)
		{
			pitch = 0.62f;
			volume = 1f;
			return true;
		}
		return false;
	}

	private static void PlayImpactSound(Vector3 position, float pitch, float volume)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		ResolveImpactSfx();
		if (!((Object)(object)impactSfx == (Object)null) && !((Object)(object)SFX_Player.instance == (Object)null))
		{
			SFX_Settings settings = impactSfx.settings;
			SFX_Settings val = new SFX_Settings();
			val.volume = ((settings != null) ? Mathf.Clamp01(Mathf.Max(settings.volume, volume)) : volume);
			val.volume_Variation = 0.04f;
			val.pitch = pitch;
			val.pitch_Variation = 0.05f;
			val.spatialBlend = 1f;
			val.dopplerLevel = settings?.dopplerLevel ?? 0f;
			val.range = ((settings != null) ? Mathf.Max(settings.range, 60f) : 60f);
			val.cooldown = 0f;
			SFX_Player.instance.PlaySFX(impactSfx, position, (Transform)null, val, 1f, false);
		}
	}

	private static void ResolveImpactSfx()
	{
		if ((Object)(object)impactSfx != (Object)null || Time.unscaledTime < nextSfxSearchTime)
		{
			return;
		}
		nextSfxSearchTime = Time.unscaledTime + 2f;
		SFX_Instance[] array = Resources.FindObjectsOfTypeAll<SFX_Instance>();
		string[] array2 = new string[6] { "crash", "car", "impact", "collision", "bonk", "hit" };
		foreach (string value in array2)
		{
			foreach (SFX_Instance val in array)
			{
				if (!((Object)(object)val == (Object)null) && val.clips != null && val.clips.Length != 0)
				{
					string text = ((((Object)val).name == null) ? string.Empty : ((Object)val).name.ToLowerInvariant());
					if (text.Contains(value))
					{
						impactSfx = val;
						LogSource.LogInfo((object)("[PlayerCrash][SFX] selected=" + ((Object)val).name));
						return;
					}
				}
			}
		}
		Bonkable[] array3 = Resources.FindObjectsOfTypeAll<Bonkable>();
		foreach (Bonkable val2 in array3)
		{
			if ((Object)(object)val2 == (Object)null || val2.bonk == null)
			{
				continue;
			}
			for (int l = 0; l < val2.bonk.Length; l++)
			{
				SFX_Instance val3 = val2.bonk[l];
				if (!((Object)(object)val3 == (Object)null) && val3.clips != null && val3.clips.Length != 0)
				{
					impactSfx = val3;
					LogSource.LogInfo((object)("[PlayerCrash][SFX] selectedBonk=" + ((Object)val3).name));
					return;
				}
			}
		}
	}
}
[BepInPlugin("Sapphire009.NoEmote", "NoEmote", "0.1.0")]
public class NoEmote : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterInput), "Sample", new Type[] { typeof(bool) })]
	private static class CharacterInputSamplePatch
	{
		[HarmonyPrefix]
		private static void Prefix(CharacterInput __instance, ref bool playerMovementActive)
		{
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.input != (Object)(object)__instance) && !((Object)(object)localCharacter.data == (Object)null) && localCharacter.data.usingEmoteWheel)
			{
				playerMovementActive = true;
			}
		}
	}

	private Harmony harmony;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("Sapphire009.NoEmote");
		harmony.PatchAll();
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
	}
}
[BepInPlugin("Sapphire009.Skate", "Skate", "0.1.0")]
public class WASD : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterInput), "Sample", new Type[] { typeof(bool) })]
	private static class CharacterInputSamplePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterInput __instance, bool playerMovementActive)
		{
			DisableAirSprint(__instance);
			ApplySkateInput(__instance, playerMovementActive);
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")]
	private static class CharacterMovementForcePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance, ref float __result)
		{
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.data == (Object)null) && localCharacter.refs != null && !((Object)(object)localCharacter.refs.movement != (Object)(object)__instance) && localCharacter.data.isSprinting && !localCharacter.data.isClimbing && !localCharacter.data.isRopeClimbing && (!localCharacter.data.isGrounded || sprintCoastingActive))
			{
				float num = Mathf.Max(__instance.sprintMultiplier, 1f);
				__result /= num;
			}
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "JumpRpc", new Type[] { typeof(bool) })]
	private static class CharacterMovementJumpPatch
	{
		[HarmonyPrefix]
		private static void Prefix(CharacterMovement __instance, bool __0)
		{
			ResetReverseState();
			sprintCoastingActive = false;
			ArmJumpCarry(__instance, __0);
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "FixedUpdate")]
	private static class CharacterMovementFixedUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance)
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.movement == (Object)(object)__instance && reverseHolding)
			{
				MaintainReverseHold(localCharacter);
			}
			HandleJumpCarryFixed(__instance);
		}
	}

	private const float AccelerationTime = 0.65f;

	private const float DecelerationTime = 1.15f;

	private const float LowSpeedDecelerationTime = 0.25f;

	private const float LowSpeedThreshold = 0.2f;

	private const float DirectionChangeTime = 0.85f;

	private const float SpeedMultiplier = 1.95f;

	private const float ReverseTriggerDot = -0.35f;

	private const float ReverseZeroSpeed = 0.35f;

	private const float ReverseHoldDuration = 0.12f;

	private const float ReverseMemoryThreshold = 0.15f;

	private const float MinimumCarrySpeed = 0.1f;

	private const float JumpCarryTimeout = 10f;

	private const float CarrySpeedTolerance = 0.02f;

	private const float LandingCarryDuration = 0.2f;

	private static Vector3 skateWorldInput;

	private static Vector3 skateWorldVelocity;

	private static Character trackedCharacter;

	private static bool wasSprintMovementActive;

	private static bool sprintCoastingActive;

	private static bool reverseTransitionActive;

	private static bool reverseHolding;

	private static Vector3 reverseOriginalDirection;

	private static float reverseHoldUntil;

	private static Character jumpCarryCharacter;

	private static CharacterMovement jumpCarryMovement;

	private static Vector3 jumpCarryVelocity;

	private static float jumpCarrySpeed;

	private static float jumpCarryStartedAt;

	private static bool jumpCarryActive;

	private static bool jumpCarryTakeoffSeen;

	private static bool jumpStartedWithSprint;

	private static bool jumpCarryLandingActive;

	private static float jumpCarryLandingStartedAt;

	private static Vector3 jumpCarryLandingVelocity;

	private static float jumpCarryLandingSpeed;

	private Harmony harmony;

	private CharacterMovement trackedMovement;

	private float originalMovementForce;

	private bool movementForceStored;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("Sapphire009.Slip");
		harmony.PatchAll();
	}

	private void Update()
	{
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.movement == (Object)null)
		{
			RestoreMovementForce();
			ResetJumpCarry();
			ResetReverseState();
			sprintCoastingActive = false;
			return;
		}
		CharacterMovement movement = localCharacter.refs.movement;
		if ((Object)(object)trackedMovement != (Object)(object)movement)
		{
			RestoreMovementForce();
			trackedMovement = movement;
			originalMovementForce = movement.movementForce;
			movementForceStored = true;
		}
		movement.movementForce = originalMovementForce * 1.95f;
		if (reverseHolding && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.isGrounded)
		{
			MaintainReverseHold(localCharacter);
		}
		if (jumpCarryLandingActive && (Object)(object)jumpCarryCharacter == (Object)(object)localCharacter && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.isGrounded)
		{
			MaintainLandingHorizontalSpeed(localCharacter);
		}
		if (jumpCarryActive && Time.time - jumpCarryStartedAt > 10f)
		{
			ResetJumpCarry();
		}
	}

	private void OnDestroy()
	{
		RestoreMovementForce();
		ResetSkateState();
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
	}

	private void RestoreMovementForce()
	{
		if (!movementForceStored || (Object)(object)trackedMovement == (Object)null)
		{
			trackedMovement = null;
			movementForceStored = false;
		}
		else
		{
			trackedMovement.movementForce = originalMovementForce;
			trackedMovement = null;
			movementForceStored = false;
		}
	}

	private static void ResetSkateState()
	{
		//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_000b: 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)
		skateWorldInput = Vector3.zero;
		skateWorldVelocity = Vector3.zero;
		trackedCharacter = null;
		wasSprintMovementActive = false;
		sprintCoastingActive = false;
		ResetReverseState();
		ResetJumpCarry();
	}

	private static void ResetMovementAcceleration()
	{
		//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_000b: 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)
		skateWorldInput = Vector3.zero;
		skateWorldVelocity = Vector3.zero;
		wasSprintMovementActive = false;
		sprintCoastingActive = false;
		ResetReverseState();
	}

	private static void ResetReverseState()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		reverseTransitionActive = false;
		reverseHolding = false;
		reverseOriginalDirection = Vector3.zero;
		reverseHoldUntil = 0f;
	}

	private static void ResetJumpCarry()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		jumpCarryCharacter = null;
		jumpCarryMovement = null;
		jumpCarryVelocity = Vector3.zero;
		jumpCarrySpeed = 0f;
		jumpCarryStartedAt = 0f;
		jumpCarryActive = false;
		jumpCarryTakeoffSeen = false;
		jumpStartedWithSprint = false;
		jumpCarryLandingActive = false;
		jumpCarryLandingStartedAt = 0f;
		jumpCarryLandingVelocity = Vector3.zero;
		jumpCarryLandingSpeed = 0f;
	}

	private static void DisableAirSprint(CharacterInput characterInput)
	{
		Character localCharacter = Character.localCharacter;
		if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.input != (Object)(object)characterInput) && !((Object)(object)localCharacter.data == (Object)null) && !localCharacter.data.isGrounded && !localCharacter.data.isClimbing && !localCharacter.data.isRopeClimbing)
		{
			characterInput.sprintIsPressed = false;
			characterInput.sprintWasPressed = false;
			characterInput.sprintToggleIsPressed = false;
			characterInput.sprintToggleWasPressed = false;
			wasSprintMovementActive = false;
			sprintCoastingActive = false;
		}
	}

	private static void DisableSprint(CharacterInput characterInput)
	{
		characterInput.sprintIsPressed = false;
		characterInput.sprintWasPressed = false;
		characterInput.sprintToggleIsPressed = false;
		characterInput.sprintToggleWasPressed = false;
		wasSprintMovementActive = false;
	}

	private static void SuppressMovementInput(CharacterInput characterInput)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		characterInput.movementInput = Vector2.zero;
		DisableSprint(characterInput);
		sprintCoastingActive = false;
	}

	private static void BeginReverseHold(Character character)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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)
		reverseTransitionActive = false;
		reverseHolding = true;
		reverseOriginalDirection = Vector3.zero;
		reverseHoldUntil = Time.time + 0.12f;
		skateWorldInput = Vector3.zero;
		skateWorldVelocity = Vector3.zero;
		wasSprintMovementActive = false;
		ZeroHorizontalVelocity(character);
	}

	private static void MaintainReverseHold(Character character)
	{
		if (reverseHolding)
		{
			if (Time.time >= reverseHoldUntil)
			{
				reverseHolding = false;
				reverseHoldUntil = 0f;
			}
			else
			{
				ZeroHorizontalVelocity(character);
			}
		}
	}

	private static bool HandleReverseZeroPause(Character character, CharacterInput characterInput, Vector3 targetWorldInput, bool hasMovementInput)
	{
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: 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_00e9: 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_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: 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_020f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || !character.data.isGrounded || character.data.isClimbing || character.data.isRopeClimbing)
		{
			ResetReverseState();
			return false;
		}
		if (reverseHolding)
		{
			if (!hasMovementInput)
			{
				ResetReverseState();
				return false;
			}
			if (Time.time < reverseHoldUntil)
			{
				ZeroHorizontalVelocity(character);
				SuppressMovementInput(characterInput);
				return true;
			}
			reverseHolding = false;
			reverseHoldUntil = 0f;
			skateWorldInput = Vector3.zero;
			skateWorldVelocity = Vector3.zero;
			wasSprintMovementActive = false;
			return false;
		}
		if (!hasMovementInput)
		{
			reverseTransitionActive = false;
			reverseOriginalDirection = Vector3.zero;
			return false;
		}
		Vector3 normalized = ((Vector3)(ref targetWorldInput)).normalized;
		if (reverseTransitionActive)
		{
			float num = Vector3.Dot(reverseOriginalDirection, normalized);
			if (num > -0.35f)
			{
				reverseTransitionActive = false;
				reverseOriginalDirection = Vector3.zero;
				return false;
			}
			if (!TryGetAverageHorizontalVelocity(character, out var horizontalVelocity))
			{
				return false;
			}
			float magnitude = ((Vector3)(ref horizontalVelocity)).magnitude;
			float num2 = Vector3.Dot(horizontalVelocity, reverseOriginalDirection);
			if (magnitude <= 0.35f || num2 <= 0f)
			{
				BeginReverseHold(character);
				SuppressMovementInput(characterInput);
				return true;
			}
			return false;
		}
		if (!TryGetAverageHorizontalVelocity(character, out var horizontalVelocity2))
		{
			return false;
		}
		float magnitude2 = ((Vector3)(ref horizontalVelocity2)).magnitude;
		if (magnitude2 > 0.35f)
		{
			Vector3 normalized2 = ((Vector3)(ref horizontalVelocity2)).normalized;
			float num3 = Vector3.Dot(normalized2, normalized);
			if (num3 <= -0.35f)
			{
				reverseTransitionActive = true;
				reverseOriginalDirection = normalized2;
				return false;
			}
		}
		else if (((Vector3)(ref skateWorldInput)).sqrMagnitude >= 0.0225f)
		{
			float num4 = Vector3.Dot(((Vector3)(ref skateWorldInput)).normalized, normalized);
			if (num4 <= -0.35f)
			{
				BeginReverseHold(character);
				SuppressMovementInput(characterInput);
				return true;
			}
		}
		return false;
	}

	private static void ApplySkateInput(CharacterInput characterInput, bool playerMovementActive)
	{
		//IL_0043: 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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: 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_0164: 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_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: 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_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_043d: Unknown result type (might be due to invalid IL or missing references)
		//IL_044a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0454: Unknown result type (might be due to invalid IL or missing references)
		//IL_0459: Unknown result type (might be due to invalid IL or missing references)
		//IL_0415: Unknown result type (might be due to invalid IL or missing references)
		//IL_041a: Unknown result type (might be due to invalid IL or missing references)
		//IL_041f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0424: Unknown result type (might be due to invalid IL or missing references)
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.input != (Object)(object)characterInput)
		{
			return;
		}
		if ((Object)(object)trackedCharacter != (Object)(object)localCharacter)
		{
			trackedCharacter = localCharacter;
			skateWorldInput = Vector3.zero;
			skateWorldVelocity = Vector3.zero;
			wasSprintMovementActive = false;
			sprintCoastingActive = false;
			ResetReverseState();
			ResetJumpCarry();
		}
		if (!playerMovementActive || localCharacter.data.dead || localCharacter.data.fullyPassedOut)
		{
			ResetMovementAcceleration();
			return;
		}
		if (localCharacter.data.isClimbing || localCharacter.data.isRopeClimbing)
		{
			ResetMovementAcceleration();
			ResetJumpCarry();
			return;
		}
		Vector2 val = Vector2.ClampMagnitude(characterInput.movementInput, 1f);
		bool flag = characterInput.sprintIsPressed || characterInput.sprintToggleIsPressed;
		Vector3 lookDirection = localCharacter.data.lookDirection;
		lookDirection.y = 0f;
		if (((Vector3)(ref lookDirection)).sqrMagnitude > 0.0001f)
		{
			((Vector3)(ref lookDirection)).Normalize();
		}
		Vector3 lookDirection_Right = localCharacter.data.lookDirection_Right;
		lookDirection_Right.y = 0f;
		if (((Vector3)(ref lookDirection_Right)).sqrMagnitude > 0.0001f)
		{
			((Vector3)(ref lookDirection_Right)).Normalize();
		}
		Vector3 val2 = lookDirection * val.y + lookDirection_Right * val.x;
		val2 = Vector3.ClampMagnitude(val2, 1f);
		bool flag2 = ((Vector3)(ref val2)).sqrMagnitude > 0.0001f;
		if (HandleReverseZeroPause(localCharacter, characterInput, val2, flag2))
		{
			return;
		}
		sprintCoastingActive = localCharacter.data.isGrounded && !flag2 && flag;
		if (sprintCoastingActive)
		{
			DisableSprint(characterInput);
		}
		bool flag3 = localCharacter.data.isGrounded && flag2 && flag;
		bool flag4 = localCharacter.data.isGrounded && jumpCarryActive && jumpCarryTakeoffSeen && jumpStartedWithSprint && flag2 && flag3;
		if (flag4)
		{
			wasSprintMovementActive = true;
		}
		float num = 1f;
		if (localCharacter.refs != null && (Object)(object)localCharacter.refs.movement != (Object)null)
		{
			num = Mathf.Max(localCharacter.refs.movement.sprintMultiplier, 1f);
		}
		if (flag2 && ((Vector3)(ref skateWorldInput)).sqrMagnitude < 0.0001f)
		{
			float num2 = 0.5128205f;
			if (flag3 && !flag4)
			{
				num2 /= num;
			}
			num2 = Mathf.Clamp01(num2);
			skateWorldInput = val2 * num2;
			skateWorldVelocity = Vector3.zero;
		}
		else if (flag2 && flag3 && !wasSprintMovementActive)
		{
			skateWorldInput /= num;
			skateWorldVelocity = Vector3.zero;
		}
		float num3;
		if (flag2)
		{
			num3 = ((!(((Vector3)(ref skateWorldInput)).sqrMagnitude > 0.0001f) || !(Vector3.Dot(((Vector3)(ref skateWorldInput)).normalized, ((Vector3)(ref val2)).normalized) < 0.5f)) ? 0.65f : 0.85f);
		}
		else
		{
			float magnitude = ((Vector3)(ref skateWorldInput)).magnitude;
			if (magnitude <= 0.2f)
			{
				float num4 = Mathf.InverseLerp(0f, 0.2f, magnitude);
				num3 = Mathf.Lerp(0.25f, 1.15f, num4);
			}
			else
			{
				num3 = 1.15f;
			}
		}
		skateWorldInput = Vector3.SmoothDamp(skateWorldInput, val2, ref skateWorldVelocity, num3, float.PositiveInfinity, Time.deltaTime);
		skateWorldInput.y = 0f;
		if (!flag2 && ((Vector3)(ref skateWorldInput)).sqrMagnitude < 0.0001f)
		{
			skateWorldInput = Vector3.zero;
			skateWorldVelocity = Vector3.zero;
		}
		float num5 = Vector3.Dot(skateWorldInput, lookDirection_Right);
		float num6 = Vector3.Dot(skateWorldInput, lookDirection);
		characterInput.movementInput = Vector2.ClampMagnitude(new Vector2(num5, num6), 1f);
		if (localCharacter.data.isGrounded)
		{
			wasSprintMovementActive = flag2 && flag3;
		}
		else
		{
			wasSprintMovementActive = false;
		}
	}

	private static bool TryGetAverageVelocity(Character character, out Vector3 averageVelocity)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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)
		averageVelocity = Vector3.zero;
		if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return false;
		}
		Vector3 val = Vector3.zero;
		int num = 0;
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val2 = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Rig == (Object)null) && !val2.Rig.isKinematic)
			{
				val += val2.Rig.linearVelocity;
				num++;
			}
		}
		if (num <= 0)
		{
			return false;
		}
		averageVelocity = val / (float)num;
		return true;
	}

	private static bool TryGetAverageHorizontalVelocity(Character character, out Vector3 horizontalVelocity)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		horizontalVelocity = Vector3.zero;
		if (!TryGetAverageVelocity(character, out var averageVelocity))
		{
			return false;
		}
		averageVelocity.y = 0f;
		horizontalVelocity = averageVelocity;
		return true;
	}

	private static void ZeroHorizontalVelocity(Character character)
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return;
		}
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Rig == (Object)null) && !val.Rig.isKinematic)
			{
				Vector3 linearVelocity = val.Rig.linearVelocity;
				linearVelocity.x = 0f;
				linearVelocity.z = 0f;
				val.Rig.linearVelocity = linearVelocity;
			}
		}
	}

	private static void SetAverageHorizontalVelocity(Character character, Vector3 targetVelocity)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		if (!TryGetAverageHorizontalVelocity(character, out var horizontalVelocity))
		{
			return;
		}
		targetVelocity.y = 0f;
		Vector3 val = targetVelocity - horizontalVelocity;
		val.y = 0f;
		if (((Vector3)(ref val)).sqrMagnitude < 1E-06f || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return;
		}
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val2 = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Rig == (Object)null) && !val2.Rig.isKinematic)
			{
				Vector3 linearVelocity = val2.Rig.linearVelocity;
				linearVelocity.x += val.x;
				linearVelocity.z += val.z;
				val2.Rig.linearVelocity = linearVelocity;
			}
		}
	}

	private static void MaintainJumpHorizontalSpeed(Character character)
	{
		//IL_0054: 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_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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		if (!jumpCarryActive || (Object)(object)character == (Object)null || (Object)(object)character != (Object)(object)jumpCarryCharacter || !TryGetAverageHorizontalVelocity(character, out var horizontalVelocity))
		{
			return;
		}
		float magnitude = ((Vector3)(ref horizontalVelocity)).magnitude;
		Vector3 val;
		if (magnitude > 0.1f)
		{
			val = horizontalVelocity / magnitude;
		}
		else
		{
			if (!(((Vector3)(ref jumpCarryVelocity)).sqrMagnitude > 0.0001f))
			{
				return;
			}
			val = ((Vector3)(ref jumpCarryVelocity)).normalized;
		}
		if (!(Mathf.Abs(magnitude - jumpCarrySpeed) <= 0.02f))
		{
			SetAverageHorizontalVelocity(character, val * jumpCarrySpeed);
		}
	}

	private static void CaptureLandingHorizontalVelocity(Character character)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (TryGetAverageHorizontalVelocity(character, out var horizontalVelocity) && !(((Vector3)(ref horizontalVelocity)).magnitude < 0.1f))
		{
			jumpCarryLandingVelocity = horizontalVelocity;
			jumpCarryLandingSpeed = ((Vector3)(ref horizontalVelocity)).magnitude;
		}
	}

	private static void MaintainLandingHorizontalSpeed(Character character)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: 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)
		if (!jumpCarryLandingActive || (Object)(object)character == (Object)null || (Object)(object)character != (Object)(object)jumpCarryCharacter || (Object)(object)character.data == (Object)null || !character.data.isGrounded || !TryGetAverageHorizontalVelocity(character, out var horizontalVelocity))
		{
			return;
		}
		float magnitude = ((Vector3)(ref horizontalVelocity)).magnitude;
		if (magnitude + 0.02f >= jumpCarryLandingSpeed)
		{
			return;
		}
		Vector3 normalized;
		if (magnitude > 0.1f)
		{
			normalized = ((Vector3)(ref horizontalVelocity)).normalized;
		}
		else
		{
			if (!(((Vector3)(ref jumpCarryLandingVelocity)).sqrMagnitude > 0.0001f))
			{
				return;
			}
			normalized = ((Vector3)(ref jumpCarryLandingVelocity)).normalized;
		}
		SetAverageHorizontalVelocity(character, normalized * jumpCarryLandingSpeed);
	}

	private static void ArmJumpCarry(CharacterMovement movement, bool isPalJump)
	{
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		if (isPalJump)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.movement != (Object)(object)movement || !localCharacter.data.isGrounded)
		{
			return;
		}
		if (!TryGetAverageHorizontalVelocity(localCharacter, out var horizontalVelocity))
		{
			ResetJumpCarry();
			return;
		}
		float magnitude = ((Vector3)(ref horizontalVelocity)).magnitude;
		if (magnitude < 0.1f)
		{
			ResetJumpCarry();
			return;
		}
		bool flag = localCharacter.data.isSprinting;
		if ((Object)(object)localCharacter.input != (Object)null)
		{
			flag = flag || localCharacter.input.sprintIsPressed || localCharacter.input.sprintToggleIsPressed;
		}
		jumpCarryCharacter = localCharacter;
		jumpCarryMovement = movement;
		jumpCarryVelocity = horizontalVelocity;
		jumpCarrySpeed = magnitude;
		jumpCarryLandingVelocity = horizontalVelocity;
		jumpCarryLandingSpeed = magnitude;
		jumpCarryStartedAt = Time.time;
		jumpCarryActive = true;
		jumpCarryTakeoffSeen = false;
		jumpStartedWithSprint = flag;
		jumpCarryLandingActive = false;
		jumpCarryLandingStartedAt = 0f;
	}

	private static void HandleJumpCarryFixed(CharacterMovement movement)
	{
		if (!jumpCarryActive || (Object)(object)jumpCarryCharacter == (Object)null || (Object)(object)jumpCarryMovement != (Object)(object)movement)
		{
			return;
		}
		Character val = jumpCarryCharacter;
		if ((Object)(object)val.data == (Object)null || val.data.dead || val.data.fullyPassedOut || val.data.isClimbing || val.data.isRopeClimbing)
		{
			ResetJumpCarry();
		}
		else if (Time.time - jumpCarryStartedAt > 10f)
		{
			ResetJumpCarry();
		}
		else if (!val.data.isGrounded)
		{
			jumpCarryTakeoffSeen = true;
			jumpCarryLandingActive = false;
			MaintainJumpHorizontalSpeed(val);
			CaptureLandingHorizontalVelocity(val);
		}
		else if (val.data.chargingJump && !jumpCarryTakeoffSeen)
		{
			MaintainJumpHorizontalSpeed(val);
		}
		else if (jumpCarryTakeoffSeen)
		{
			if (!jumpCarryLandingActive)
			{
				jumpCarryLandingActive = true;
				jumpCarryLandingStartedAt = Time.time;
			}
			MaintainLandingHorizontalSpeed(val);
			if (Time.time - jumpCarryLandingStartedAt >= 0.2f)
			{
				ResetJumpCarry();
			}
		}
	}
}
[HarmonyPatch(typeof(CharacterClimbing), "StartClimbRpc", new Type[]
{
	typeof(Vector3),
	typeof(Vector3)
})]
public static class FallSpeedSlip
{
	private sealed class ClimbState
	{
		public Character Character;

		public Vector3 Velocity;

		public bool Valid;

		public bool HadPreviousGrab;

		public bool HadDetach;

		public float TimeSinceDetach;

		public float DistanceSinceDetach;
	}

	[HarmonyPatch(typeof(CharacterClimbing), "StopClimbingRpc", new Type[] { typeof(float) })]
	private static class StopClimbingPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterClimbing __instance)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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)__instance == (Object)null)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.data == (Object)null || (Object)(object)component != (Object)(object)Character.localCharacter)
			{
				return;
			}
			EnsureCharacter(component);
			if (lastProcessedDetachFrame != Time.frameCount)
			{
				lastProcessedDetachFrame = Time.frameCount;
				if (hasGrabbedSinceGrounded)
				{
					detachActive = true;
					detachTime = Time.time;
					detachPosition = component.Center;
					LogSource.LogInfo((object)("[FallSpeedSlip][DETACH] frame=" + Time.frameCount + " position=" + V3(detachPosition)));
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "FixedUpdate")]
	private static class CharacterMovementFixedUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.movement != (Object)(object)__instance)
			{
				return;
			}
			EnsureCharacter(localCharacter);
			if (localCharacter.data.isGrounded && !localCharacter.data.isClimbing && !localCharacter.data.isRopeClimbing)
			{
				if (hasGrabbedSinceGrounded || detachActive)
				{
					LogSource.LogInfo((object)"[FallSpeedSlip][GROUND-RESET]");
				}
				hasGrabbedSinceGrounded = false;
				detachActive = false;
				detachTime = 0f;
				detachPosition = Vector3.zero;
			}
		}
	}

	private const float OriginalFallSlipMultiplier = 1.5f;

	private const float MinFallSlipSpeed = 4.5f;

	private const float FirstApproachHorizontalSlipSpeed = 5f;

	private const float RegrabHorizontalSlipSpeed = 6.5f;

	private const float MinRegrabTravelDistance = 2.5f;

	private const float MinRegrabAirTime = 0.55f;

	private const float FullFallSlipSpeed = 30f;

	private const float FullHorizontalSlipSpeed = 35f;

	private const float MinSlipMultiplier = 0.25f;

	private const float MaxSlipMultiplier = 2.5f;

	private const float SlipCurvePower = 1.8f;

	private const float OverallSlipMultiplier = 3.5f;

	private static readonly ManualLogSource LogSource = Logger.CreateLogSource("Skate.FallSpeedSlip");

	private static Character trackedCharacter;

	private static bool hasGrabbedSinceGrounded;

	private static bool detachActive;

	private static float detachTime;

	private static Vector3 detachPosition;

	private static int lastProcessedGrabFrame = -1;

	private static int lastProcessedDetachFrame = -1;

	private static void ResetState(Character character)
	{
		//IL_001d: 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)
		trackedCharacter = character;
		hasGrabbedSinceGrounded = false;
		detachActive = false;
		detachTime = 0f;
		detachPosition = Vector3.zero;
		lastProcessedGrabFrame = -1;
		lastProcessedDetachFrame = -1;
		LogSource.LogInfo((object)"[FallSpeedSlip][RESET]");
	}

	private static void EnsureCharacter(Character character)
	{
		if (!((Object)(object)trackedCharacter == (Object)(object)character))
		{
			ResetState(character);
		}
	}

	[HarmonyPrefix]
	private static void Prefix(CharacterClimbing __instance, out ClimbState __state)
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		__state = new ClimbState();
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		Character component = ((Component)__instance).GetComponent<Character>();
		if ((Object)(object)component == (Object)null || (Object)(object)component.data == (Object)null || (Object)(object)component != (Object)(object)Character.localCharacter)
		{
			return;
		}
		EnsureCharacter(component);
		if (TryGetActualAverageVelocity(component, out var averageVelocity))
		{
			__state.Character = component;
			__state.Velocity = averageVelocity;
			__state.HadPreviousGrab = hasGrabbedSinceGrounded;
			__state.HadDetach = detachActive;
			if (detachActive)
			{
				__state.TimeSinceDetach = Mathf.Max(0f, Time.time - detachTime);
				__state.DistanceSinceDetach = Vector3.Distance(detachPosition, component.Center);
			}
			__state.Valid = true;
		}
	}

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	private static void Postfix(CharacterClimbing __instance, Vector3 climbPos, Vector3 climbNormal, ClimbState __state)
	{
		//IL_007d: 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)
		//IL_00b7: 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_00bd: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_00df: 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_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: 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)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: 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_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || __state == null || !__state.Valid || (Object)(object)__state.Character == (Object)null)
		{
			return;
		}
		if (lastProcessedGrabFrame == Time.frameCount)
		{
			LogSource.LogInfo((object)("[FallSpeedSlip][DUPLICATE-GRAB-SKIPPED] frame=" + Time.frameCount));
			return;
		}
		lastProcessedGrabFrame = Time.frameCount;
		Character character = __state.Character;
		Vector3 velocity = __state.Velocity;
		if (((Vector3)(ref climbNormal)).sqrMagnitude < 0.0001f)
		{
			__instance.playerSlide = Vector2.zero;
			ConsumeCharacterVelocity(character);
			MarkGrabbed();
			return;
		}
		Vector3 normalized = ((Vector3)(ref climbNormal)).normalized;
		Vector3 val = Vector3.ProjectOnPlane(Vector3.up, normalized);
		if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
		{
			__instance.playerSlide = Vector2.zero;
			ConsumeCharacterVelocity(character);
			MarkGrabbed();
			return;
		}
		((Vector3)(ref val)).Normalize();
		Vector3 val2 = Vector3.Cross(val, normalized);
		if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
		{
			__instance.playerSlide = Vector2.zero;
			ConsumeCharacterVelocity(character);
			MarkGrabbed();
			return;
		}
		((Vector3)(ref val2)).Normalize();
		Vector3 val3 = Vector3.ProjectOnPlane(velocity, normalized);
		float num = Vector3.Dot(val3, val);
		float num2 = Mathf.Max(0f, 0f - num);
		float num3 = Vector3.Dot(val3, -val2);
		float num4 = Mathf.Abs(num3);
		bool flag = !__state.HadPreviousGrab;
		bool flag2 = __state.HadDetach && (__state.DistanceSinceDetach >= 2.5f || __state.TimeSinceDetach >= 0.55f);
		float num5 = (flag ? 5f : 6.5f);
		bool flag3 = num2 >= 4.5f;
		bool flag4 = num4 >= num5 && (flag || flag2);
		float num6 = 0f;
		float num7 = 0f;
		float num8 = 0f;
		float num9 = 0f;
		float num10 = 0f;
		float num11 = 0f;
		if (flag3)
		{
			num8 = Mathf.InverseLerp(4.5f, 30f, num2);
			num8 = Mathf.Pow(num8, 1.8f);
			num10 = Mathf.Lerp(0.25f, 2.5f, num8);
			num6 = (0f - num2) * 1.5f * num10 * 3.5f;
		}
		if (flag4)
		{
			num9 = Mathf.InverseLerp(num5, 35f, num4);
			num9 = Mathf.Pow(num9, 1.8f);
			num11 = Mathf.Lerp(0.25f, 2.5f, num9);
			num7 = num3 * 1.5f * num11 * 3.5f;
		}
		num6 = Mathf.Min(0f, num6);
		if (!flag3 && !flag4)
		{
			__instance.playerSlide = Vector2.zero;
		}
		else
		{
			__instance.playerSlide = new Vector2(num7, num6);
		}
		LogSource.LogInfo((object)("[FallSpeedSlip][RESULT] frame=" + Time.frameCount + " first=" + flag + " regrabTravel=" + flag2 + " time=" + __state.TimeSinceDetach.ToString("F3") + " distance=" + __state.DistanceSinceDetach.ToString("F3") + " wallH=" + num4.ToString("F3") + " hThreshold=" + num5.ToString("F3") + " wallDown=" + num2.ToString("F3") + " horizontalSlip=" + flag4 + " fallSlip=" + flag3 + " slide=" + V2(__instance.playerSlide)));
		ConsumeCharacterVelocity(character);
		MarkGrabbed();
	}

	private static void MarkGrabbed()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		hasGrabbedSinceGrounded = true;
		detachActive = false;
		detachTime = 0f;
		detachPosition = Vector3.zero;
	}

	private static bool TryGetActualAverageVelocity(Character character, out Vector3 averageVelocity)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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)
		averageVelocity = Vector3.zero;
		if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return false;
		}
		Vector3 val = Vector3.zero;
		int num = 0;
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val2 = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Rig == (Object)null) && !val2.Rig.isKinematic)
			{
				val += val2.Rig.linearVelocity;
				num++;
			}
		}
		if (num <= 0)
		{
			return false;
		}
		averageVelocity = val / (float)num;
		return true;
	}

	private static void ConsumeCharacterVelocity(Character character)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
		{
			return;
		}
		for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
		{
			Bodypart val = character.refs.ragdoll.partList[i];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Rig == (Object)null) && !val.Rig.isKinematic)
			{
				val.Rig.linearVelocity = Vector3.zero;
			}
		}
	}

	private static string V3(Vector3 value)
	{
		return "(" + value.x.ToString("F3") + "," + value.y.ToString("F3") + "," + value.z.ToString("F3") + ")";
	}

	private static string V2(Vector2 value)
	{
		return "(" + value.x.ToString("F3") + "," + value.y.ToString("F3") + ")";
	}
}