Decompiled source of BetterAutoRun v2.0.0

plugins\BetterAutoRun.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyTitle("BetterAutoRun")]
[assembly: AssemblyDescription("Smarter autorun and path following for Valheim")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BetterAutoRun")]
[assembly: AssemblyCopyright("Copyright © 2021-2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace BetterAutoRun
{
	internal sealed class AutoRunState
	{
		internal bool SprintEnabled { get; set; }

		internal bool SprintExhausted { get; set; }

		internal Vector3 InitialMoveDirection { get; set; } = Vector3.zero;

		internal float PathDirectionOverrideUntil { get; set; }

		internal float WaterHeight { get; set; }

		internal LiquidVolume LiquidVolume { get; set; }

		internal Vector3 LastPosition { get; set; } = Vector3.zero;

		internal bool MovementControlActive { get; set; }

		internal float EvadeJumpAllowedAt { get; set; }

		internal GroundType StartGroundType { get; set; } = GroundType.Unknown;

		internal Character Mount { get; set; }

		internal void Reset()
		{
			//IL_000f: 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)
			SprintEnabled = false;
			SprintExhausted = false;
			InitialMoveDirection = Vector3.zero;
			PathDirectionOverrideUntil = 0f;
			WaterHeight = 0f;
			LiquidVolume = null;
			LastPosition = Vector3.zero;
			MovementControlActive = false;
			EvadeJumpAllowedAt = 0f;
			StartGroundType = GroundType.Unknown;
			Mount = null;
		}
	}
	internal static class AutoSprintController
	{
		internal static void ApplyControls(Player player, ref bool run, bool autoRun)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			AutoRunState state = BetterAutoRun.State;
			if (state.SprintEnabled && (BetterAutoRun.GlobalSprintToggleConfig.Value || player.m_autoRun))
			{
				if (state.SprintExhausted && player.GetStamina() >= ((Character)player).GetMaxStamina())
				{
					state.SprintExhausted = false;
				}
				if (!state.SprintExhausted && player.GetStamina() > BetterAutoRun.StaminaMinThresholdConfig.Value)
				{
					run = true;
				}
				else
				{
					state.SprintExhausted = true;
				}
			}
			if (autoRun && state.InitialMoveDirection == Vector3.zero)
			{
				state.InitialMoveDirection = ((Character)player).GetLookDir();
				state.PathDirectionOverrideUntil = Time.time + (float)BetterAutoRun.PathDirectionOverrideDurationMillisConfig.Value / 1000f;
			}
			else if (!autoRun && !player.m_autoRun && !BetterAutoRun.IsRiding())
			{
				state.InitialMoveDirection = Vector3.zero;
				state.LastPosition = Vector3.zero;
			}
		}

		internal static void HandleToggle(Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = BetterAutoRun.AutoSprintShortcut.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown() || (!BetterAutoRun.GlobalSprintToggleConfig.Value && !player.m_autoRun))
			{
				return;
			}
			AutoRunState state = BetterAutoRun.State;
			if (state.SprintEnabled && state.SprintExhausted)
			{
				state.SprintExhausted = false;
				return;
			}
			state.SprintEnabled = !state.SprintEnabled;
			if (!state.SprintEnabled)
			{
				state.SprintExhausted = false;
			}
		}
	}
	internal enum GroundType
	{
		Terrain,
		Path,
		Unknown
	}
	[BepInPlugin("org.bepinex.plugins.bid.betterautorun", "BetterAutoRun", "2.0.0")]
	internal class BetterAutoRun : BaseUnityPlugin
	{
		public const string PluginGUID = "org.bepinex.plugins.bid.betterautorun";

		public const string PluginName = "BetterAutoRun";

		public const string PluginVersion = "2.0.0";

		private static readonly AutoRunState RuntimeState = new AutoRunState();

		private readonly Harmony harmony = new Harmony("org.bepinex.plugins.bid.betterautorun");

		private DebugRenderer debugRenderer;

		private PathScanDiagnostics diagnostics;

		private PathScanner pathScanner;

		private RidingController ridingController;

		private Shader legacyShader;

		private Material lineMaterial;

		private float updateTimer;

		public static ConfigEntry<bool> GlobalSprintToggleConfig;

		public static ConfigEntry<bool> KeepAutoRunOnJumpConfig;

		public static ConfigEntry<float> StaminaMinThresholdConfig;

		public static ConfigEntry<int> UpdateTimeMillisConfig;

		public static ConfigEntry<int> MaxAngleConfig;

		public static ConfigEntry<int> NumAnglesConfig;

		public static ConfigEntry<int> PathPointsConfig;

		public static ConfigEntry<float> PathToleranceConfig;

		public static ConfigEntry<float> MaxInclineConfig;

		public static ConfigEntry<bool> PavedOnlyConfig;

		public static ConfigEntry<bool> EnabledConfig;

		public static ConfigEntry<bool> VisualDebugConfig;

		public static ConfigEntry<float> HeightmapSearchRadiusConfig;

		public static ConfigEntry<float> RaycastHeightConfig;

		public static ConfigEntry<float> CollisionHeightIncreaseConfig;

		public static ConfigEntry<float> CollisionRayLengthDownConfig;

		public static ConfigEntry<float> NearCollisionDetectionAngleConfig;

		public static ConfigEntry<float> NearCollisionCorrectionAngleConfig;

		public static ConfigEntry<float> NearCollisionDetectionLengthScaleConfig;

		public static ConfigEntry<float> RidingDistanceFactorConfig;

		public static ConfigEntry<bool> NearCollisionDetectionEnabledConfig;

		public static ConfigEntry<bool> EvadeJumpEnabledConfig;

		public static ConfigEntry<int> EvadeJumpGracePeriodMillisConfig;

		public static ConfigEntry<float> EvadeJumpMovementThresholdConfig;

		public static ConfigEntry<int> PathDirectionOverrideDurationMillisConfig;

		public static ConfigEntry<KeyboardShortcut> AutoSprintShortcut;

		internal static AutoRunState State => RuntimeState;

		internal static bool IsEnabled
		{
			get
			{
				if (EnabledConfig != null)
				{
					return EnabledConfig.Value;
				}
				return false;
			}
		}

		internal static bool IsRiding(IDoodadController controller = null)
		{
			if (controller == null)
			{
				Player localPlayer = Player.m_localPlayer;
				controller = (((Object)(object)localPlayer == (Object)null) ? null : localPlayer.GetDoodadController());
			}
			return controller is Sadle;
		}

		private void Awake()
		{
			//IL_0030: 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_004a: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterAutoRun 2.0.0 loaded");
			CreateConfigValues();
			AutoSprintShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Client config", "AutoSprint", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), new ConfigDescription("Key used to toggle automatic sprinting", (AcceptableValueBase)null, Array.Empty<object>()));
			debugRenderer = new DebugRenderer();
			diagnostics = new PathScanDiagnostics(debugRenderer);
			pathScanner = new PathScanner(RuntimeState, diagnostics);
			ridingController = new RidingController(RuntimeState);
			harmony.PatchAll();
		}

		private void OnDestroy()
		{
			RuntimeState.Reset();
			if (debugRenderer != null)
			{
				debugRenderer.Dispose();
			}
			if ((Object)(object)lineMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)lineMaterial);
				lineMaterial = null;
			}
			harmony.UnpatchSelf();
		}

		private void Update()
		{
			//IL_00b0: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				debugRenderer.BeginFrame();
				RuntimeState.Reset();
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (VisualDebugConfig.Value && (Object)(object)lineMaterial == (Object)null)
			{
				TryInitializeLineMaterial();
			}
			else if (!VisualDebugConfig.Value)
			{
				debugRenderer.BeginFrame();
			}
			bool flag = localPlayer.m_autoRun || IsRiding(localPlayer.GetDoodadController());
			if (((Character)localPlayer).IsDebugFlying() || !flag)
			{
				RuntimeState.MovementControlActive = false;
				return;
			}
			if (!RuntimeState.MovementControlActive)
			{
				RuntimeState.MovementControlActive = true;
				RuntimeState.LastPosition = Vector3.zero;
				RuntimeState.EvadeJumpAllowedAt = Time.time + (float)EvadeJumpGracePeriodMillisConfig.Value / 1000f;
			}
			if (Input.GetMouseButton(1))
			{
				RuntimeState.InitialMoveDirection = ((Character)localPlayer).GetLookDir();
				RuntimeState.PathDirectionOverrideUntil = Time.time + (float)PathDirectionOverrideDurationMillisConfig.Value / 1000f;
			}
			updateTimer -= Time.deltaTime;
			if (!(updateTimer >= 0f))
			{
				if (VisualDebugConfig.Value)
				{
					debugRenderer.BeginFrame();
				}
				pathScanner.RefreshEnvironment(((Component)localPlayer).transform.position);
				JumpIfStuck(localPlayer);
				Vector3 moveDirection = pathScanner.CalculateMoveDirection(localPlayer);
				ridingController.ApplyMoveDirection(localPlayer, moveDirection);
				if (VisualDebugConfig.Value)
				{
					diagnostics.Draw();
				}
				updateTimer = (float)UpdateTimeMillisConfig.Value / 1000f;
				RuntimeState.LastPosition = ((Component)localPlayer).transform.position;
			}
		}

		private void JumpIfStuck(Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!(RuntimeState.LastPosition == Vector3.zero) && !(Time.time < RuntimeState.EvadeJumpAllowedAt))
			{
				Vector3 val = RuntimeState.LastPosition - ((Component)player).transform.position;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				float value = EvadeJumpMovementThresholdConfig.Value;
				if (EvadeJumpEnabledConfig.Value && sqrMagnitude < value * value && player.GetStamina() > StaminaMinThresholdConfig.Value)
				{
					((Character)player).Jump(true);
				}
			}
		}

		private void TryInitializeLineMaterial()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			legacyShader = Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply");
			if ((Object)(object)legacyShader == (Object)null)
			{
				Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
				foreach (Shader val in array)
				{
					if (((Object)val).name == "Legacy Shaders/Particles/Alpha Blended Premultiply")
					{
						legacyShader = val;
						break;
					}
				}
			}
			if ((Object)(object)legacyShader != (Object)null)
			{
				lineMaterial = new Material(legacyShader);
				debugRenderer.SetMaterial(lineMaterial);
			}
		}

		private void CreateConfigValues()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Expected O, but got Unknown
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Expected O, but got Unknown
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Expected O, but got Unknown
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Expected O, but got Unknown
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Expected O, but got Unknown
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Expected O, but got Unknown
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Expected O, but got Unknown
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Expected O, but got Unknown
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Expected O, but got Unknown
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Expected O, but got Unknown
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Expected O, but got Unknown
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			GlobalSprintToggleConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "GlobalSprintToggle", false, new ConfigDescription("Only sprint in autorun mode, or also in normal run mode (global)", (AcceptableValueBase)null, Array.Empty<object>()));
			KeepAutoRunOnJumpConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "KeepAutoRunOnJump", true, new ConfigDescription("Keep autorun enabled when the player presses jump", (AcceptableValueBase)null, Array.Empty<object>()));
			StaminaMinThresholdConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "StaminaMinThreshold", 30f, new ConfigDescription("Stop sprinting if stamina is below this value", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 250f), Array.Empty<object>()));
			UpdateTimeMillisConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "UpdateMillis", 100, new ConfigDescription("Update direction every x milliseconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000), Array.Empty<object>()));
			MaxAngleConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "MaxAngle", 90, new ConfigDescription("Max angle to look for a path", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 180), Array.Empty<object>()));
			NumAnglesConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "NumAngles", 10, new ConfigDescription("Number of angles to check a path between current forward direction and MaxAngle", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 36), Array.Empty<object>()));
			PathPointsConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "PathPoints", 10, new ConfigDescription("Number of one-metre path samples to check per angle", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			PathToleranceConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "PathTolerance", 0.3f, new ConfigDescription("Tolerance a point is still considered a path (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MaxInclineConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "MaxInclineRatio", 1f, new ConfigDescription("Maximum ratio forward/height", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			PavedOnlyConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "PavedOnly", false, new ConfigDescription("Only consider paved roads as paths", (AcceptableValueBase)null, Array.Empty<object>()));
			EnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "enabled", true, new ConfigDescription("Enable or disable the mod", (AcceptableValueBase)null, Array.Empty<object>()));
			VisualDebugConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "VisualDebug", false, new ConfigDescription("Enable or disable visual debugging", (AcceptableValueBase)null, Array.Empty<object>()));
			HeightmapSearchRadiusConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "HeightmapSearchRadius", 0.5f, new ConfigDescription("Radius to look for heightmaps (internal)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			RaycastHeightConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "RaycastHeight", 0.5f, new ConfigDescription("Height of the raycast for horizontal collision detection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			CollisionHeightIncreaseConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "CollissionHeightIncrease", 1.25f, new ConfigDescription("Height added to the vertical collision detection line", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			CollisionRayLengthDownConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "CollissonRayLengthDown", 4f, new ConfigDescription("Length of the downward collision detection raycast", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			NearCollisionDetectionAngleConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "NearCollissionDetectionAngle", 30f, new ConfigDescription("Angle for near collision detection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), Array.Empty<object>()));
			NearCollisionCorrectionAngleConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "NearCollissionCorrectionAngle", 30f, new ConfigDescription("Angle for near collision detection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), Array.Empty<object>()));
			NearCollisionDetectionLengthScaleConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "NearCollissionDetectionLengthScale", 1f, new ConfigDescription("Scale factor for the near collision detection ray", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>()));
			RidingDistanceFactorConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "RidingDistanceFactor", 2f, new ConfigDescription("Multiply the number of path samples checked while riding", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 5f), Array.Empty<object>()));
			NearCollisionDetectionEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "NearCollissionDetectionEnabled", true, new ConfigDescription("Correct movement in case of near collission detection", (AcceptableValueBase)null, Array.Empty<object>()));
			EvadeJumpEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Client config", "EvadeJumpEnabled", true, new ConfigDescription("Jump if stuck somewhere", (AcceptableValueBase)null, Array.Empty<object>()));
			EvadeJumpGracePeriodMillisConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "EvadeJumpGracePeriodMillis", 500, new ConfigDescription("Delay before evade jump detection starts after automatic movement begins", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3000), Array.Empty<object>()));
			EvadeJumpMovementThresholdConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Client config", "EvadeJumpMovementThreshold", 0.05f, new ConfigDescription("Minimum movement between checks to avoid an evade jump, in metres", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>()));
			PathDirectionOverrideDurationMillisConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Client config", "PathDirectionOverrideDurationMillis", 3000, new ConfigDescription("How long the selected direction is preferred on paths after a mouse input", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30000), Array.Empty<object>()));
		}
	}
	internal sealed class DebugRenderer
	{
		private readonly List<LineRenderer> lineRenderers = new List<LineRenderer>();

		private Material material;

		private int activeLineCount;

		internal void SetMaterial(Material lineMaterial)
		{
			material = lineMaterial;
		}

		internal void BeginFrame()
		{
			activeLineCount = 0;
			foreach (LineRenderer lineRenderer in lineRenderers)
			{
				((Renderer)lineRenderer).enabled = false;
			}
		}

		internal void DrawLine(Vector3 start, Vector3 end, Color color, float width = 0.02f)
		{
			//IL_0022: 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_004f: 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)
			if (!((Object)(object)material == (Object)null))
			{
				LineRenderer lineRenderer = GetLineRenderer();
				((Renderer)lineRenderer).material = material;
				lineRenderer.startColor = color;
				lineRenderer.endColor = color;
				lineRenderer.startWidth = width;
				lineRenderer.endWidth = width;
				lineRenderer.positionCount = 2;
				lineRenderer.useWorldSpace = true;
				lineRenderer.SetPosition(0, start);
				lineRenderer.SetPosition(1, end);
			}
		}

		internal void DrawPathScans(SortedList<float, SortedList<int, PathSampleDebugInfo>> scans, Vector3 startPoint, float raycastHeight, bool hasSelectedAngle, float selectedAngle, SortedList<float, bool> nearCollisionCandidates)
		{
			//IL_0043: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<float, SortedList<int, PathSampleDebugInfo>> scan in scans)
			{
				bool flag = hasSelectedAngle && Mathf.Abs(scan.Key - selectedAngle) < 0.001f;
				bool value;
				bool flag2 = nearCollisionCandidates.TryGetValue(scan.Key, out value);
				Vector3 start = startPoint;
				start.y += raycastHeight;
				foreach (KeyValuePair<int, PathSampleDebugInfo> item in scan.Value)
				{
					PathSampleDebugInfo value2 = item.Value;
					Vector3 target = value2.Target;
					if (!value2.Collision)
					{
						target.y += raycastHeight;
					}
					Color color = Color.green;
					float width = 0.02f;
					if (value2.ColorError)
					{
						color = Color.red;
					}
					if (value2.SlopeError)
					{
						color = Color.magenta;
					}
					if (value2.Collision)
					{
						color = Color.blue;
					}
					if (value2.IsNearCollisionCheck)
					{
						color = (Color)(value2.Collision ? new Color(1f, 0.271f, 0f) : Color.yellow);
						if (value2.Collision)
						{
							width = 0.04f;
						}
					}
					if (flag2)
					{
						color = (value ? new Color(0.1f, 1f, 0.8f) : new Color(1f, 0.1f, 0.05f));
						width = 0.045f;
					}
					if (flag)
					{
						((Color)(ref color))..ctor(1f, 0.85f, 0.05f);
						width = 0.065f;
					}
					DrawLine(start, target, color, width);
					start = target;
				}
			}
		}

		internal void Dispose()
		{
			foreach (LineRenderer lineRenderer in lineRenderers)
			{
				if ((Object)(object)lineRenderer != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)lineRenderer).gameObject);
				}
			}
			lineRenderers.Clear();
		}

		private LineRenderer GetLineRenderer()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			LineRenderer val;
			if (activeLineCount < lineRenderers.Count)
			{
				val = lineRenderers[activeLineCount];
			}
			else
			{
				val = new GameObject("BetterAutoRun Debug Line").AddComponent<LineRenderer>();
				lineRenderers.Add(val);
			}
			activeLineCount++;
			((Renderer)val).enabled = true;
			return val;
		}
	}
	internal sealed class PathScanner
	{
		private static readonly string[] DefaultLayers = new string[9] { "piece", "terrain", "piece_nonsolid", "static_solid", "Default", "vehicle", "pathblocker", "character", "Default_small" };

		private static readonly string[] RidingLayers = new string[7] { "piece", "terrain", "piece_nonsolid", "static_solid", "Default", "vehicle", "pathblocker" };

		private readonly AutoRunState state;

		private readonly PathScanDiagnostics diagnostics;

		private readonly int defaultLayerMask;

		private readonly int ridingLayerMask;

		private readonly int waterLayerMask;

		private readonly List<Heightmap> heightmaps = new List<Heightmap>();

		private readonly Collider[] waterColliders = (Collider[])(object)new Collider[32];

		internal PathScanner(AutoRunState state, PathScanDiagnostics diagnostics)
		{
			this.state = state;
			this.diagnostics = diagnostics;
			defaultLayerMask = LayerMask.GetMask(DefaultLayers);
			ridingLayerMask = LayerMask.GetMask(RidingLayers);
			waterLayerMask = LayerMask.GetMask(new string[1] { "WaterVolume" });
		}

		internal void RefreshEnvironment(Vector3 position)
		{
			//IL_0007: 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)
			state.WaterHeight = GetWaterHeight(position);
			state.LiquidVolume = FindLiquidVolume(position);
		}

		internal Vector3 CalculateMoveDirection(Player player)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Vector3 lookDirection;
			Vector3 startPoint = GetStartPoint(player, out lookDirection);
			Vector3 val = lookDirection;
			int num = -1;
			float angle = 0f;
			PathScanResult pathScanResult = null;
			int num2 = BetterAutoRun.PathPointsConfig.Value;
			SortedList<float, PathScanResult> sortedList = new SortedList<float, PathScanResult>();
			diagnostics.BeginScan(startPoint);
			if (BetterAutoRun.IsRiding(player.GetDoodadController()))
			{
				num2 = (int)((float)num2 * BetterAutoRun.RidingDistanceFactorConfig.Value);
			}
			float num3 = (float)BetterAutoRun.MaxAngleConfig.Value / (float)BetterAutoRun.NumAnglesConfig.Value;
			for (int i = 0; i < BetterAutoRun.NumAnglesConfig.Value; i++)
			{
				for (int j = -1; j <= 1; j += 2)
				{
					float num4 = (float)i * num3 * (float)j;
					Vector3 val2 = RotateDirection(lookDirection, num4);
					diagnostics.PrepareAngle(num4);
					PathScanResult pathScanResult2 = ScanDirection(player, startPoint, val2, num4);
					sortedList.Add(num4, pathScanResult2);
					if (pathScanResult2.TraversablePoints > num)
					{
						num = pathScanResult2.TraversablePoints;
						val = val2;
						angle = num4;
						pathScanResult = pathScanResult2;
						if (num >= num2)
						{
							break;
						}
					}
					if (i == 0)
					{
						break;
					}
				}
				if (num >= num2)
				{
					break;
				}
			}
			if (val == lookDirection && pathScanResult != null && pathScanResult.BlockingReason == PathBlockReason.InvalidGround)
			{
				ApplyNearCollisionCorrection(player, startPoint, val, angle, num3, sortedList, out var _);
				diagnostics.MarkSelectedAngle(angle);
				return lookDirection;
			}
			float selectedAngle2;
			Vector3 result = ApplyNearCollisionCorrection(player, startPoint, val, angle, num3, sortedList, out selectedAngle2);
			diagnostics.MarkSelectedAngle(selectedAngle2);
			return result;
		}

		private PathScanResult ScanDirection(Player player, Vector3 startPoint, Vector3 direction, float angle, int maxPointsOverride = 0, bool isNearCollisionCheck = false)
		{
			//IL_0047: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007a: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			int num = maxPointsOverride;
			if (num == 0)
			{
				num = BetterAutoRun.PathPointsConfig.Value;
				if (BetterAutoRun.IsRiding(player.GetDoodadController()) && !isNearCollisionCheck)
				{
					num = (int)((float)num * BetterAutoRun.RidingDistanceFactorConfig.Value);
				}
			}
			float num2 = (isNearCollisionCheck ? BetterAutoRun.NearCollisionDetectionLengthScaleConfig.Value : 1f);
			Vector3 lastPosition = startPoint;
			float y = startPoint.y;
			float lastHeight = y;
			float num3 = 0f;
			PathScanResult pathScanResult = new PathScanResult();
			for (int i = 1; i <= num; i++)
			{
				Vector3 val = startPoint + direction * ((float)i * num2);
				y = (val.y += num3);
				PathSampleDebugInfo pathSampleDebugInfo = new PathSampleDebugInfo
				{
					IsNearCollisionCheck = isNearCollisionCheck,
					Target = val,
					TargetHeight = y
				};
				if (CollisionDetected(player, val, lastHeight, y, lastPosition, out var heightDifference, pathSampleDebugInfo, isNearCollisionCheck))
				{
					if (!pathSampleDebugInfo.SlopeError && !pathSampleDebugInfo.ColorError)
					{
						pathSampleDebugInfo.Collision = true;
					}
					pathScanResult.LastSample = pathSampleDebugInfo;
					pathScanResult.BlockingReason = GetBlockingReason(pathSampleDebugInfo);
					diagnostics.RecordSample(angle, i, pathSampleDebugInfo);
					break;
				}
				pathSampleDebugInfo.Target += Vector3.up * heightDifference;
				y += heightDifference;
				num3 += heightDifference;
				pathScanResult.TraversablePoints++;
				pathScanResult.LastSample = pathSampleDebugInfo;
				diagnostics.RecordSample(angle, i, pathSampleDebugInfo);
				lastHeight = y;
				lastPosition = val;
			}
			return pathScanResult;
		}

		private bool CollisionDetected(Player player, Vector3 targetPosition, float lastHeight, float targetHeight, Vector3 lastPosition, out float heightDifference, PathSampleDebugInfo sample, bool isNearCollisionCheck)
		{
			//IL_0044: 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)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0056: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00f4: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			int num = (BetterAutoRun.IsRiding(player.GetDoodadController()) ? ridingLayerMask : defaultLayerMask);
			heightDifference = 0f;
			float value = BetterAutoRun.RaycastHeightConfig.Value;
			lastPosition.y = lastHeight + value;
			targetPosition.y = targetHeight + value;
			Vector3 val = targetPosition - lastPosition;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num2 = Vector3.Distance(lastPosition, targetPosition);
			RaycastHit val2 = default(RaycastHit);
			bool flag = Physics.Raycast(lastPosition, normalized, ref val2, num2, num);
			Vector3 val3 = (flag ? ((RaycastHit)(ref val2)).point : targetPosition);
			val3.y += BetterAutoRun.CollisionHeightIncreaseConfig.Value;
			val3 += normalized * 0.005f;
			RaycastHit val4 = default(RaycastHit);
			bool num3 = Physics.Raycast(val3, Vector3.down, ref val4, BetterAutoRun.CollisionRayLengthDownConfig.Value, num);
			diagnostics.RecordLine(val3, val3 + Vector3.down * BetterAutoRun.CollisionRayLengthDownConfig.Value);
			if (!num3)
			{
				sample.SlopeError = true;
				sample.Target += Vector3.down * BetterAutoRun.CollisionRayLengthDownConfig.Value;
				return true;
			}
			if (flag && ((RaycastHit)(ref val4)).point.y < ((RaycastHit)(ref val2)).point.y)
			{
				((RaycastHit)(ref val4)).point = val3;
			}
			heightDifference = ((RaycastHit)(ref val4)).point.y - (lastPosition.y - value);
			float num4 = (flag ? ((RaycastHit)(ref val2)).distance : num2);
			if ((((Component)((RaycastHit)(ref val4)).collider).gameObject.layer != 11 || !((Character)player).IsRunning() || heightDifference < -0.5f || isNearCollisionCheck) && heightDifference != 0f && num4 / Math.Abs(heightDifference) < BetterAutoRun.MaxInclineConfig.Value)
			{
				sample.Target = ((RaycastHit)(ref val4)).point;
				sample.TargetHeight = sample.Target.y;
				if (heightDifference < 0f)
				{
					sample.SlopeError = true;
				}
				return true;
			}
			if (((Component)((RaycastHit)(ref val4)).collider).gameObject.layer == 11)
			{
				Heightmap heightmap;
				Color color = (sample.TargetColor = GetHitColor(targetPosition, out heightmap));
				float num5 = default(float);
				Heightmap.GetHeight(targetPosition, ref num5);
				if ((Object)(object)heightmap != (Object)null && heightmap.GetLava(targetPosition) > 0.2f)
				{
					sample.ColorError = true;
					return true;
				}
				if (num5 <= GetLiquidHeight(targetPosition) || num5 + ((Character)player).m_swimDepth / 2f <= state.WaterHeight)
				{
					sample.ColorError = true;
					return true;
				}
				if (state.StartGroundType == GroundType.Path && !IsPath(color))
				{
					sample.ColorError = true;
					return true;
				}
				return false;
			}
			if ((Object)(object)((Component)((RaycastHit)(ref val4)).collider).gameObject.GetComponentInParent<Piece>() == (Object)null && state.StartGroundType == GroundType.Path)
			{
				sample.Target = ((RaycastHit)(ref val4)).point;
				sample.TargetHeight = sample.Target.y;
				sample.SlopeError = true;
				return true;
			}
			if (state.StartGroundType == GroundType.Terrain && !((Character)player).IsRunning())
			{
				sample.Target = ((RaycastHit)(ref val4)).point;
				sample.TargetHeight = sample.Target.y;
				sample.SlopeError = true;
				return true;
			}
			return false;
		}

		private Vector3 GetStartPoint(Player player, out Vector3 lookDirection)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			state.StartGroundType = GroundType.Unknown;
			Vector3 position = ((Component)player).transform.position;
			lookDirection = ((Component)player).transform.forward;
			IDoodadController doodadController = player.GetDoodadController();
			if (BetterAutoRun.IsRiding(doodadController))
			{
				Component controlledComponent = doodadController.GetControlledComponent();
				if ((Object)(object)controlledComponent != (Object)null)
				{
					position = controlledComponent.transform.position;
					lookDirection = controlledComponent.transform.forward;
				}
			}
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(position + Vector3.up * 0.1f, Vector3.down, ref val, BetterAutoRun.CollisionRayLengthDownConfig.Value, defaultLayerMask))
			{
				position.y = ((RaycastHit)(ref val)).point.y;
				if (((Component)((RaycastHit)(ref val)).collider).gameObject.layer == 11)
				{
					state.StartGroundType = GroundType.Terrain;
					if (IsPath(GetHitColor(((RaycastHit)(ref val)).point, out var _)))
					{
						state.StartGroundType = GroundType.Path;
					}
				}
				else if ((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>() != (Object)null)
				{
					state.StartGroundType = GroundType.Path;
				}
			}
			bool flag = Time.time <= state.PathDirectionOverrideUntil;
			if (state.InitialMoveDirection != Vector3.zero && (state.StartGroundType == GroundType.Terrain || flag))
			{
				lookDirection = state.InitialMoveDirection;
			}
			lookDirection.y = 0f;
			((Vector3)(ref lookDirection)).Normalize();
			return position;
		}

		private Vector3 ApplyNearCollisionCorrection(Player player, Vector3 startPoint, Vector3 direction, float angle, float angleIncrement, SortedList<float, PathScanResult> regularResults, out float selectedAngle)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00e2: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			selectedAngle = angle;
			if (!BetterAutoRun.NearCollisionDetectionEnabledConfig.Value)
			{
				return direction;
			}
			float num = 0f - BetterAutoRun.NearCollisionDetectionAngleConfig.Value;
			float value = BetterAutoRun.NearCollisionDetectionAngleConfig.Value;
			Vector3 direction2 = RotateDirection(direction, num);
			Vector3 direction3 = RotateDirection(direction, value);
			float angle2 = angle + num;
			float angle3 = angle + value;
			diagnostics.PrepareAngle(angle2);
			diagnostics.PrepareAngle(angle3);
			PathScanResult pathScanResult = ScanDirection(player, startPoint, direction2, angle2, 1, isNearCollisionCheck: true);
			PathScanResult pathScanResult2 = ScanDirection(player, startPoint, direction3, angle3, 1, isNearCollisionCheck: true);
			if (pathScanResult.TraversablePoints == 0 && pathScanResult2.TraversablePoints > 0)
			{
				return SelectAdjacentRegularPath(player, startPoint, direction, angle, BetterAutoRun.NearCollisionCorrectionAngleConfig.Value, 1f, regularResults, out selectedAngle);
			}
			if (pathScanResult2.TraversablePoints == 0 && pathScanResult.TraversablePoints > 0)
			{
				return SelectAdjacentRegularPath(player, startPoint, direction, angle, BetterAutoRun.NearCollisionCorrectionAngleConfig.Value, -1f, regularResults, out selectedAngle);
			}
			return direction;
		}

		private Vector3 SelectAdjacentRegularPath(Player player, Vector3 startPoint, Vector3 direction, float angle, float angleIncrement, float side, SortedList<float, PathScanResult> regularResults, out float selectedAngle)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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)
			selectedAngle = angle;
			float num = angle + angleIncrement * side;
			if (num < (float)(-BetterAutoRun.MaxAngleConfig.Value) || num > (float)BetterAutoRun.MaxAngleConfig.Value)
			{
				diagnostics.MarkNearCollisionCandidate(num, accepted: false);
				return direction;
			}
			PathScanResult pathScanResult = FindRegularResult(regularResults, num);
			if (pathScanResult == null)
			{
				Vector3 direction2 = RotateDirection(direction, angleIncrement * side);
				diagnostics.PrepareAngle(num);
				pathScanResult = ScanDirection(player, startPoint, direction2, num, 1);
			}
			bool flag = pathScanResult.TraversablePoints > 0;
			diagnostics.MarkNearCollisionCandidate(num, flag);
			if (!flag)
			{
				return direction;
			}
			selectedAngle = num;
			return RotateDirection(direction, angleIncrement * side);
		}

		private static PathScanResult FindRegularResult(SortedList<float, PathScanResult> regularResults, float angle)
		{
			foreach (KeyValuePair<float, PathScanResult> regularResult in regularResults)
			{
				if (Mathf.Abs(regularResult.Key - angle) < 0.001f)
				{
					return regularResult.Value;
				}
			}
			return null;
		}

		private Color GetHitColor(Vector3 point, out Heightmap heightmap)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0054: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			heightmaps.Clear();
			Heightmap.FindHeightmap(point, BetterAutoRun.HeightmapSearchRadiusConfig.Value, heightmaps);
			Color val = Heightmap.m_paintMaskNothing;
			heightmap = null;
			int num = default(int);
			int num2 = default(int);
			foreach (Heightmap heightmap2 in heightmaps)
			{
				heightmap2.WorldToVertex(point, ref num, ref num2);
				val = heightmap2.GetPaintMask(num, num2);
				heightmap = heightmap2;
				if (IsPath(val))
				{
					return val;
				}
			}
			return val;
		}

		private float GetWaterHeight(Vector3 position)
		{
			//IL_0000: 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)
			int num = Physics.OverlapSphereNonAlloc(position, 2f, waterColliders, waterLayerMask);
			for (int i = 0; i < num; i++)
			{
				WaterVolume component = ((Component)waterColliders[i]).GetComponent<WaterVolume>();
				if ((Object)(object)component != (Object)null)
				{
					return component.GetWaterSurface(position, 1f);
				}
			}
			return 0f;
		}

		private LiquidVolume FindLiquidVolume(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(position, 2f, waterColliders, waterLayerMask);
			for (int i = 0; i < num; i++)
			{
				Transform parent = ((Component)waterColliders[i]).transform.parent;
				LiquidVolume val = (((Object)(object)parent == (Object)null) ? null : ((Component)parent).GetComponentInChildren<LiquidVolume>());
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private float GetLiquidHeight(Vector3 position)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)state.LiquidVolume == (Object)null))
			{
				return state.LiquidVolume.GetSurface(position);
			}
			return 0f;
		}

		private static bool IsPath(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			if (ColorsAreEqual(color, Heightmap.m_paintMaskPaved))
			{
				return true;
			}
			if (!BetterAutoRun.PavedOnlyConfig.Value)
			{
				return ColorsAreEqual(color, Heightmap.m_paintMaskDirt);
			}
			return false;
		}

		private static bool ColorsAreEqual(Color first, Color second)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_004a: 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)
			float value = BetterAutoRun.PathToleranceConfig.Value;
			if (Mathf.Abs(first.r - second.r) <= value && Mathf.Abs(first.g - second.g) <= value && Mathf.Abs(first.b - second.b) <= value)
			{
				return Mathf.Abs(first.a - second.a) <= value;
			}
			return false;
		}

		private static Vector3 RotateDirection(Vector3 direction, float angle)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			Vector3 result = Quaternion.Euler(0f, angle, 0f) * direction;
			result.y = 0f;
			((Vector3)(ref result)).Normalize();
			return result;
		}

		private static PathBlockReason GetBlockingReason(PathSampleDebugInfo sample)
		{
			if (sample.ColorError)
			{
				return PathBlockReason.InvalidGround;
			}
			if (sample.SlopeError)
			{
				return PathBlockReason.Slope;
			}
			return PathBlockReason.Collision;
		}
	}
	internal sealed class PathScanDiagnostics
	{
		private struct DebugLine
		{
			internal readonly Vector3 Start;

			internal readonly Vector3 End;

			internal DebugLine(Vector3 start, Vector3 end)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Start = start;
				End = end;
			}
		}

		private readonly DebugRenderer renderer;

		private readonly SortedList<float, SortedList<int, PathSampleDebugInfo>> scans = new SortedList<float, SortedList<int, PathSampleDebugInfo>>();

		private readonly SortedList<float, bool> nearCollisionCandidates = new SortedList<float, bool>();

		private readonly List<DebugLine> lines = new List<DebugLine>();

		private Vector3 startPoint;

		private bool hasSelectedAngle;

		private float selectedAngle;

		private static bool Enabled
		{
			get
			{
				if (BetterAutoRun.VisualDebugConfig != null)
				{
					return BetterAutoRun.VisualDebugConfig.Value;
				}
				return false;
			}
		}

		internal PathScanDiagnostics(DebugRenderer renderer)
		{
			this.renderer = renderer;
		}

		internal void BeginScan(Vector3 scanStartPoint)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled)
			{
				startPoint = scanStartPoint;
				scans.Clear();
				nearCollisionCandidates.Clear();
				lines.Clear();
				hasSelectedAngle = false;
				selectedAngle = 0f;
			}
		}

		internal void PrepareAngle(float angle)
		{
			if (Enabled && !scans.ContainsKey(angle))
			{
				scans.Add(angle, new SortedList<int, PathSampleDebugInfo>());
			}
		}

		internal void RecordSample(float angle, int distance, PathSampleDebugInfo sample)
		{
			if (Enabled)
			{
				PrepareAngle(angle);
				SortedList<int, PathSampleDebugInfo> sortedList = scans[angle];
				if (sortedList.ContainsKey(distance))
				{
					sortedList.Remove(distance);
				}
				sortedList.Add(distance, sample);
			}
		}

		internal void RecordLine(Vector3 start, Vector3 end)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled)
			{
				lines.Add(new DebugLine(start, end));
			}
		}

		internal void MarkNearCollisionCandidate(float angle, bool accepted)
		{
			if (Enabled)
			{
				if (nearCollisionCandidates.ContainsKey(angle))
				{
					nearCollisionCandidates[angle] = accepted;
				}
				else
				{
					nearCollisionCandidates.Add(angle, accepted);
				}
			}
		}

		internal void MarkSelectedAngle(float angle)
		{
			if (Enabled)
			{
				hasSelectedAngle = true;
				selectedAngle = angle;
			}
		}

		internal void Draw()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled)
			{
				return;
			}
			foreach (DebugLine line in lines)
			{
				renderer.DrawLine(line.Start, line.End, Color.black);
			}
			renderer.DrawPathScans(scans, startPoint, BetterAutoRun.RaycastHeightConfig.Value, hasSelectedAngle, selectedAngle, nearCollisionCandidates);
		}
	}
	internal enum PathBlockReason
	{
		None,
		Collision,
		InvalidGround,
		Slope
	}
	internal sealed class PathSampleDebugInfo
	{
		internal Vector3 Target { get; set; }

		internal bool ColorError { get; set; }

		internal bool SlopeError { get; set; }

		internal Color TargetColor { get; set; }

		internal float TargetHeight { get; set; }

		internal bool Collision { get; set; }

		internal bool IsNearCollisionCheck { get; set; }
	}
	internal sealed class PathScanResult
	{
		internal int TraversablePoints { get; set; }

		internal PathBlockReason BlockingReason { get; set; }

		internal PathSampleDebugInfo LastSample { get; set; }
	}
	internal sealed class RidingController
	{
		private static readonly FieldInfo SaddleControlDirectionField = AccessTools.Field(typeof(Sadle), "m_controlDir");

		private readonly AutoRunState state;

		internal RidingController(AutoRunState state)
		{
			this.state = state;
		}

		internal void ApplyMoveDirection(Player player, Vector3 moveDirection)
		{
			//IL_0045: 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)
			state.Mount = null;
			IDoodadController doodadController = player.GetDoodadController();
			Sadle val = (Sadle)(object)((doodadController is Sadle) ? doodadController : null);
			if ((Object)(object)val != (Object)null)
			{
				state.Mount = val.GetCharacter();
				SaddleControlDirectionField.SetValue(val, moveDirection);
			}
			else
			{
				((Character)player).SetMoveDir(moveDirection);
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "org.bepinex.plugins.bid.betterautorun";

		public const string Name = "BetterAutoRun";

		public const string Version = "2.0.0";

		public const string AssemblyVersion = "2.0.0.0";
	}
}
namespace BetterAutoRun.Patches
{
	[HarmonyPatch(typeof(Player), "SetControls")]
	internal static class PlayerSetControlsPatch
	{
		private static void Prefix(Player __instance, ref bool run, bool autoRun, bool jump, out bool __state)
		{
			__state = (Object)(object)__instance == (Object)(object)Player.m_localPlayer && BetterAutoRun.IsEnabled && BetterAutoRun.KeepAutoRunOnJumpConfig.Value && __instance.m_autoRun && jump;
			if (BetterAutoRun.IsEnabled)
			{
				AutoSprintController.ApplyControls(__instance, ref run, autoRun);
			}
		}

		private static void Postfix(Player __instance, bool __state)
		{
			if (__state)
			{
				__instance.m_autoRun = true;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	internal static class PlayerUpdatePatch
	{
		private static void Prefix(Player __instance)
		{
			if (BetterAutoRun.IsEnabled && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				AutoSprintController.HandleToggle(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Sadle), "ApplyControlls")]
	internal static class SadleApplyControlsPatch
	{
		private static void Prefix(Vector3 moveDir, Vector3 lookDir)
		{
			//IL_0007: 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)
			if (BetterAutoRun.IsEnabled && moveDir.z > 0f)
			{
				BetterAutoRun.State.InitialMoveDirection = lookDir;
				BetterAutoRun.State.PathDirectionOverrideUntil = Time.time + (float)BetterAutoRun.PathDirectionOverrideDurationMillisConfig.Value / 1000f;
			}
		}
	}
}