Decompiled source of Bikings v1.1.1

ValheimBikeMod.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Networking;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		return new MonoScriptData
		{
			FilePathsData = new byte[565]
			{
				0, 0, 0, 1, 0, 0, 0, 43, 92, 65,
				115, 115, 101, 116, 115, 92, 86, 97, 108, 104,
				101, 105, 109, 66, 105, 107, 101, 77, 111, 100,
				92, 83, 99, 114, 105, 112, 116, 115, 92, 66,
				105, 107, 101, 65, 117, 100, 105, 111, 46, 99,
				115, 0, 0, 0, 4, 0, 0, 0, 48, 92,
				65, 115, 115, 101, 116, 115, 92, 86, 97, 108,
				104, 101, 105, 109, 66, 105, 107, 101, 77, 111,
				100, 92, 83, 99, 114, 105, 112, 116, 115, 92,
				66, 105, 107, 101, 66, 117, 105, 108, 100, 80,
				105, 101, 99, 101, 46, 99, 115, 0, 0, 0,
				2, 0, 0, 0, 44, 92, 65, 115, 115, 101,
				116, 115, 92, 86, 97, 108, 104, 101, 105, 109,
				66, 105, 107, 101, 77, 111, 100, 92, 83, 99,
				114, 105, 112, 116, 115, 92, 66, 105, 107, 101,
				67, 111, 110, 102, 105, 103, 46, 99, 115, 0,
				0, 0, 1, 0, 0, 0, 48, 92, 65, 115,
				115, 101, 116, 115, 92, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 77, 111, 100, 92,
				83, 99, 114, 105, 112, 116, 115, 92, 66, 105,
				107, 101, 67, 111, 110, 116, 114, 111, 108, 108,
				101, 114, 46, 99, 115, 0, 0, 0, 1, 0,
				0, 0, 53, 92, 65, 115, 115, 101, 116, 115,
				92, 86, 97, 108, 104, 101, 105, 109, 66, 105,
				107, 101, 77, 111, 100, 92, 83, 99, 114, 105,
				112, 116, 115, 92, 66, 105, 107, 101, 77, 111,
				117, 110, 116, 67, 111, 110, 116, 114, 111, 108,
				108, 101, 114, 46, 99, 115, 0, 0, 0, 1,
				0, 0, 0, 52, 92, 65, 115, 115, 101, 116,
				115, 92, 86, 97, 108, 104, 101, 105, 109, 66,
				105, 107, 101, 77, 111, 100, 92, 83, 99, 114,
				105, 112, 116, 115, 92, 66, 105, 107, 101, 82,
				105, 100, 101, 114, 65, 110, 105, 109, 97, 116,
				105, 111, 110, 46, 99, 115, 0, 0, 0, 3,
				0, 0, 0, 47, 92, 65, 115, 115, 101, 116,
				115, 92, 86, 97, 108, 104, 101, 105, 109, 66,
				105, 107, 101, 77, 111, 100, 92, 83, 99, 114,
				105, 112, 116, 115, 92, 66, 105, 107, 101, 82,
				105, 100, 101, 114, 80, 111, 115, 101, 46, 99,
				115, 0, 0, 0, 1, 0, 0, 0, 54, 92,
				65, 115, 115, 101, 116, 115, 92, 86, 97, 108,
				104, 101, 105, 109, 66, 105, 107, 101, 77, 111,
				100, 92, 83, 99, 114, 105, 112, 116, 115, 92,
				66, 105, 107, 101, 86, 105, 115, 117, 97, 108,
				67, 111, 110, 116, 114, 111, 108, 108, 101, 114,
				46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
				45, 92, 65, 115, 115, 101, 116, 115, 92, 86,
				97, 108, 104, 101, 105, 109, 66, 105, 107, 101,
				77, 111, 100, 92, 83, 99, 114, 105, 112, 116,
				115, 92, 66, 105, 107, 105, 110, 103, 82, 97,
				100, 105, 111, 46, 99, 115, 0, 0, 0, 3,
				0, 0, 0, 51, 92, 65, 115, 115, 101, 116,
				115, 92, 86, 97, 108, 104, 101, 105, 109, 66,
				105, 107, 101, 77, 111, 100, 92, 83, 99, 114,
				105, 112, 116, 115, 92, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 80, 108, 117, 103,
				105, 110, 46, 99, 115
			},
			TypesData = new byte[735]
			{
				0, 0, 0, 0, 24, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 77, 111, 100, 124,
				66, 105, 107, 101, 65, 117, 100, 105, 111, 0,
				0, 0, 0, 29, 86, 97, 108, 104, 101, 105,
				109, 66, 105, 107, 101, 77, 111, 100, 124, 66,
				105, 107, 101, 66, 117, 105, 108, 100, 80, 105,
				101, 99, 101, 0, 0, 0, 0, 45, 86, 97,
				108, 104, 101, 105, 109, 66, 105, 107, 101, 77,
				111, 100, 46, 66, 105, 107, 101, 66, 117, 105,
				108, 100, 80, 105, 101, 99, 101, 124, 90, 78,
				101, 116, 83, 99, 101, 110, 101, 95, 65, 119,
				97, 107, 101, 0, 0, 0, 0, 44, 86, 97,
				108, 104, 101, 105, 109, 66, 105, 107, 101, 77,
				111, 100, 46, 66, 105, 107, 101, 66, 117, 105,
				108, 100, 80, 105, 101, 99, 101, 124, 79, 98,
				106, 101, 99, 116, 68, 66, 95, 65, 119, 97,
				107, 101, 0, 0, 0, 0, 46, 86, 97, 108,
				104, 101, 105, 109, 66, 105, 107, 101, 77, 111,
				100, 46, 66, 105, 107, 101, 66, 117, 105, 108,
				100, 80, 105, 101, 99, 101, 124, 80, 108, 97,
				121, 101, 114, 95, 79, 110, 83, 112, 97, 119,
				110, 101, 100, 0, 0, 0, 0, 25, 86, 97,
				108, 104, 101, 105, 109, 66, 105, 107, 101, 77,
				111, 100, 124, 66, 105, 107, 101, 67, 111, 110,
				102, 105, 103, 0, 0, 0, 0, 52, 66, 101,
				112, 73, 110, 69, 120, 46, 67, 111, 110, 102,
				105, 103, 117, 114, 97, 116, 105, 111, 110, 124,
				67, 111, 110, 102, 105, 103, 117, 114, 97, 116,
				105, 111, 110, 77, 97, 110, 97, 103, 101, 114,
				65, 116, 116, 114, 105, 98, 117, 116, 101, 115,
				0, 0, 0, 0, 29, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 77, 111, 100, 124,
				66, 105, 107, 101, 67, 111, 110, 116, 114, 111,
				108, 108, 101, 114, 0, 0, 0, 0, 34, 86,
				97, 108, 104, 101, 105, 109, 66, 105, 107, 101,
				77, 111, 100, 124, 66, 105, 107, 101, 77, 111,
				117, 110, 116, 67, 111, 110, 116, 114, 111, 108,
				108, 101, 114, 0, 0, 0, 0, 33, 86, 97,
				108, 104, 101, 105, 109, 66, 105, 107, 101, 77,
				111, 100, 124, 66, 105, 107, 101, 82, 105, 100,
				101, 114, 65, 110, 105, 109, 97, 116, 105, 111,
				110, 0, 0, 0, 0, 25, 86, 97, 108, 104,
				101, 105, 109, 66, 105, 107, 101, 77, 111, 100,
				124, 82, 105, 100, 101, 114, 66, 111, 110, 101,
				115, 0, 0, 0, 0, 29, 86, 97, 108, 104,
				101, 105, 109, 66, 105, 107, 101, 77, 111, 100,
				124, 82, 105, 100, 101, 114, 80, 111, 115, 101,
				70, 114, 97, 109, 101, 0, 0, 0, 0, 30,
				86, 97, 108, 104, 101, 105, 109, 66, 105, 107,
				101, 77, 111, 100, 124, 82, 105, 100, 101, 114,
				80, 111, 115, 101, 83, 111, 108, 118, 101, 114,
				0, 0, 0, 0, 35, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 77, 111, 100, 124,
				66, 105, 107, 101, 86, 105, 115, 117, 97, 108,
				67, 111, 110, 116, 114, 111, 108, 108, 101, 114,
				0, 0, 0, 0, 26, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 77, 111, 100, 124,
				66, 105, 107, 105, 110, 103, 82, 97, 100, 105,
				111, 0, 0, 0, 0, 32, 86, 97, 108, 104,
				101, 105, 109, 66, 105, 107, 101, 77, 111, 100,
				124, 86, 97, 108, 104, 101, 105, 109, 66, 105,
				107, 101, 80, 108, 117, 103, 105, 110, 0, 0,
				0, 0, 52, 86, 97, 108, 104, 101, 105, 109,
				66, 105, 107, 101, 77, 111, 100, 46, 86, 97,
				108, 104, 101, 105, 109, 66, 105, 107, 101, 80,
				108, 117, 103, 105, 110, 124, 66, 108, 111, 99,
				107, 80, 108, 97, 121, 101, 114, 67, 111, 110,
				116, 114, 111, 108, 115, 0, 0, 0, 0, 55,
				86, 97, 108, 104, 101, 105, 109, 66, 105, 107,
				101, 77, 111, 100, 46, 86, 97, 108, 104, 101,
				105, 109, 66, 105, 107, 101, 80, 108, 117, 103,
				105, 110, 124, 80, 111, 115, 101, 82, 105, 100,
				101, 114, 115, 66, 101, 102, 111, 114, 101, 67,
				97, 109, 101, 114, 97
			},
			TotalFiles = 10,
			TotalTypes = 18,
			IsEditorOnly = false
		};
	}
}
namespace BepInEx.Configuration
{
	internal sealed class ConfigurationManagerAttributes
	{
		public bool? ShowRestart { get; set; }

		public string DispName { get; set; }

		public string Category { get; set; }

		public int? Order { get; set; }

		public bool? HideDefaultButton { get; set; }

		public bool? IsAdvanced { get; set; }

		public Func<object, string> ObjToStr { get; set; }

		public Func<string, object> StrToObj { get; set; }
	}
}
namespace ValheimBikeMod
{
	[RequireComponent(typeof(BikeController))]
	public sealed class BikeAudio : MonoBehaviour
	{
		public AudioClip slowClip;

		public AudioClip fastClip;

		[Range(0f, 1f)]
		public float volume = 0.8f;

		public float fadeSpeed = 6f;

		[Tooltip("0 = 2D (rider only), 1 = fully positional.")]
		[Range(0f, 1f)]
		public float spatialBlend = 0.85f;

		public float maxDistance = 24f;

		private AudioSource slow;

		private AudioSource fast;

		private int mode;

		private void Awake()
		{
			slow = MakeSource();
			fast = MakeSource();
			AssignClips();
		}

		private AudioSource MakeSource()
		{
			AudioSource obj = ((Component)this).gameObject.AddComponent<AudioSource>();
			obj.loop = true;
			obj.playOnAwake = false;
			obj.volume = 0f;
			obj.spatialBlend = spatialBlend;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.minDistance = 2f;
			obj.maxDistance = maxDistance;
			obj.dopplerLevel = 0f;
			return obj;
		}

		private void AssignClips()
		{
			if (!Object.op_Implicit((Object)(object)slowClip))
			{
				slowClip = ValheimBikePlugin.ChainSlowClip;
			}
			if (!Object.op_Implicit((Object)(object)fastClip))
			{
				fastClip = ValheimBikePlugin.ChainFastClip;
			}
			Assign(slow, slowClip);
			Assign(fast, fastClip);
		}

		private static void Assign(AudioSource s, AudioClip clip)
		{
			if (!((Object)(object)s == (Object)null) && !((Object)(object)clip == (Object)null) && !((Object)(object)s.clip == (Object)(object)clip))
			{
				s.clip = clip;
				s.Play();
			}
		}

		public void SetMode(int m)
		{
			mode = Mathf.Clamp(m, 0, 2);
		}

		private void Update()
		{
			if ((Object.op_Implicit((Object)(object)slow) && !Object.op_Implicit((Object)(object)slow.clip)) || (Object.op_Implicit((Object)(object)fast) && !Object.op_Implicit((Object)(object)fast.clip)))
			{
				AssignClips();
			}
			float num = ((mode == 1) ? volume : 0f);
			float num2 = ((mode == 2) ? volume : 0f);
			if (Object.op_Implicit((Object)(object)slow))
			{
				slow.volume = Mathf.MoveTowards(slow.volume, num, fadeSpeed * Time.deltaTime);
			}
			if (Object.op_Implicit((Object)(object)fast))
			{
				fast.volume = Mathf.MoveTowards(fast.volume, num2, fadeSpeed * Time.deltaTime);
			}
		}

		private void OnDisable()
		{
			mode = 0;
			if (Object.op_Implicit((Object)(object)slow))
			{
				slow.volume = 0f;
			}
			if (Object.op_Implicit((Object)(object)fast))
			{
				fast.volume = 0f;
			}
		}
	}
	internal static class BikeBuildPiece
	{
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class ZNetScene_Awake
		{
			private static readonly FieldInfo NamedPrefabs = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs");

			private static void Postfix(ZNetScene __instance)
			{
				if ((Object)(object)Prefab == (Object)null || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				PreparePrefab();
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)Prefab).name);
				if (!(NamedPrefabs?.GetValue(__instance) is IDictionary dictionary))
				{
					ManualLogSource log = ValheimBikePlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)"BikeBuildPiece: ZNetScene.m_namedPrefabs not found.");
					}
				}
				else if (!dictionary.Contains(stableHashCode))
				{
					__instance.m_prefabs.Add(Prefab);
					dictionary[stableHashCode] = Prefab;
					ManualLogSource log2 = ValheimBikePlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("BikeBuildPiece: registered '" + ((Object)Prefab).name + "' with ZNetScene."));
					}
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDB_Awake
		{
			private static void Postfix()
			{
				AddToHammer();
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static class Player_OnSpawned
		{
			private static void Postfix()
			{
				AddToHammer();
			}
		}

		internal static GameObject Prefab;

		private static bool prefabPrepared;

		private static bool addedToTable;

		private static readonly (string item, int amount)[] Cost = new(string, int)[3]
		{
			("Wood", 10),
			("BronzeNails", 10),
			("Bronze", 1)
		};

		private static void PreparePrefab()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			if (prefabPrepared || (Object)(object)Prefab == (Object)null)
			{
				return;
			}
			prefabPrepared = true;
			try
			{
				((Object)Prefab).name = "ValheimBike";
				Prefab.SetActive(true);
				ZNetView obj = Prefab.GetComponent<ZNetView>() ?? Prefab.AddComponent<ZNetView>();
				obj.m_persistent = true;
				obj.m_type = (ObjectType)1;
				obj.m_syncInitialScale = true;
				obj.m_distant = false;
				ZSyncTransform obj2 = Prefab.GetComponent<ZSyncTransform>() ?? Prefab.AddComponent<ZSyncTransform>();
				obj2.m_syncPosition = true;
				obj2.m_syncRotation = true;
				obj2.m_syncScale = false;
				obj2.m_syncBodyVelocity = false;
				obj2.m_characterParentSync = false;
				Piece obj3 = Prefab.GetComponent<Piece>() ?? Prefab.AddComponent<Piece>();
				obj3.m_name = "Bicycle";
				obj3.m_description = "A craftable rideable bicycle.";
				obj3.m_category = (PieceCategory)0;
				obj3.m_canBeRemoved = true;
				obj3.m_groundPiece = true;
				obj3.m_cultivatedGroundOnly = false;
				obj3.m_allowedInDungeons = false;
				obj3.m_icon = ValheimBikePlugin.BikeIcon;
				obj3.m_placeEffect = new EffectList();
				int num = LayerMask.NameToLayer("piece");
				if (num >= 0)
				{
					Prefab.layer = num;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = ValheimBikePlugin.Log;
				if (log != null)
				{
					log.LogError((object)("BikeBuildPiece.PreparePrefab failed: " + ex));
				}
			}
		}

		private static bool BuildRequirements(Piece piece)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return false;
			}
			List<Requirement> list = new List<Requirement>();
			(string, int)[] cost = Cost;
			for (int i = 0; i < cost.Length; i++)
			{
				(string, int) tuple = cost[i];
				string item = tuple.Item1;
				int item2 = tuple.Item2;
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
				ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log = ValheimBikePlugin.Log;
					if (log != null)
					{
						log.LogDebug((object)("BikeBuildPiece: '" + item + "' not in ObjectDB yet, will retry."));
					}
					return false;
				}
				list.Add(new Requirement
				{
					m_resItem = val,
					m_amount = item2,
					m_recover = true
				});
			}
			piece.m_resources = list.ToArray();
			return true;
		}

		private static void AddToHammer()
		{
			if (addedToTable || (Object)(object)Prefab == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			PreparePrefab();
			Piece component = Prefab.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null || !BuildRequirements(component))
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer");
			PieceTable val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildPieces;
			if (!((Object)(object)val == (Object)null) && val.m_pieces != null && !val.m_pieces.Contains(Prefab))
			{
				val.m_pieces.Add(Prefab);
				addedToTable = true;
				ManualLogSource log = ValheimBikePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"BikeBuildPiece: added to Hammer menu (10 Wood, 10 BronzeNails, 1 Bronze).");
				}
			}
		}
	}
	internal static class BikeConfig
	{
		private const int CurrentLayout = 2;

		private static ConfigEntry<float> _baseSpeed;

		private static ConfigEntry<float> _cruiseMul;

		private static ConfigEntry<float> _sprintMul;

		private static ConfigEntry<float> _accel;

		private static ConfigEntry<float> _sprintAccelMul;

		private static ConfigEntry<float> _braking;

		private static ConfigEntry<float> _reverseSpeed;

		private static ConfigEntry<float> _turnRate;

		private static ConfigEntry<float> _highSpeedSteer;

		private static ConfigEntry<int> _tapsToSprint;

		private static ConfigEntry<float> _smallObstacle;

		private static ConfigEntry<float> _smallObstacleW;

		private static ConfigEntry<float> _leanAngle;

		private static ConfigEntry<float> _sprintRock;

		private static ConfigEntry<float> _hopMinHeight;

		private static ConfigEntry<float> _hopMaxHeight;

		private static ConfigEntry<float> _hopChargeTime;

		private static ConfigEntry<bool> _wheelies;

		private static ConfigEntry<bool> _fallOff;

		private static ConfigEntry<bool> _sendFlying;

		private static ConfigEntry<float> _enemyDmg;

		private static ConfigEntry<float> _enemyMinSpeed;

		private static ConfigEntry<float> _enemyPower;

		private static ConfigEntry<bool> _destruction;

		private static ConfigEntry<float> _crashSpeed;

		private static ConfigEntry<bool> _cameraFollow;

		private static ConfigEntry<float> _cameraFollowDelay;

		private static ConfigEntry<float> _fastPedalAnimSpeed;

		private static ConfigEntry<float> _cadenceScale;

		private static ConfigEntry<float> _hipHeight;

		private static ConfigEntry<KeyCode> _sprintKey;

		private static ConfigEntry<bool> _mouseDrive;

		private static ConfigEntry<KeyCode> _hopKey;

		private static ConfigEntry<KeyCode> _dismountKey;

		private static ConfigEntry<KeyCode> _leanForwardKey;

		private static ConfigEntry<KeyCode> _leanBackKey;

		private static ConfigEntry<KeyCode> _radioNextKey;

		private static ConfigEntry<KeyCode> _radioOffKey;

		private static ConfigEntry<KeyCode> _volumeUpKey;

		private static ConfigEntry<KeyCode> _volumeDownKey;

		private static ConfigEntry<KeyCode> _accelButton;

		private static ConfigEntry<KeyCode> _brakeButton;

		private static ConfigEntry<KeyCode> _hopButton;

		private static ConfigEntry<KeyCode> _dismountButton;

		private static ConfigEntry<KeyCode> _radioNextButton;

		private static ConfigEntry<KeyCode> _radioOffButton;

		private static ConfigEntry<int> _layout;

		private static int _order;

		public static bool Ready { get; private set; }

		private static ConfigDescription Desc(string desc, AcceptableValueBase range = null)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			return new ConfigDescription(desc, range, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					ShowRestart = false,
					Order = _order++
				}
			});
		}

		public static void Init(ConfigFile cfg)
		{
			if (cfg != null)
			{
				_order = 0;
				_baseSpeed = cfg.Bind<float>("Speed", "BaseSpeed", 12f, Desc("Top speed (m/s) when pedalling steadily at a cruise.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f)));
				_cruiseMul = cfg.Bind<float>("Speed", "CruiseSpeedMultiplier", 1f, Desc("Speed multiplier while just holding W / B (easy, relaxed pace).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f)));
				_sprintMul = cfg.Bind<float>("Speed", "SprintSpeedMultiplier", 1.7f, Desc("Speed multiplier while fast-pedalling (hold Shift, or tap-mash W / B).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 6f)));
				_accel = cfg.Bind<float>("Speed", "Acceleration", 9f, Desc("How quickly the bike reaches its target speed (m/s^2).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f)));
				_sprintAccelMul = cfg.Bind<float>("Speed", "SprintAccelMultiplier", 1.6f, Desc("Acceleration multiplier while fast-pedalling.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 6f)));
				_braking = cfg.Bind<float>("Speed", "Braking", 16f, Desc("Deceleration when braking / reversing (m/s^2).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 80f)));
				_reverseSpeed = cfg.Bind<float>("Speed", "ReverseSpeed", 2.5f, Desc("Top speed (m/s) when reversing (hold S when stopped).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f)));
				_turnRate = cfg.Bind<float>("Handling", "TurnRate", 130f, Desc("Steering rate (degrees/second at low speed). Higher = sharper turning.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 240f)));
				_highSpeedSteer = cfg.Bind<float>("Handling", "HighSpeedSteerFactor", 0.45f, Desc("Fraction of the low-speed steer rate still available at top speed (higher = more responsive / twitchier when moving fast).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f)));
				_tapsToSprint = cfg.Bind<int>("Handling", "TapsToSprint", 2, Desc("Rapid taps of W / B inside the tap window needed to trigger fast pedalling.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6)));
				_smallObstacle = cfg.Bind<float>("Handling", "SmallObstacleHeight", 0.65f, Desc("Obstacles shorter than this (metres above the ground) are ridden THROUGH: dropped food / items, plants, grass tufts, small stones. Taller obstacles (rocks, walls, trees, stumps) still stop the bike.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f)));
				_smallObstacleW = cfg.Bind<float>("Handling", "SmallObstacleWidth", 0.35f, Desc("Obstacles narrower than this (metres across) are ridden through no matter how tall they are - saplings, shoots, thin stalks simply bend aside.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f)));
				_leanAngle = cfg.Bind<float>("Riding", "LeanAngle", 26f, Desc("Maximum angle (degrees) the bike and rider lean into corners. 0 = stay upright.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 45f)));
				_sprintRock = cfg.Bind<float>("Riding", "SprintRockAngle", 3f, Desc("Side-to-side rock (degrees) of the bike while sprinting out of the saddle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f)));
				_hopMinHeight = cfg.Bind<float>("Riding", "BunnyHopMinHeight", 0.45f, Desc("Bunny hop height (m) for a quick tap of the hop key.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 3f)));
				_hopMaxHeight = cfg.Bind<float>("Riding", "BunnyHopMaxHeight", 1.8f, Desc("Bunny hop height (m) when the hop key is held for the full charge time - the longer you hold Space, the higher you go, up to this. Crank it up for silly moon jumps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 50f)));
				_hopChargeTime = cfg.Bind<float>("Riding", "BunnyHopChargeTime", 1f, Desc("Seconds of holding the hop key to reach the maximum hop height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 4f)));
				_wheelies = cfg.Bind<bool>("Riding", "Wheelies", true, Desc("Lean back while pedalling for a wheelie, lean forward while braking for a stoppie."));
				_fallOff = cfg.Bind<bool>("Riding", "FallOffBike", false, Desc("True = a hard crash (above CrashKnockOffSpeed) throws the rider over the handlebars. False = you never fall off; the bike just stops."));
				_sendFlying = cfg.Bind<bool>("Riding", "SendEnemiesFlying", true, Desc("Ride into monsters / wild animals at speed and they go FLYING. Other players and tamed animals are never hit."));
				_enemyDmg = cfg.Bind<float>("Riding", "EnemyHitDamage", 25f, Desc("Blunt damage dealt to an enemy you ride into (scaled by speed). 0 = harmless launches; the top of the slider hits like a battering ram.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f)));
				_enemyMinSpeed = cfg.Bind<float>("Riding", "EnemyLaunchMinSpeed", 3f, Desc("Below this speed (m/s) enemies are just pushed aside instead of launched.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f)));
				_enemyPower = cfg.Bind<float>("Riding", "EnemyLaunchPower", 1f, Desc("How FAR enemies fly when you ride into them. 1 = normal bowling; crank it up for home-run launches across the map.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f)));
				_destruction = cfg.Bind<bool>("Riding", "DestructionMode", true, Desc("SMASH MODE: ride through trees, rocks, bushes and structures and destroy them (they drop their normal resources). WARNING: this includes player buildings - including your own. Turn off to collide with things normally."));
				_crashSpeed = cfg.Bind<float>("Riding", "CrashKnockOffSpeed", 13f, Desc("Only used when FallOffBike is True: hitting a solid obstacle faster than this (m/s) throws the rider off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f)));
				_cameraFollow = cfg.Bind<bool>("Riding", "CameraAutoFollow", true, Desc("Swing the camera back behind the bike when you stop moving the mouse / right stick."));
				_cameraFollowDelay = cfg.Bind<float>("Riding", "CameraFollowDelay", 1f, Desc("Seconds without camera input before the camera starts swinging behind the bike.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f)));
				_fastPedalAnimSpeed = cfg.Bind<float>("Animation", "FastPedalAnimSpeed", 1.7f, Desc("Pedal cadence multiplier while sprinting out of the saddle.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f)));
				_cadenceScale = cfg.Bind<float>("Animation", "PedalCadenceScale", 1f, Desc("Scales how fast the legs turn the pedals for a given speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f)));
				_hipHeight = cfg.Bind<float>("Animation", "SeatHipHeight", 0.1f, Desc("Height (m) of the rider's hip joint above the saddle. Raise if the rider sinks into the seat.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.3f, 0.5f)));
				_sprintKey = cfg.Bind<KeyCode>("Controls - keyboard", "SprintKey", (KeyCode)304, Desc("Hold for fast pedalling (stand up on the pedals). Tap-mashing W does the same."));
				_mouseDrive = cfg.Bind<bool>("Controls - keyboard", "MouseDrive", true, Desc("Hold LEFT MOUSE to pedal AND steer toward wherever the camera is looking."));
				_hopKey = cfg.Bind<KeyCode>("Controls - keyboard", "BunnyHopKey", (KeyCode)32, Desc("Bunny hop. Hold to crouch and charge a higher hop, release to jump."));
				_dismountKey = cfg.Bind<KeyCode>("Controls - keyboard", "DismountKey", (KeyCode)101, Desc("Get off the bike (the same key that gets you on)."));
				_leanForwardKey = cfg.Bind<KeyCode>("Controls - keyboard", "LeanForwardKey", (KeyCode)264, Desc("Lean forward (brake + lean forward = stoppie)."));
				_leanBackKey = cfg.Bind<KeyCode>("Controls - keyboard", "LeanBackKey", (KeyCode)258, Desc("Lean back (pedal + lean back = wheelie)."));
				_radioNextKey = cfg.Bind<KeyCode>("Controls - keyboard", "RadioNextKey", (KeyCode)110, Desc("Next radio track."));
				_radioOffKey = cfg.Bind<KeyCode>("Controls - keyboard", "RadioOffKey", (KeyCode)98, Desc("Turn the radio off."));
				_volumeUpKey = cfg.Bind<KeyCode>("Controls - keyboard", "RadioVolumeUpKey", (KeyCode)93, Desc("Radio volume up."));
				_volumeDownKey = cfg.Bind<KeyCode>("Controls - keyboard", "RadioVolumeDownKey", (KeyCode)91, Desc("Radio volume down."));
				_accelButton = cfg.Bind<KeyCode>("Controls - gamepad", "AccelButton", (KeyCode)331, Desc("Pedal (default B). Hold = cruise, tap-mash = sprint. The right trigger also pedals."));
				_brakeButton = cfg.Bind<KeyCode>("Controls - gamepad", "BrakeButton", (KeyCode)330, Desc("Brake / reverse (default A). The left trigger also brakes."));
				_hopButton = cfg.Bind<KeyCode>("Controls - gamepad", "BunnyHopButton", (KeyCode)332, Desc("Bunny hop (default X). Hold to charge, release to jump."));
				_dismountButton = cfg.Bind<KeyCode>("Controls - gamepad", "DismountButton", (KeyCode)333, Desc("Get off the bike (default Y)."));
				_radioNextButton = cfg.Bind<KeyCode>("Controls - gamepad", "RadioNextButton", (KeyCode)335, Desc("Next radio track (default RB)."));
				_radioOffButton = cfg.Bind<KeyCode>("Controls - gamepad", "RadioOffButton", (KeyCode)334, Desc("Turn the radio off (default LB)."));
				_layout = cfg.Bind<int>("Internal", "ControlLayoutVersion", 1, Desc("Used to migrate old default key bindings. Don't edit."));
				MigrateOldDefaults();
				Ready = true;
			}
		}

		private static void MigrateOldDefaults()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			if (_layout.Value >= 2)
			{
				return;
			}
			bool flag = false;
			if ((int)_dismountKey.Value == 32)
			{
				_dismountKey.Value = (KeyCode)101;
				flag = true;
			}
			if ((int)_radioNextKey.Value == 101)
			{
				_radioNextKey.Value = (KeyCode)110;
				flag = true;
			}
			if ((int)_radioOffKey.Value == 114)
			{
				_radioOffKey.Value = (KeyCode)98;
				flag = true;
			}
			if (Mathf.Approximately(_turnRate.Value, 85f))
			{
				_turnRate.Value = 110f;
				flag = true;
			}
			_layout.Value = 2;
			if (flag)
			{
				ManualLogSource log = ValheimBikePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Bike config: moved old default keys to the new layout (Space = bunny hop, E = get off, N / B = radio).");
				}
			}
		}

		private static float F(ConfigEntry<float> e, float fallback)
		{
			if (!Ready || e == null)
			{
				return fallback;
			}
			return e.Value;
		}

		private static bool B(ConfigEntry<bool> e, bool fallback)
		{
			if (!Ready || e == null)
			{
				return fallback;
			}
			return e.Value;
		}

		public static float BaseSpeed(float fallback)
		{
			return F(_baseSpeed, fallback);
		}

		public static float CruiseMultiplier(float fallback)
		{
			return F(_cruiseMul, fallback);
		}

		public static float SprintMultiplier(float fallback)
		{
			return F(_sprintMul, fallback);
		}

		public static float Acceleration(float fallback)
		{
			return F(_accel, fallback);
		}

		public static float SprintAccelMultiplier(float fallback)
		{
			return F(_sprintAccelMul, fallback);
		}

		public static float Braking(float fallback)
		{
			return F(_braking, fallback);
		}

		public static float ReverseSpeed(float fallback)
		{
			return F(_reverseSpeed, fallback);
		}

		public static float TurnRate(float fallback)
		{
			return F(_turnRate, fallback);
		}

		public static float HighSpeedSteer(float fallback)
		{
			return F(_highSpeedSteer, fallback);
		}

		public static int TapsToSprint(int fallback)
		{
			if (!Ready || _tapsToSprint == null)
			{
				return fallback;
			}
			return _tapsToSprint.Value;
		}

		public static float SmallObstacleHeight(float fallback)
		{
			return F(_smallObstacle, fallback);
		}

		public static float SmallObstacleWidth(float fallback)
		{
			return F(_smallObstacleW, fallback);
		}

		public static float LeanAngle(float fallback)
		{
			return F(_leanAngle, fallback);
		}

		public static float SprintRockAngle(float fallback)
		{
			return F(_sprintRock, fallback);
		}

		public static float HopMinHeight(float fallback)
		{
			return F(_hopMinHeight, fallback);
		}

		public static float HopMaxHeight(float fallback)
		{
			return F(_hopMaxHeight, fallback);
		}

		public static float HopChargeTime(float fallback)
		{
			return F(_hopChargeTime, fallback);
		}

		public static bool Wheelies(bool fallback)
		{
			return B(_wheelies, fallback);
		}

		public static bool FallOffBike(bool fallback)
		{
			return B(_fallOff, fallback);
		}

		public static bool SendEnemiesFlying(bool fallback)
		{
			return B(_sendFlying, fallback);
		}

		public static float EnemyHitDamage(float fallback)
		{
			return F(_enemyDmg, fallback);
		}

		public static float EnemyLaunchMinSpeed(float fallback)
		{
			return F(_enemyMinSpeed, fallback);
		}

		public static float EnemyLaunchPower(float fallback)
		{
			return F(_enemyPower, fallback);
		}

		public static bool DestructionMode(bool fallback)
		{
			return B(_destruction, fallback);
		}

		public static float CrashKnockOffSpeed(float fallback)
		{
			return F(_crashSpeed, fallback);
		}

		public static bool CameraAutoFollow(bool fallback)
		{
			return B(_cameraFollow, fallback);
		}

		public static float CameraFollowDelay(float fallback)
		{
			return F(_cameraFollowDelay, fallback);
		}

		public static float FastPedalAnimSpeed(float fallback)
		{
			return F(_fastPedalAnimSpeed, fallback);
		}

		public static float PedalCadenceScale(float fallback)
		{
			return F(_cadenceScale, fallback);
		}

		public static float SeatHipHeight(float fallback)
		{
			return F(_hipHeight, fallback);
		}

		private static KeyCode K(ConfigEntry<KeyCode> e, KeyCode fallback)
		{
			//IL_000a: 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)
			if (!Ready || e == null)
			{
				return fallback;
			}
			return e.Value;
		}

		public static bool MouseDrive(bool fallback)
		{
			return B(_mouseDrive, fallback);
		}

		public static KeyCode SprintKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_sprintKey, f);
		}

		public static KeyCode HopKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_hopKey, f);
		}

		public static KeyCode DismountKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_dismountKey, f);
		}

		public static KeyCode LeanForwardKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_leanForwardKey, f);
		}

		public static KeyCode LeanBackKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_leanBackKey, f);
		}

		public static KeyCode RadioNextKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_radioNextKey, f);
		}

		public static KeyCode RadioOffKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_radioOffKey, f);
		}

		public static KeyCode VolumeUpKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_volumeUpKey, f);
		}

		public static KeyCode VolumeDownKey(KeyCode f)
		{
			//IL_0005: 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)
			return K(_volumeDownKey, f);
		}

		public static KeyCode AccelButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_accelButton, f);
		}

		public static KeyCode BrakeButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_brakeButton, f);
		}

		public static KeyCode HopButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_hopButton, f);
		}

		public static KeyCode DismountButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_dismountButton, f);
		}

		public static KeyCode RadioNextButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_radioNextButton, f);
		}

		public static KeyCode RadioOffButton(KeyCode f)
		{
			//IL_0005: 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)
			return K(_radioOffButton, f);
		}
	}
	[RequireComponent(typeof(Rigidbody))]
	public sealed class BikeController : MonoBehaviour
	{
		[Header("Arcade physics")]
		[Min(0f)]
		public float maxSpeed = 12f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float maxReverseSpeed = 2.5f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float acceleration = 9f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float braking = 16f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float coasting = 3f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float steerRate = 110f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float uprightStrength = 18f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float uprightDamping = 5f;

		[Header("Arcade physics")]
		[Min(0f)]
		public float lateralGrip = 8f;

		[Tooltip("Fraction of the low-speed steer rate kept at top speed (higher = twitchier at speed).")]
		[Range(0.05f, 1f)]
		public float highSpeedSteer = 0.45f;

		[Tooltip("Speed scrubbed off when cornering hard (0 = none, realistic bikes slow into turns).")]
		[Range(0f, 1f)]
		public float corneringDrag = 0.35f;

		[Header("Stability")]
		[Tooltip("Move as a controlled kinematic vehicle. Avoids PhysX corrupting the attached Player / camera.")]
		public bool stableKinematicMotion = true;

		[Min(0f)]
		public float gravity = 20f;

		[Min(1f)]
		public float maxFallSpeed = 30f;

		[Header("Ground follow (smoothed)")]
		[Tooltip("Radius of the down ground probe - larger = skips small terrain triangles.")]
		[Min(0.05f)]
		public float groundSampleRadius = 0.4f;

		[Tooltip("Distance the two wheel probes sit ahead of / behind centre (half wheelbase).")]
		[Min(0.2f)]
		public float wheelHalfBase = 0.62f;

		[Min(1f)]
		public float groundProbeDepth = 25f;

		[Tooltip("Low-pass on the sampled ground height. Higher = smoother, more bumps absorbed.")]
		[Range(0.02f, 0.5f)]
		public float heightSmoothTime = 0.12f;

		[Tooltip("Cap on how fast the bike corrects its height (m/s).")]
		[Min(0.5f)]
		public float maxHeightSpeed = 7f;

		[Tooltip("Cap on how fast the bike re-pitches to the slope (deg/s).")]
		[Min(5f)]
		public float pitchSmoothSpeed = 55f;

		[Tooltip("Steepest slope the bike will pitch to follow.")]
		[Range(0f, 60f)]
		public float maxSlopeAngle = 32f;

		[Tooltip("Above this SUSTAINED uphill angle the bike loses climbing speed (transient bumps don't count).")]
		[Range(0f, 60f)]
		public float climbLimit = 26f;

		[Tooltip("If ground drops more than this below the bike it falls freely instead of following the ground.")]
		[Min(0.3f)]
		public float maxReconnectDrop = 1.6f;

		[Header("Collision (separate from ground follow)")]
		[Min(0.05f)]
		public float collisionRadius = 0.34f;

		[Min(0f)]
		public float collisionSkin = 0.06f;

		[Tooltip("Obstacles shorter than this above the ground are ridden over (kerb lip only - rocks / roots / stumps should block).")]
		[Min(0f)]
		public float stepOverHeight = 0.14f;

		[Tooltip("Front-end kick (deg) when the bike is stopped by an obstacle - a little jolt.")]
		[Range(0f, 20f)]
		public float obstacleJolt = 7f;

		[Tooltip("Obstacles whose collider top is below this height (m above the ground the bike rides on) are ridden through: dropped items, plants, small stones.")]
		[Min(0f)]
		public float smallObstacleHeight = 0.65f;

		[Tooltip("Obstacles thinner than this (m across, e.g. saplings, stalks, thin posts) are ridden through no matter how tall they are.")]
		[Min(0f)]
		public float smallObstacleWidth = 0.35f;

		[Header("Cadence")]
		[Min(1f)]
		public float sprintSpeedMultiplier = 1.7f;

		[Min(1f)]
		public float sprintAccelMultiplier = 1.6f;

		[Header("Tricks (GTA style)")]
		[Tooltip("Largest wheelie angle (deg): lean back while pedalling.")]
		[Range(0f, 45f)]
		public float maxWheelieAngle = 28f;

		[Tooltip("Largest stoppie angle (deg): lean forward while braking.")]
		[Range(0f, 30f)]
		public float maxStoppieAngle = 16f;

		[Min(1f)]
		public float wheelieRaiseSpeed = 70f;

		[Min(1f)]
		public float wheelieDropSpeed = 110f;

		[Min(0f)]
		public float wheelieMinSpeed = 2.5f;

		[Tooltip("Nose-up kick (deg) at the start of a bunny hop.")]
		[Range(0f, 30f)]
		public float hopPitchKick = 9f;

		[Tooltip("A hop pressed this long after rolling off an edge still counts.")]
		[Min(0f)]
		public float hopCoyoteTime = 0.12f;

		[Header("Water")]
		[Min(0f)]
		public float deepWaterDepth = 0.8f;

		[Header("Enemy bowling (GTA style)")]
		[Tooltip("Characters you ride into at speed are sent flying. Players and tamed animals are never hit.")]
		public bool sendEnemiesFlying = true;

		[Tooltip("Base blunt damage dealt to a character hit at speed (scaled by speed). 0 = harmless launches.")]
		[Min(0f)]
		public float enemyHitDamage = 25f;

		[Tooltip("Below this speed (m/s) characters are just pushed aside instead of launched.")]
		[Min(0f)]
		public float enemyLaunchMinSpeed = 3f;

		private Rigidbody rb;

		private Quaternion lastSafeRotation = Quaternion.identity;

		private float throttle;

		private float steer;

		private float leanInput;

		private bool sprint;

		private float kinematicSpeed;

		private float verticalSpeed;

		private float groundClearance = -1f;

		private bool grounded;

		private float _heading;

		private float _pitchDeg;

		private float _wheelieDeg;

		private float _smoothGroundY;

		private float _groundYVel;

		private float _smoothFrontY;

		private float _smoothRearY;

		private float _frontYVel;

		private float _rearYVel;

		private bool _inAir;

		private float _airPitchKick;

		private float _pendingHopSpeed;

		private float _lastGroundedTime = -99f;

		private float _lastHopTime = -99f;

		private bool _initialised;

		private Transform[] ownTransforms;

		private int characterMask;

		private int collisionMask = -1;

		private int groundMask = -1;

		private int solidGroundMask;

		private ZNetView _znv;

		private Vector3 _lastZdoPush = new Vector3(900000000f, 900000000f, 900000000f);

		private float _steerSmooth;

		private float _steerVel;

		[NonSerialized]
		public Collider[] riderColliders;

		private float _remoteSpeed;

		private int _remotePedal;

		private static readonly Dictionary<Character, float> s_nextLaunch = new Dictionary<Character, float>();

		private static readonly Dictionary<Component, float> s_nextSmash = new Dictionary<Component, float>();

		public float SignedSpeed
		{
			get
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				if (!RemoteDriven())
				{
					if (!stableKinematicMotion)
					{
						if (!Object.op_Implicit((Object)(object)rb))
						{
							return 0f;
						}
						return Vector3.Dot(rb.linearVelocity, ((Component)this).transform.forward);
					}
					return kinematicSpeed;
				}
				return _remoteSpeed;
			}
		}

		public float SteeringInput => _steerSmooth;

		public float Throttle => throttle;

		public float LeanInput => leanInput;

		public bool IsGrounded => grounded;

		public bool InAir => _inAir;

		public float VerticalSpeed => verticalSpeed;

		public float WheelieAngle => _wheelieDeg;

		public float YawRateDeg { get; private set; }

		public bool CanHop
		{
			get
			{
				if (stableKinematicMotion && Time.time - _lastHopTime > 0.3f)
				{
					if (_inAir)
					{
						return Time.time - _lastGroundedTime <= hopCoyoteTime;
					}
					return true;
				}
				return false;
			}
		}

		public int PedalMode
		{
			get
			{
				if (!RemoteDriven())
				{
					if (!(throttle > 0.01f))
					{
						return 0;
					}
					if (!sprint)
					{
						return 1;
					}
					return 2;
				}
				return _remotePedal;
			}
		}

		public event Action<float> Landed;

		public event Action<float> Crashed;

		public event Action<float> Hopped;

		private void Awake()
		{
			//IL_003b: 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)
			rb = ((Component)this).GetComponent<Rigidbody>();
			ownTransforms = ((Component)this).GetComponentsInChildren<Transform>(true);
			rb.interpolation = (RigidbodyInterpolation)1;
			rb.maxAngularVelocity = 8f;
			if (ValidRotation(rb.rotation))
			{
				lastSafeRotation = rb.rotation;
			}
			characterMask = 0;
			string[] array = new string[5] { "character", "character_net", "character_ghost", "character_trigger", "character_noenv" };
			for (int i = 0; i < array.Length; i++)
			{
				int num = LayerMask.NameToLayer(array[i]);
				if (num >= 0)
				{
					characterMask |= 1 << num;
				}
			}
			collisionMask = -5;
			array = new string[17]
			{
				"terrain", "character", "character_net", "character_ghost", "character_trigger", "character_noenv", "piece_nonsolid", "item", "item_floating", "movinginstance",
				"Water", "WaterVolume", "smoke", "weapon", "blocker", "pathblocker", "viewblock"
			};
			for (int i = 0; i < array.Length; i++)
			{
				int num2 = LayerMask.NameToLayer(array[i]);
				if (num2 >= 0)
				{
					collisionMask &= ~(1 << num2);
				}
			}
			groundMask = 0;
			array = new string[3] { "terrain", "piece", "vehicle" };
			for (int i = 0; i < array.Length; i++)
			{
				int num3 = LayerMask.NameToLayer(array[i]);
				if (num3 >= 0)
				{
					groundMask |= 1 << num3;
				}
			}
			if (groundMask == 0)
			{
				groundMask = -5;
			}
			solidGroundMask = 0;
			array = new string[2] { "Default", "static_solid" };
			for (int i = 0; i < array.Length; i++)
			{
				int num4 = LayerMask.NameToLayer(array[i]);
				if (num4 >= 0)
				{
					solidGroundMask |= 1 << num4;
				}
			}
			if (stableKinematicMotion)
			{
				groundClearance = MeasureGroundClearance();
				rb.isKinematic = true;
				rb.useGravity = false;
			}
		}

		private void Start()
		{
			_znv = ((Component)this).GetComponent<ZNetView>();
		}

		private void PushZdoPosition()
		{
			//IL_004c: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			if ((Object)(object)_znv == (Object)null)
			{
				_znv = ((Component)this).GetComponent<ZNetView>();
			}
			if ((Object)(object)_znv == (Object)null)
			{
				return;
			}
			try
			{
				if (!_znv.IsValid() || !_znv.IsOwner())
				{
					return;
				}
				Vector3 val = rb.position - _lastZdoPush;
				if (!(((Vector3)(ref val)).sqrMagnitude < 0.25f))
				{
					ZDO zDO = _znv.GetZDO();
					if (zDO != null)
					{
						zDO.SetPosition(rb.position);
						_lastZdoPush = rb.position;
					}
				}
			}
			catch
			{
			}
		}

		public void SetInput(float t, float s, bool sprinting = false)
		{
			throttle = Mathf.Clamp(t, -1f, 1f);
			steer = Mathf.Clamp(s, -1f, 1f);
			sprint = sprinting && throttle > 0f;
		}

		public void SetLean(float lean)
		{
			leanInput = Mathf.Clamp(lean, -1f, 1f);
		}

		public void ClearInput()
		{
			throttle = (steer = (leanInput = 0f));
			sprint = false;
			_pendingHopSpeed = 0f;
		}

		public bool Hop(float height)
		{
			if (!CanHop || _pendingHopSpeed > 0f)
			{
				return false;
			}
			_pendingHopSpeed = Mathf.Sqrt(2f * Mathf.Max(0.1f, gravity) * Mathf.Max(0.02f, height));
			_lastHopTime = Time.time;
			return true;
		}

		private void FixedUpdate()
		{
			if (Object.op_Implicit((Object)(object)rb) && !RemoteDriven())
			{
				if (stableKinematicMotion)
				{
					StableMove();
					PushZdoPosition();
				}
				else
				{
					DynamicMove();
					PushZdoPosition();
				}
			}
		}

		private bool RemoteDriven()
		{
			if (stableKinematicMotion && (Object)(object)_znv != (Object)null && _znv.IsValid())
			{
				return !_znv.IsOwner();
			}
			return false;
		}

		internal void SetRemoteState(float speed, int pedal)
		{
			_remoteSpeed = speed;
			_remotePedal = Mathf.Clamp(pedal, 0, 2);
		}

		private static Component FindDestructible(Collider c)
		{
			Component[] componentsInParent = ((Component)c).GetComponentsInParent<Component>(true);
			foreach (Component val in componentsInParent)
			{
				if (val is Destructible || val is WearNTear || val is MineRock5 || val is MineRock || val is TreeBase || val is TreeLog)
				{
					return val;
				}
			}
			return null;
		}

		private void DestroyObstacles(Vector3 from, Vector3 delta)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004f: 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_0077: 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_00dd: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_0156: 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_018e: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			float magnitude = ((Vector3)(ref delta)).magnitude;
			if (magnitude < 1E-05f)
			{
				return;
			}
			Vector3 val = delta / magnitude;
			float num = from.y - groundClearance;
			float num2 = num + stepOverHeight + collisionRadius;
			RaycastHit[] array = Physics.SphereCastAll(new Vector3(from.x, num2, from.z), collisionRadius, val, magnitude + collisionSkin, collisionMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if ((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null || ((RaycastHit)(ref val2)).distance <= 0f || IsOwnOrRider(((RaycastHit)(ref val2)).collider) || IsCharacter(((RaycastHit)(ref val2)).collider) || ((RaycastHit)(ref val2)).collider is TerrainCollider)
				{
					continue;
				}
				Bounds bounds = ((RaycastHit)(ref val2)).collider.bounds;
				if (((Bounds)(ref bounds)).max.y < num + BikeConfig.SmallObstacleHeight(smallObstacleHeight))
				{
					continue;
				}
				Component val3 = FindDestructible(((RaycastHit)(ref val2)).collider);
				if ((Object)(object)val3 == (Object)null || (s_nextSmash.TryGetValue(val3, out var value) && Time.time < value))
				{
					continue;
				}
				s_nextSmash[val3] = Time.time + 1f;
				try
				{
					HitData val4 = new HitData();
					val4.m_damage = new DamageTypes
					{
						m_blunt = 9999f,
						m_slash = 9999f,
						m_chop = 9999f,
						m_pickaxe = 9999f
					};
					val4.m_pushForce = 25f;
					val4.m_point = ((RaycastHit)(ref val2)).point;
					val4.m_dir = val;
					Destructible val5 = (Destructible)(object)((val3 is Destructible) ? val3 : null);
					if (val5 != null)
					{
						val5.Destroy(val4);
						continue;
					}
					WearNTear val6 = (WearNTear)(object)((val3 is WearNTear) ? val3 : null);
					if (val6 != null)
					{
						val6.Damage(val4);
						continue;
					}
					MineRock5 val7 = (MineRock5)(object)((val3 is MineRock5) ? val3 : null);
					if (val7 != null)
					{
						val7.Damage(val4);
						continue;
					}
					MineRock val8 = (MineRock)(object)((val3 is MineRock) ? val3 : null);
					if (val8 != null)
					{
						val8.Damage(val4);
						continue;
					}
					TreeBase val9 = (TreeBase)(object)((val3 is TreeBase) ? val3 : null);
					if (val9 != null)
					{
						val9.Damage(val4);
						continue;
					}
					TreeLog val10 = (TreeLog)(object)((val3 is TreeLog) ? val3 : null);
					if (val10 != null)
					{
						val10.Damage(val4);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = ValheimBikePlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("smash failed on " + ((Object)val3).name + ": " + ex.Message));
					}
				}
			}
			if (s_nextSmash.Count <= 64)
			{
				return;
			}
			List<Component> list = new List<Component>();
			foreach (Component key in s_nextSmash.Keys)
			{
				if ((Object)(object)key == (Object)null)
				{
					list.Add(key);
				}
			}
			foreach (Component item in list)
			{
				s_nextSmash.Remove(item);
			}
		}

		private void LaunchCharacters(Vector3 from, Vector3 delta)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0089: 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)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_012b: 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_0165: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: 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_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Abs(kinematicSpeed);
			if (!BikeConfig.SendEnemiesFlying(sendEnemiesFlying) || num < BikeConfig.EnemyLaunchMinSpeed(enemyLaunchMinSpeed) || ((Vector3)(ref delta)).sqrMagnitude < 1E-08f)
			{
				return;
			}
			Vector3 normalized = ((Vector3)(ref delta)).normalized;
			RaycastHit[] array = Physics.SphereCastAll(from + Vector3.up * (collisionRadius + 0.35f), 0.7f, normalized, ((Vector3)(ref delta)).magnitude + 0.7f, characterMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val = array[i];
				Character val2 = (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) ? ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>() : null);
				if ((Object)(object)val2 == (Object)null || IsOwnOrRider(((RaycastHit)(ref val)).collider) || (int)val2.m_faction == 0 || (s_nextLaunch.TryGetValue(val2, out var value) && Time.time < value))
				{
					continue;
				}
				s_nextLaunch[val2] = Time.time + 0.75f;
				try
				{
					float num2 = Mathf.Clamp(num / 9f, 0.6f, 2.2f);
					HitData val3 = new HitData();
					val3.m_damage = new DamageTypes
					{
						m_blunt = BikeConfig.EnemyHitDamage(enemyHitDamage) * num2
					};
					val3.m_pushForce = 15f * num2;
					val3.m_point = ((Component)val2).transform.position + Vector3.up * 0.5f;
					val3.m_dir = normalized;
					val2.ApplyDamage(val3, true, false, (DamageModifier)0);
					val2.Stagger(normalized);
					Rigidbody component = ((Component)val2).GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null)
					{
						float num3 = Random.Range(0.85f, 1.25f);
						if (Random.value < 0.2f)
						{
							num3 *= 1.7f;
						}
						Vector3 val4 = normalized * (num * 1.05f * num3) + Vector3.up * (Mathf.Min(5f + num * 0.55f, 13f) * (0.8f + 0.2f * num3));
						component.velocity = val4 * BikeConfig.EnemyLaunchPower(1f);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = ValheimBikePlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("enemy launch failed on " + ((Object)val2).name + ": " + ex.Message));
					}
				}
			}
			if (s_nextLaunch.Count <= 64)
			{
				return;
			}
			List<Character> list = new List<Character>();
			foreach (Character key in s_nextLaunch.Keys)
			{
				if ((Object)(object)key == (Object)null)
				{
					list.Add(key);
				}
			}
			foreach (Character item in list)
			{
				s_nextLaunch.Remove(item);
			}
		}

		private void StableMove()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_008f: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0791: Unknown result type (might be due to invalid IL or missing references)
			//IL_0797: Unknown result type (might be due to invalid IL or missing references)
			//IL_079c: Unknown result type (might be due to invalid IL or missing references)
			//IL_087f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0880: Unknown result type (might be due to invalid IL or missing references)
			//IL_0882: Unknown result type (might be due to invalid IL or missing references)
			//IL_0887: Unknown result type (might be due to invalid IL or missing references)
			//IL_088a: Unknown result type (might be due to invalid IL or missing references)
			//IL_088b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0808: Unknown result type (might be due to invalid IL or missing references)
			//IL_0819: Unknown result type (might be due to invalid IL or missing references)
			//IL_081e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a29: Unknown result type (might be due to invalid IL or missing references)
			//IL_09db: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a70: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a75: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a77: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a80: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a89: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a90: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a98: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aaf: Unknown result type (might be due to invalid IL or missing references)
			float fixedDeltaTime = Time.fixedDeltaTime;
			if (groundClearance < 0f)
			{
				groundClearance = MeasureGroundClearance();
			}
			Vector3 position = rb.position;
			Vector3 val = Vector3.ProjectOnPlane((ValidRotation(rb.rotation) ? rb.rotation : lastSafeRotation) * Vector3.forward, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			((Vector3)(ref val)).Normalize();
			if (!_initialised)
			{
				_heading = Mathf.Atan2(val.x, val.z) * 57.29578f;
				_pitchDeg = 0f;
				_smoothGroundY = position.y - groundClearance;
				_smoothFrontY = (_smoothRearY = position.y - groundClearance);
				_initialised = true;
			}
			float y;
			bool flag = SampleGround(position + val * wheelHalfBase, out y);
			float y2;
			bool flag2 = SampleGround(position - val * wheelHalfBase, out y2);
			float y3;
			bool flag3 = SampleGround(position, out y3);
			int num = 0;
			float num2 = 0f;
			if (flag)
			{
				num2 += y;
				num++;
			}
			if (flag2)
			{
				num2 += y2;
				num++;
			}
			float num3 = ((num > 0) ? (num2 / (float)num) : (flag3 ? y3 : _smoothGroundY));
			bool flag4 = num > 0 || flag3;
			float num4 = num3 + groundClearance;
			bool flag5 = flag4 && num4 > position.y - maxReconnectDrop;
			float num5 = WaterLevel();
			bool flag6 = !float.IsNaN(num5) && flag4 && num3 < num5 - deepWaterDepth;
			float num6 = 0f;
			if (_pendingHopSpeed > 0f)
			{
				num6 = _pendingHopSpeed;
				verticalSpeed = _pendingHopSpeed;
				_pendingHopSpeed = 0f;
				_inAir = true;
				_airPitchKick = hopPitchKick;
			}
			if (flag)
			{
				_smoothFrontY = Mathf.SmoothDamp(_smoothFrontY, y, ref _frontYVel, heightSmoothTime, float.PositiveInfinity, fixedDeltaTime);
			}
			if (flag2)
			{
				_smoothRearY = Mathf.SmoothDamp(_smoothRearY, y2, ref _rearYVel, heightSmoothTime, float.PositiveInfinity, fixedDeltaTime);
			}
			float num7 = 0f;
			if (_inAir)
			{
				_airPitchKick = Mathf.MoveTowards(_airPitchKick, 0f, hopPitchKick * 1.2f * fixedDeltaTime);
				num7 = Mathf.Clamp((0f - leanInput) * 22f + ((verticalSpeed > 0f) ? _airPitchKick : ((0f - _airPitchKick) * 0.4f)), -35f, 35f);
			}
			else if (flag && flag2 && flag5)
			{
				num7 = Mathf.Clamp(Mathf.Atan2(_smoothFrontY - _smoothRearY, wheelHalfBase * 2f) * 57.29578f, 0f - maxSlopeAngle, maxSlopeAngle);
			}
			_pitchDeg = Mathf.MoveTowardsAngle(_pitchDeg, num7, pitchSmoothSpeed * (_inAir ? 0.8f : 1f) * fixedDeltaTime);
			float num8 = BikeConfig.BaseSpeed(maxSpeed);
			float num9 = BikeConfig.CruiseMultiplier(1f);
			float num10 = BikeConfig.SprintMultiplier(sprintSpeedMultiplier);
			float num11 = BikeConfig.ReverseSpeed(maxReverseSpeed);
			float num12 = BikeConfig.Braking(braking);
			float num13 = num8 * (sprint ? num10 : num9);
			float num14 = ((throttle >= 0f) ? (throttle * num13) : (throttle * num11));
			if (_inAir)
			{
				num14 = kinematicSpeed + Mathf.Clamp(throttle, -0.35f, 0.6f) * 2.5f;
			}
			else if (flag6)
			{
				num14 = 0f;
			}
			else if (num14 > 0f && _pitchDeg > climbLimit)
			{
				float num15 = Mathf.InverseLerp(climbLimit, maxSlopeAngle, _pitchDeg);
				num14 *= Mathf.Clamp01(1f - 0.85f * num15);
			}
			bool flag7 = _wheelieDeg < -1f;
			float num16 = (_inAir ? 0f : (flag6 ? (num12 * 1.5f) : ((throttle == 0f) ? coasting : ((Mathf.Sign(num14) != Mathf.Sign(kinematicSpeed) && Mathf.Abs(kinematicSpeed) > 0.2f) ? (num12 * (flag7 ? 1.3f : 1f)) : (BikeConfig.Acceleration(acceleration) * (sprint ? BikeConfig.SprintAccelMultiplier(sprintAccelMultiplier) : 1f))))));
			kinematicSpeed = Mathf.MoveTowards(kinematicSpeed, num14, num16 * fixedDeltaTime);
			if (!_inAir && corneringDrag > 0f && Mathf.Abs(kinematicSpeed) > 0.1f)
			{
				kinematicSpeed *= Mathf.Clamp01(1f - corneringDrag * Mathf.Abs(_steerSmooth) * fixedDeltaTime);
			}
			if (Mathf.Abs(kinematicSpeed) < 0.02f)
			{
				kinematicSpeed = 0f;
			}
			float num17 = 0f;
			if (!_inAir && BikeConfig.Wheelies(fallback: true) && kinematicSpeed > wheelieMinSpeed)
			{
				if (leanInput < -0.3f && throttle > 0.01f)
				{
					num17 = maxWheelieAngle * Mathf.InverseLerp(0.3f, 1f, 0f - leanInput);
				}
				else if (leanInput > 0.3f && throttle < -0.01f)
				{
					num17 = (0f - maxStoppieAngle) * Mathf.InverseLerp(0.3f, 1f, leanInput);
				}
			}
			float num18 = ((Mathf.Abs(num17) > Mathf.Abs(_wheelieDeg)) ? wheelieRaiseSpeed : wheelieDropSpeed);
			_wheelieDeg = Mathf.MoveTowards(_wheelieDeg, num17, num18 * fixedDeltaTime);
			float num19 = wheelHalfBase * Mathf.Sin(Mathf.Abs(_wheelieDeg) * (MathF.PI / 180f));
			_steerSmooth = Mathf.SmoothDamp(_steerSmooth, steer, ref _steerVel, 0.12f, float.PositiveInfinity, fixedDeltaTime);
			float num20 = Mathf.Clamp(_steerSmooth, -1f, 1f);
			float num21 = Mathf.Max(0.01f, num8 * Mathf.Max(num9, num10));
			float num22 = Mathf.Lerp(1f, BikeConfig.HighSpeedSteer(highSpeedSteer), Mathf.Clamp01(Mathf.Abs(kinematicSpeed) / num21));
			if (_wheelieDeg > 1f)
			{
				num22 *= Mathf.Lerp(1f, 0.35f, _wheelieDeg / Mathf.Max(1f, maxWheelieAngle));
			}
			if (_inAir)
			{
				num22 *= 0.55f;
			}
			float num23 = ((Mathf.Abs(kinematicSpeed) < 0.15f) ? 1f : Mathf.Sign(kinematicSpeed));
			float num24 = num20 * BikeConfig.TurnRate(steerRate) * num22 * num23;
			_heading += num24 * fixedDeltaTime;
			YawRateDeg = num24;
			float num25 = 0f;
			Vector3 val2 = val * kinematicSpeed * fixedDeltaTime;
			if (BikeConfig.DestructionMode(fallback: false) && ((Vector3)(ref val2)).sqrMagnitude > 1E-08f && Mathf.Abs(kinematicSpeed) > 2.5f)
			{
				DestroyObstacles(position, val2);
			}
			if (((Vector3)(ref val2)).sqrMagnitude > 1E-08f && SweepBlocked(position, val2, out var allowed))
			{
				float num26 = Mathf.Abs(kinematicSpeed);
				bool num27 = num26 > 1f;
				val2 = ((Vector3)(ref val2)).normalized * Mathf.Max(0f, allowed);
				kinematicSpeed = 0f;
				if (num27 && obstacleJolt > 0f)
				{
					_pitchDeg = Mathf.Min(_pitchDeg + obstacleJolt, maxSlopeAngle);
				}
				float num28 = BikeConfig.CrashKnockOffSpeed(0f);
				if (BikeConfig.FallOffBike(fallback: false) && num28 > 0f && num26 >= num28)
				{
					num25 = num26;
				}
			}
			Vector3 val3 = position + val2;
			LaunchCharacters(position, val2);
			float num29 = 0f;
			if (_inAir)
			{
				verticalSpeed = Mathf.Max(verticalSpeed - gravity * fixedDeltaTime, 0f - maxFallSpeed);
				val3.y = position.y + verticalSpeed * fixedDeltaTime;
				if (flag4 && verticalSpeed <= 0f && val3.y <= num4)
				{
					num29 = Mathf.Max(0.01f, 0f - verticalSpeed);
					val3.y = num4;
					_smoothGroundY = num3;
					_groundYVel = 0f;
					if (flag)
					{
						_smoothFrontY = y;
					}
					if (flag2)
					{
						_smoothRearY = y2;
					}
					_frontYVel = (_rearYVel = 0f);
					verticalSpeed = 0f;
					_inAir = false;
					grounded = true;
				}
				else
				{
					grounded = false;
				}
			}
			else if (flag5)
			{
				float num30 = Mathf.Max(maxHeightSpeed, Mathf.Abs(kinematicSpeed) * 0.85f);
				_smoothGroundY = Mathf.SmoothDamp(_smoothGroundY, num3, ref _groundYVel, heightSmoothTime, num30, fixedDeltaTime);
				float num31 = _smoothGroundY + groundClearance + num19;
				val3.y = Mathf.MoveTowards(position.y, num31, num30 * fixedDeltaTime);
				verticalSpeed = 0f;
				grounded = true;
			}
			else
			{
				_inAir = true;
				verticalSpeed = Mathf.Max((0f - gravity) * fixedDeltaTime, 0f - maxFallSpeed);
				val3.y = position.y + verticalSpeed * fixedDeltaTime;
				grounded = false;
			}
			if (grounded)
			{
				_lastGroundedTime = Time.time;
			}
			Quaternion q = Quaternion.Euler(0f - (_pitchDeg + _wheelieDeg), _heading, 0f);
			if (Finite(val3) && ValidRotation(q))
			{
				q = Normalize(q);
				rb.MoveRotation(q);
				rb.MovePosition(val3);
				lastSafeRotation = q;
			}
			else
			{
				kinematicSpeed = 0f;
				verticalSpeed = 0f;
				ClearInput();
				rb.MoveRotation(lastSafeRotation);
				Debug.LogError((object)"ValheimBike: rejected invalid kinematic movement.", (Object)(object)this);
			}
			if (num6 > 0f)
			{
				this.Hopped?.Invoke(num6);
			}
			if (num29 > 0f)
			{
				this.Landed?.Invoke(num29);
			}
			if (num25 > 0f)
			{
				this.Crashed?.Invoke(num25);
			}
		}

		private void DynamicMove()
		{
			//IL_0014: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0088: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00c5: 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_00ee: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			if (rb.isKinematic)
			{
				return;
			}
			if (!Finite(rb.linearVelocity) || !Finite(rb.angularVelocity) || !ValidRotation(rb.rotation))
			{
				rb.linearVelocity = Vector3.zero;
				rb.angularVelocity = Vector3.zero;
				rb.rotation = lastSafeRotation;
				ClearInput();
				return;
			}
			lastSafeRotation = rb.rotation;
			Vector3 val = Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up);
			Vector3 val2 = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.1f)
			{
				val2 = ((Component)this).transform.forward;
			}
			float num = maxSpeed * (sprint ? sprintSpeedMultiplier : 1f);
			float num2 = Vector3.Dot(rb.linearVelocity, val2);
			float num3 = ((throttle >= 0f) ? (throttle * num) : (throttle * maxReverseSpeed));
			float num4 = acceleration * (sprint ? sprintAccelMultiplier : 1f);
			float num5 = ((throttle == 0f) ? coasting : ((Mathf.Sign(num3) != Mathf.Sign(num2) && Mathf.Abs(num2) > 0.2f) ? braking : num4));
			float num6 = Mathf.MoveTowards(num2, num3, num5 * Time.fixedDeltaTime);
			rb.AddForce(val2 * (num6 - num2), (ForceMode)2);
			rb.AddForce(-Vector3.Project(rb.linearVelocity, ((Component)this).transform.right) * lateralGrip, (ForceMode)5);
			float num7 = Mathf.Lerp(1f, highSpeedSteer, Mathf.Clamp01(Mathf.Abs(num2) / Mathf.Max(0.01f, maxSpeed)));
			float num8 = ((Mathf.Abs(num2) < 0.15f) ? 1f : Mathf.Sign(num2));
			Quaternion q = Quaternion.AngleAxis(steer * steerRate * num7 * num8 * Time.fixedDeltaTime, Vector3.up) * rb.rotation;
			if (ValidRotation(q))
			{
				rb.MoveRotation(Normalize(q));
			}
			Vector3 val3 = Vector3.Cross(((Component)this).transform.up, Vector3.up);
			rb.AddTorque(val3 * uprightStrength - Vector3.ProjectOnPlane(rb.angularVelocity, Vector3.up) * uprightDamping, (ForceMode)5);
		}

		private bool SampleGround(Vector3 probe, out float y)
		{
			//IL_000b: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_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_018f: 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_00e6: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_0171: 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)
			y = 0f;
			bool flag = false;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(probe.x, probe.y + groundClearance + 3f, probe.z);
			float num = groundClearance + 3f + groundProbeDepth;
			RaycastHit[] array = Physics.SphereCastAll(val, groundSampleRadius, Vector3.down, num, groundMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !(((RaycastHit)(ref val2)).distance <= 0f) && !IsOwnOrRider(((RaycastHit)(ref val2)).collider) && !IsCharacter(((RaycastHit)(ref val2)).collider))
				{
					float y2 = ((RaycastHit)(ref val2)).point.y;
					if (!flag || y2 > y)
					{
						y = y2;
						flag = true;
					}
				}
			}
			if (solidGroundMask != 0)
			{
				array = Physics.SphereCastAll(val, groundSampleRadius, Vector3.down, num, solidGroundMask, (QueryTriggerInteraction)1);
				for (int i = 0; i < array.Length; i++)
				{
					RaycastHit val3 = array[i];
					if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !(((RaycastHit)(ref val3)).distance <= 0f) && !IsOwnOrRider(((RaycastHit)(ref val3)).collider) && !IsCharacter(((RaycastHit)(ref val3)).collider) && !(((RaycastHit)(ref val3)).normal.y < 0.55f) && (!flag || ((RaycastHit)(ref val3)).point.y > y))
					{
						y = ((RaycastHit)(ref val3)).point.y;
						flag = true;
					}
				}
			}
			float num2 = TerrainHeight(probe);
			if (!float.IsNaN(num2))
			{
				if (!flag || num2 > y)
				{
					y = num2;
				}
				flag = true;
			}
			return flag;
		}

		private bool SweepBlocked(Vector3 from, Vector3 delta, out float allowed)
		{
			//IL_0014: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			allowed = ((Vector3)(ref delta)).magnitude;
			if (allowed < 1E-05f)
			{
				return false;
			}
			Vector3 val = delta / allowed;
			float num = from.y - groundClearance;
			float num2 = num + stepOverHeight + collisionRadius;
			RaycastHit[] array = Physics.SphereCastAll(new Vector3(from.x, num2, from.z), collisionRadius, val, allowed + collisionSkin, collisionMask, (QueryTriggerInteraction)1);
			bool result = false;
			float num3 = BikeConfig.SmallObstacleHeight(smallObstacleHeight);
			float num4 = BikeConfig.SmallObstacleWidth(smallObstacleWidth);
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val2 = array2[i];
				if ((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null || ((RaycastHit)(ref val2)).distance <= 0f || IsOwnOrRider(((RaycastHit)(ref val2)).collider) || IsCharacter(((RaycastHit)(ref val2)).collider) || ((RaycastHit)(ref val2)).collider is TerrainCollider)
				{
					continue;
				}
				Bounds bounds = ((RaycastHit)(ref val2)).collider.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				if (num4 > 0f && Mathf.Max(size.x, size.z) < num4)
				{
					continue;
				}
				bounds = ((RaycastHit)(ref val2)).collider.bounds;
				if (!(((Bounds)(ref bounds)).max.y < num + num3) && !((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Pickable>() != (Object)null) && (!BikeConfig.DestructionMode(fallback: false) || !((Object)(object)FindDestructible(((RaycastHit)(ref val2)).collider) != (Object)null)) && !(((RaycastHit)(ref val2)).point.y < num + stepOverHeight))
				{
					float num5 = ((RaycastHit)(ref val2)).distance - collisionSkin;
					if (num5 < allowed)
					{
						allowed = Mathf.Max(0f, num5);
						result = true;
					}
				}
			}
			return result;
		}

		private float MeasureGroundClearance()
		{
			//IL_0006: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0040: 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)
			float num = ((Component)this).transform.position.y;
			bool flag = false;
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val) && !val.isTrigger)
				{
					Bounds bounds;
					float num2;
					if (!flag)
					{
						bounds = val.bounds;
						num2 = ((Bounds)(ref bounds)).min.y;
					}
					else
					{
						float num3 = num;
						bounds = val.bounds;
						num2 = Mathf.Min(num3, ((Bounds)(ref bounds)).min.y);
					}
					num = num2;
					flag = true;
				}
			}
			if (!flag)
			{
				return 0f;
			}
			return Mathf.Clamp(((Component)this).transform.position.y - num, 0f, 1.5f);
		}

		private static float TerrainHeight(Vector3 p)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ZoneSystem instance = ZoneSystem.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return float.NaN;
				}
				float groundHeight = instance.GetGroundHeight(p);
				return (float.IsNaN(groundHeight) || float.IsInfinity(groundHeight)) ? float.NaN : groundHeight;
			}
			catch
			{
				return float.NaN;
			}
		}

		private static float WaterLevel()
		{
			try
			{
				ZoneSystem instance = ZoneSystem.instance;
				if ((Object)(object)instance != (Object)null)
				{
					return instance.m_waterLevel;
				}
			}
			catch
			{
			}
			return float.NaN;
		}

		private bool IsOwnOrRider(Collider c)
		{
			Transform transform = ((Component)c).transform;
			if (ownTransforms != null)
			{
				Transform[] array = ownTransforms;
				foreach (Transform val in array)
				{
					if ((Object)(object)val == (Object)(object)transform || (Object.op_Implicit((Object)(object)val) && transform.IsChildOf(val)))
					{
						return true;
					}
				}
			}
			if (riderColliders != null)
			{
				Collider[] array2 = riderColliders;
				for (int i = 0; i < array2.Length; i++)
				{
					if ((Object)(object)array2[i] == (Object)(object)c)
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool IsCharacter(Collider c)
		{
			if (characterMask != 0)
			{
				return (characterMask & (1 << ((Component)c).gameObject.layer)) != 0;
			}
			return false;
		}

		private static bool Finite(Vector3 v)
		{
			//IL_0000: 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_001a: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(v.x) && !float.IsInfinity(v.x) && !float.IsNaN(v.y) && !float.IsInfinity(v.y) && !float.IsNaN(v.z))
			{
				return !float.IsInfinity(v.z);
			}
			return false;
		}

		private static bool ValidRotation(Quaternion q)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0021: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			float num = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
			if (!float.IsNaN(num) && !float.IsInfinity(num) && num > 0.5f)
			{
				return num < 1.5f;
			}
			return false;
		}

		private static Quaternion Normalize(Quaternion q)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0021: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
			if (!(num > 0.0001f))
			{
				return Quaternion.identity;
			}
			return new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num);
		}
	}
	public sealed class BikeMountController : MonoBehaviour, Interactable, Hoverable
	{
		public Transform seatPoint;

		public Transform dismountPoint;

		public string hoverName = "Bicycle";

		public bool allowReverse = true;

		[Tooltip("Local offset from SeatPoint for where the rider's root is attached (bike space).")]
		public Vector3 seatOffset = new Vector3(0f, -0.55f, 0f);

		public bool hideWeaponsWhileRiding = true;

		[Header("Fallback keys (the BepInEx config overrides these in game)")]
		public KeyCode accelButton = (KeyCode)331;

		public KeyCode brakeButton = (KeyCode)330;

		public KeyCode hopButton = (KeyCode)332;

		public KeyCode dismountButton = (KeyCode)333;

		public KeyCode dismountKey = (KeyCode)101;

		public KeyCode hopKey = (KeyCode)32;

		public KeyCode radioNext = (KeyCode)110;

		public KeyCode radioOff = (KeyCode)98;

		public KeyCode radioNextButton = (KeyCode)335;

		public KeyCode radioOffButton = (KeyCode)334;

		public KeyCode radioVolumeDownKey = (KeyCode)91;

		public KeyCode radioVolumeUpKey = (KeyCode)93;

		[Header("Tap-to-sprint")]
		[Tooltip("A press shorter than this counts as a tap, not a hold.")]
		public float tapMaxHold = 0.25f;

		[Tooltip("Taps within this rolling window are remembered.")]
		public float tapWindow = 0.9f;

		[Tooltip("Taps inside the window needed to sprint.")]
		public int tapsToSprint = 2;

		[Tooltip("Trigger travel (0..1) that counts as pressed.")]
		[Range(0.05f, 0.95f)]
		public float triggerThreshold = 0.35f;

		private static readonly List<BikeMountController> s_all = new List<BikeMountController>();

		private static bool s_quitting;

		private const string RiderVar = "vbRider";

		private const string SpeedVar = "vbSpeed";

		private const string PedalVar = "vbPedal";

		private BikeController bike;

		private BikeRiderAnimation anim;

		private BikeAudio audioRig;

		private BikingRadio radio;

		private BikeVisualController visual;

		private ZNetView _znv;

		private Player rider;

		private Collider[] bikeCols;

		private Collider[] riderCols;

		private Transform seat;

		private bool attached;

		private float _syncTimer;

		private float _riderMissingSince = -1f;

		private readonly List<float> taps = new List<float>();

		private readonly bool[] accelWasDown = new bool[3];

		private readonly float[] accelPressedAt = new float[3] { -99f, -99f, -99f };

		private float mountedAt = -99f;

		private float dismountedAt = -99f;

		private bool hopWasHeld;

		private float hopPressedAt;

		private float hopCharge;

		private float lastCameraInput;

		public Player Rider => rider;

		public Transform AttachPoint
		{
			get
			{
				if (!attached)
				{
					return null;
				}
				return seat;
			}
		}

		public float HopCharge
		{
			get
			{
				if (!hopWasHeld)
				{
					return 0f;
				}
				return 0.35f + 0.65f * hopCharge;
			}
		}

		public static BikeMountController RiddenBy(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return null;
			}
			foreach (BikeMountController item in s_all)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.rider == (Object)(object)p)
				{
					return item;
				}
			}
			return null;
		}

		private void Awake()
		{
			bike = ((Component)this).GetComponent<BikeController>();
			anim = ((Component)this).GetComponent<BikeRiderAnimation>();
			audioRig = ((Component)this).GetComponent<BikeAudio>();
			radio = ((Component)this).GetComponent<BikingRadio>();
			visual = ((Component)this).GetComponent<BikeVisualController>();
			_znv = ((Component)this).GetComponent<ZNetView>();
			bikeCols = ((Component)this).GetComponentsInChildren<Collider>(true);
			seatPoint = Find(seatPoint, "SeatPoint");
			dismountPoint = Find(dismountPoint, "Dismount_Point", "DismountPoint");
			if (!Object.op_Implicit((Object)(object)bike))
			{
				Debug.LogError((object)"ValheimBike: missing BikeController", (Object)(object)this);
			}
			if (!Object.op_Implicit((Object)(object)seatPoint))
			{
				Debug.LogError((object)"ValheimBike: missing SeatPoint", (Object)(object)this);
			}
			if (!Object.op_Implicit((Object)(object)dismountPoint))
			{
				Debug.LogError((object)"ValheimBike: missing Dismount_Point", (Object)(object)this);
			}
		}

		private void OnEnable()
		{
			if (!s_all.Contains(this))
			{
				s_all.Add(this);
			}
			if ((Object)(object)bike != (Object)null)
			{
				bike.Crashed += OnBikeCrashed;
			}
		}

		private void OnDisable()
		{
			if ((Object)(object)bike != (Object)null)
			{
				bike.Crashed -= OnBikeCrashed;
			}
			Dismount(move: true);
			s_all.Remove(this);
		}

		private void OnDestroy()
		{
			Dismount(move: true);
			s_all.Remove(this);
		}

		private void OnApplicationQuit()
		{
			s_quitting = true;
		}

		private void Start()
		{
			//IL_0028: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_znv) || !_znv.IsValid() || !_znv.IsOwner())
			{
				return;
			}
			try
			{
				if (RiderId() != ZDOID.None)
				{
					_znv.GetZDO().Set("vbRider", ZDOID.None);
				}
			}
			catch
			{
			}
		}

		private Transform Seat()
		{
			//IL_0014: 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_0088: 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_008d: 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_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_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)seat == (Object)null)
			{
				seat = new GameObject("BikeAttachPoint").transform;
				seat.SetParent(((Component)this).transform, false);
			}
			Transform val = ((Object.op_Implicit((Object)(object)visual) && Object.op_Implicit((Object)(object)visual.LeanPivot)) ? visual.LeanPivot : ((Component)this).transform);
			Vector3 val2 = (Object.op_Implicit((Object)(object)seatPoint) ? val.InverseTransformPoint(seatPoint.position) : Vector3.zero);
			seat.localPosition = val2 + seatOffset;
			seat.localRotation = Quaternion.identity;
			return seat;
		}

		private static bool Key(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)k != 0)
			{
				return ZInput.GetKey(k, false);
			}
			return false;
		}

		private static bool KeyDown(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)k != 0)
			{
				return ZInput.GetKeyDown(k, false);
			}
			return false;
		}

		private static bool GameTakesInput()
		{
			if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
			{
				return false;
			}
			if (Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible())
			{
				return false;
			}
			if (InventoryGui.IsVisible() || Minimap.IsOpen() || StoreGui.IsVisible())
			{
				return false;
			}
			if (GameCamera.InFreeFly() || Hud.InRadial())
			{
				return false;
			}
			return true;
		}

		private void Update()
		{
			//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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: