Decompiled source of Obruchnik v0.2.0

BepInEx/plugins/Obruchnik/Obruchnik.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using Obruchnik.Animations;
using Obruchnik.Runtime;
using Obruchnik.Technical;
using Photon.Pun;
using Photon.Realtime;
using REPOLib;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Obruchnik")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0")]
[assembly: AssemblyProduct("Obruchnik")]
[assembly: AssemblyTitle("Obruchnik")]
[assembly: AssemblyVersion("0.2.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Obruchnik
{
	public static class EnemyFoundation
	{
		public const int StartingHealth = 300;

		public static void Configure(EnemyParent parent, Enemy enemy, EnemyHealth health, Transform center, Transform presentation)
		{
			//IL_0083: 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_013d: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)parent) || !Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit((Object)(object)health) || !Object.op_Implicit((Object)(object)center) || !Object.op_Implicit((Object)(object)presentation))
			{
				throw new ArgumentException("All foundation references are required.");
			}
			if ((Object)(object)((Component)enemy).transform.parent != (Object)(object)((Component)parent).transform || (Object)(object)((Component)health).gameObject != (Object)(object)((Component)enemy).gameObject)
			{
				throw new ArgumentException("Expected Enemy child of EnemyParent, with EnemyHealth on Enemy.");
			}
			parent.enemyName = "Обручник";
			parent.EnableObject = ((Component)enemy).gameObject;
			parent.difficulty = (Difficulty)2;
			parent.SpawnedTimeMin = 20f;
			parent.SpawnedTimeMax = 40f;
			parent.DespawnedTimeMin = 240f;
			parent.DespawnedTimeMax = 300f;
			enemy.CenterTransform = center;
			enemy.KillLookAtTransform = center;
			health.meshParent = presentation;
			health.health = 300;
			health.deathFreezeTime = 0.1f;
			health.impactHurt = true;
			health.impactLightDamage = (health.impactMediumDamage = 0);
			health.impactHeavyDamage = 25;
			health.objectHurt = (health.objectHurtStun = true);
			health.objectHurtMultiplier = 1f;
			health.spawnValuable = true;
			health.spawnValuableMax = 3;
			EnemyHealth val = health;
			if (val.onHurt == null)
			{
				val.onHurt = new UnityEvent();
			}
			val = health;
			if (val.onDeathStart == null)
			{
				val.onDeathStart = new UnityEvent();
			}
			val = health;
			if (val.onDeath == null)
			{
				val.onDeath = new UnityEvent();
			}
			val = health;
			if (val.onObjectHurt == null)
			{
				val.onObjectHurt = new UnityEvent();
			}
		}
	}
	[BepInPlugin("bzone.obruchnik", "Obruchnik", "0.2.0")]
	[BepInDependency("REPOLib", "4.3.0")]
	public sealed class ObruchnikPlugin : BaseUnityPlugin
	{
		public const string Guid = "bzone.obruchnik";

		public const string Name = "Obruchnik";

		public const string Version = "0.2.0";

		private bool observed;

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Obruchnik 0.2.0: production development candidate for R.E.P.O. 0.5.0 / REPOLib 4.3.0; combat and multiplayer validation in progress.");
		}

		private void OnEnable()
		{
			ObruchnikDirectorHooks.Install();
			if (observed)
			{
				return;
			}
			BundleLoader.OnAllBundlesLoaded += OnBundlesLoaded;
			foreach (EnemySetup registeredEnemy in Enemies.RegisteredEnemies)
			{
				if (Object.op_Implicit((Object)(object)registeredEnemy) && string.Equals(((Object)registeredEnemy).name, "Obruchnik", StringComparison.Ordinal))
				{
					OnBundlesLoaded();
					break;
				}
			}
		}

		private void OnDisable()
		{
			BundleLoader.OnAllBundlesLoaded -= OnBundlesLoaded;
			ObruchnikDirectorHooks.Uninstall();
		}

		private void OnBundlesLoaded()
		{
			BundleLoader.OnAllBundlesLoaded -= OnBundlesLoaded;
			if (observed)
			{
				return;
			}
			observed = true;
			int num = 0;
			EnemySetup val = null;
			foreach (EnemySetup registeredEnemy in Enemies.RegisteredEnemies)
			{
				if (Object.op_Implicit((Object)(object)registeredEnemy) && string.Equals(((Object)registeredEnemy).name, "Obruchnik", StringComparison.Ordinal))
				{
					num++;
					val = registeredEnemy;
				}
			}
			if (num != 1 || !Object.op_Implicit((Object)(object)val) || val.spawnObjects == null || val.spawnObjects.Count != 1)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("Expected one {0} registration and one spawn reference; found {1} registrations.", "Obruchnik", num));
				return;
			}
			GameObject prefab = ((PrefabRef<GameObject>)(object)val.spawnObjects[0]).Prefab;
			EnemyHealth val2 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponentInChildren<EnemyHealth>(true) : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Expected Obruchnik prefab to contain EnemyHealth.");
				return;
			}
			val2.health = 300;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Obruchnik content queued once by REPOLib. This does not verify spawn, health, physics or multiplayer.");
		}
	}
}
namespace Obruchnik.Animations
{
	public sealed class ObruchnikOrganicCueReceiver : MonoBehaviour
	{
		public event Action<string> Cue;

		public void OnAnimationCue(string cue)
		{
			if (!string.IsNullOrEmpty(cue))
			{
				this.Cue?.Invoke(cue);
			}
		}
	}
	[DefaultExecutionOrder(1000)]
	public sealed class ObruchnikOrganicReactionPlayer : MonoBehaviour
	{
		public GameObject animationRoot;

		public Transform[] rigTransforms;

		public Transform[] faceTransforms;

		public AnimationClip idle;

		public AnimationClip notice;

		public AnimationClip investigate;

		public AnimationClip targetlost;

		public AnimationClip warn;

		public AnimationClip killlaugh;

		public AnimationClip[] killlaughVariants;

		public bool preserveFacePositions;

		private ObruchnikReactionController controller;

		private Vector3[] baseFacePosition;

		private Quaternion[] baseFaceRotation;

		private Vector3[] positions;

		private Vector3[] scales;

		private Quaternion[] rotations;

		private bool[] faceMask;

		private bool overlayActive;

		public ObruchnikReactionController Controller
		{
			get
			{
				if (controller == null)
				{
					Initialize("technical:" + ((Object)this).GetInstanceID());
				}
				return controller;
			}
		}

		public event Action<string> Cue;

		public void Initialize(string instanceId)
		{
			if (controller != null)
			{
				throw new InvalidOperationException("Initialize once, before signals");
			}
			controller = new ObruchnikReactionController(instanceId);
			controller.Cue += delegate(string s)
			{
				this.Cue?.Invoke(s);
			};
		}

		private AnimationClip Clip(FaceReaction r)
		{
			switch (r)
			{
			case FaceReaction.Idle:
				return idle;
			case FaceReaction.Notice:
				return notice;
			case FaceReaction.Investigate:
				return investigate;
			case FaceReaction.TargetLost:
				return targetlost;
			case FaceReaction.Warn:
				return warn;
			case FaceReaction.KillLaugh:
				if (killlaughVariants == null || killlaughVariants.Length != 3 || !Object.op_Implicit((Object)(object)killlaughVariants[Controller.LaughVariant]))
				{
					return killlaugh;
				}
				return killlaughVariants[Controller.LaughVariant];
			default:
				return null;
			}
		}

		private void Buffers()
		{
			if (positions == null || positions.Length != rigTransforms.Length)
			{
				positions = (Vector3[])(object)new Vector3[rigTransforms.Length];
				rotations = (Quaternion[])(object)new Quaternion[rigTransforms.Length];
				scales = (Vector3[])(object)new Vector3[rigTransforms.Length];
				faceMask = new bool[rigTransforms.Length];
				for (int i = 0; i < rigTransforms.Length; i++)
				{
					faceMask[i] = Array.IndexOf(faceTransforms, rigTransforms[i]) >= 0;
				}
				baseFacePosition = (Vector3[])(object)new Vector3[faceTransforms.Length];
				baseFaceRotation = (Quaternion[])(object)new Quaternion[faceTransforms.Length];
			}
		}

		public void Sample(double now)
		{
			//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_00b3: 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_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_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)
			//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_0123: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			Controller.Tick(now);
			AnimationClip val = Clip(Controller.Active);
			if (!Object.op_Implicit((Object)(object)val))
			{
				ClearOverlay();
				return;
			}
			Buffers();
			if (!overlayActive)
			{
				for (int i = 0; i < faceTransforms.Length; i++)
				{
					baseFacePosition[i] = faceTransforms[i].localPosition;
					baseFaceRotation[i] = faceTransforms[i].localRotation;
				}
				overlayActive = true;
			}
			for (int j = 0; j < rigTransforms.Length; j++)
			{
				positions[j] = rigTransforms[j].localPosition;
				rotations[j] = rigTransforms[j].localRotation;
				scales[j] = rigTransforms[j].localScale;
			}
			val.SampleAnimation(animationRoot, (float)Controller.Elapsed(now));
			for (int k = 0; k < rigTransforms.Length; k++)
			{
				if (!faceMask[k] || preserveFacePositions)
				{
					rigTransforms[k].localPosition = positions[k];
				}
				if (!faceMask[k])
				{
					rigTransforms[k].localRotation = rotations[k];
					rigTransforms[k].localScale = scales[k];
				}
			}
		}

		private void ClearOverlay()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!overlayActive)
			{
				return;
			}
			for (int i = 0; i < faceTransforms.Length; i++)
			{
				if (!preserveFacePositions)
				{
					faceTransforms[i].localPosition = baseFacePosition[i];
				}
				faceTransforms[i].localRotation = baseFaceRotation[i];
			}
			overlayActive = false;
		}

		private void LateUpdate()
		{
			Sample(Time.timeAsDouble);
		}

		private void OnDisable()
		{
			if (controller != null)
			{
				controller.Interrupt(ReactionInterrupt.Despawn);
			}
			ClearOverlay();
		}

		public void Notice(double now)
		{
			Controller.React(FaceReaction.Notice, now);
		}

		public void InvestigateNoise(double now)
		{
			Controller.React(FaceReaction.Investigate, now);
		}

		public void TargetLost(double now)
		{
			Controller.React(FaceReaction.TargetLost, now);
		}

		public bool ConfirmKill(KillConfirmation value, double now)
		{
			return Controller.ConfirmKill(value, now);
		}

		public void WeaponState(bool safe, bool priority, double now)
		{
			Controller.SetCombat(safe, priority, now);
		}

		public void Warning(double now)
		{
			Controller.Warning(now);
		}

		public void Interrupt(ReactionInterrupt reason)
		{
			Controller.Interrupt(reason);
			ClearOverlay();
		}

		[ContextMenu("Technical/Notice")]
		private void PreviewNotice()
		{
			Notice(Time.timeAsDouble);
		}

		[ContextMenu("Technical/Noise")]
		private void PreviewNoise()
		{
			InvestigateNoise(Time.timeAsDouble);
		}

		[ContextMenu("Technical/Target lost")]
		private void PreviewLost()
		{
			TargetLost(Time.timeAsDouble);
		}
	}
	public enum FaceReaction
	{
		None,
		Idle,
		Notice,
		Investigate,
		TargetLost,
		Warn,
		KillLaugh
	}
	public enum ReactionInterrupt
	{
		Attack,
		Stun,
		Grab,
		Death,
		Despawn,
		LevelChange
	}
	public struct KillConfirmation
	{
		public string VictimLifeId;

		public string KillerInstanceId;

		public bool Authoritative;

		public bool ConfirmedDeath;

		public bool Disconnected;
	}
	public sealed class ObruchnikReactionController
	{
		private readonly string instanceId;

		private readonly HashSet<string> seenLives = new HashSet<string>();

		private static readonly double[] laughPoints = new double[4] { 0.18, 0.49, 0.86, 1.25 };

		private double[][] configuredLaughPoints;

		private double[] activeLaughPoints = laughPoints;

		private string pendingLife;

		private bool weaponSafe = true;

		private bool combatPriority;

		private bool suppressed;

		private double started;

		private int pulse;

		public FaceReaction Active { get; private set; }

		public string InstanceId => instanceId;

		public double Duration { get; private set; }

		public int LaughVariant { get; private set; }

		public event Action<string> Cue;

		public event Action<FaceReaction> Changed;

		public void ConfigureLaughMarkers(double[][] markers)
		{
			if (markers == null)
			{
				configuredLaughPoints = null;
				return;
			}
			if (markers.Length != 3)
			{
				throw new ArgumentException("Three laugh marker arrays required");
			}
			double[][] array = new double[3][];
			for (int i = 0; i < 3; i++)
			{
				if (markers[i] == null || markers[i].Length == 0)
				{
					throw new ArgumentException("Empty laugh markers");
				}
				array[i] = (double[])markers[i].Clone();
				for (int j = 0; j < array[i].Length; j++)
				{
					if (double.IsNaN(array[i][j]) || array[i][j] <= 0.0 || array[i][j] >= 1.8 || (j > 0 && array[i][j] <= array[i][j - 1]))
					{
						throw new ArgumentException("Markers must increase within1.8s");
					}
				}
			}
			configuredLaughPoints = array;
		}

		public ObruchnikReactionController(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("Instance id required");
			}
			instanceId = id;
		}

		private static double Length(FaceReaction r)
		{
			return r switch
			{
				FaceReaction.Idle => 2.4, 
				FaceReaction.Notice => 0.6, 
				FaceReaction.Investigate => 2.0, 
				FaceReaction.TargetLost => 1.2, 
				FaceReaction.Warn => 0.75, 
				FaceReaction.KillLaugh => 1.8, 
				_ => 0.0, 
			};
		}

		private void Stop()
		{
			if (Active != FaceReaction.None)
			{
				this.Cue?.Invoke("ReactionAudioStop");
				Active = FaceReaction.None;
				Duration = 0.0;
				this.Changed?.Invoke(Active);
			}
		}

		private void Start(FaceReaction r, double now)
		{
			Stop();
			Active = r;
			Duration = Length(r);
			started = now;
			pulse = 0;
			if (r == FaceReaction.KillLaugh)
			{
				activeLaughPoints = ((configuredLaughPoints == null) ? laughPoints : configuredLaughPoints[LaughVariant]);
			}
			this.Changed?.Invoke(r);
			if (r == FaceReaction.Notice)
			{
				this.Cue?.Invoke("Notice");
			}
			if (r == FaceReaction.KillLaugh)
			{
				this.Cue?.Invoke("KillLaugh:" + LaughVariant);
			}
		}

		public double Elapsed(double now)
		{
			return Math.Max(0.0, Math.Min(Duration, now - started));
		}

		public bool React(FaceReaction r, double now)
		{
			if (r == FaceReaction.None || r == FaceReaction.KillLaugh || r == FaceReaction.Warn || suppressed || combatPriority || !weaponSafe || Active == FaceReaction.KillLaugh || (r == FaceReaction.Idle && Active != FaceReaction.None))
			{
				return false;
			}
			Start(r, now);
			return true;
		}

		public bool ConfirmKill(KillConfirmation kill, double now)
		{
			if (suppressed || !kill.Authoritative || !kill.ConfirmedDeath || kill.Disconnected || kill.KillerInstanceId != instanceId || string.IsNullOrEmpty(kill.VictimLifeId))
			{
				return false;
			}
			if (!seenLives.Add(kill.VictimLifeId))
			{
				return false;
			}
			if (pendingLife == null)
			{
				pendingLife = kill.VictimLifeId;
			}
			TryPending(now);
			return true;
		}

		private void TryPending(double now)
		{
			if (pendingLife != null && weaponSafe && !combatPriority && !suppressed)
			{
				uint num = 2166136261u;
				string text = pendingLife;
				foreach (char c in text)
				{
					num ^= c;
					num *= 16777619;
				}
				LaughVariant = (int)(num % 3);
				pendingLife = null;
				Start(FaceReaction.KillLaugh, now);
			}
		}

		public void SetCombat(bool safe, bool warningOrAttack, double now)
		{
			weaponSafe = safe;
			combatPriority = warningOrAttack;
			if (combatPriority && Active != FaceReaction.Warn)
			{
				Stop();
			}
			if (!combatPriority)
			{
				TryPending(now);
			}
		}

		public void Warning(double now)
		{
			pendingLife = null;
			combatPriority = true;
			weaponSafe = false;
			if (!suppressed)
			{
				Start(FaceReaction.Warn, now);
			}
		}

		public void Interrupt(ReactionInterrupt reason)
		{
			pendingLife = null;
			Stop();
			combatPriority = true;
			weaponSafe = false;
			if (reason != ReactionInterrupt.Attack)
			{
				suppressed = true;
			}
		}

		public void ReadyAfterInterrupt(double now)
		{
			suppressed = false;
			SetCombat(safe: true, warningOrAttack: false, now);
		}

		public void Tick(double now)
		{
			if (Active == FaceReaction.KillLaugh)
			{
				while (pulse < activeLaughPoints.Length && now - started >= activeLaughPoints[pulse])
				{
					this.Cue?.Invoke("LaughPulse:" + pulse);
					pulse++;
				}
			}
			if (Active != FaceReaction.None && now - started >= Duration)
			{
				Stop();
			}
		}
	}
}
namespace Obruchnik.Runtime
{
	[DefaultExecutionOrder(500)]
	public sealed class ObruchnikAuthoredLocomotion : MonoBehaviour
	{
		public ObruchnikGameAdapter bridge;

		public ObruchnikLocomotionBank bank;

		private readonly int[] plantSerial = new int[4];

		private ObruchnikLocomotionBank.Motion motion;

		private bool chase;

		private bool moving;

		private bool starting;

		private Vector3 previousRoot;

		private float distance;

		private float clock;

		private float turnAngle;

		private Quaternion turnStart;

		private int[] bindingForNode;

		private Matrix4x4[] authored;

		private Vector3[] points = (Vector3[])(object)new Vector3[4];

		private Vector3[] anchors = (Vector3[])(object)new Vector3[4];

		private Quaternion[] soles = (Quaternion[])(object)new Quaternion[4];

		private bool[] planted = new bool[4];

		private readonly Vector3[] savedAnchors = (Vector3[])(object)new Vector3[4];

		private readonly Quaternion[] savedAnchorSoles = (Quaternion[])(object)new Quaternion[4];

		private readonly bool[] savedPlanted = new bool[4];

		private readonly int[] savedPlantSerial = new int[4];

		private readonly Vector3[] loopFeet = (Vector3[])(object)new Vector3[4];

		private Matrix4x4[] inverseBindingOffsets;

		private const int CorrectionTrialLimit = 32;

		private int correctionTrials;

		private Vector3[] savedPositions;

		private Vector3[] transitionPositions;

		private Quaternion[] savedRotations;

		private Quaternion[] transitionRotations;

		private int contacts;

		private int transitionContacts;

		private float blendClock = 1f;

		private bool initialTerrainStanding;

		private static readonly float[] footingOffsets = new float[13]
		{
			0f, 0.025f, -0.025f, 0.05f, -0.05f, 0.075f, -0.075f, 0.1f, -0.1f, 0.125f,
			-0.125f, 0.15f, -0.15f
		};

		private readonly Collider[] stepContactOwn = (Collider[])(object)new Collider[4];

		private readonly Collider[] stepContactOther = (Collider[])(object)new Collider[4];

		private readonly Vector3[] stepContactNormal = (Vector3[])(object)new Vector3[4];

		private readonly float[] stepContactUntil = new float[4];

		private Vector3 terrainLanePoint;

		private Vector3 terrainLaneDirection;

		private float terrainLaneUntil;

		private bool terrainLaneKnown;

		private int terrainSwing = -1;

		private float terrainSwingClock;

		private float terrainSwingAge;

		private float terrainRestClock;

		private float terrainFromPitch;

		private float terrainTargetPitch;

		private bool terrainPrepared;

		private bool terrainRequested;

		private bool terrainDescending;

		private readonly float[] terrainUpperPitches = new float[4];

		private readonly float[] terrainPitchCorrections = new float[4];

		private Vector3 terrainFrom;

		private Vector3 terrainTarget;

		private Vector3 terrainAirAvoid;

		private Quaternion terrainFromSole;

		private Quaternion terrainTargetSole;

		private float terrainApproach;

		private float terrainAirHeight;

		private float terrainAirDesired;

		private float virtualDistance;

		private float flatTime;

		private float compactWeight;

		private Vector3 traversalDirection;

		private Vector3 portalPoint;

		private Vector3 portalDirection;

		private readonly Quaternion[] anchorSoles = (Quaternion[])(object)new Quaternion[4];

		private Matrix4x4[] compactOriginal;

		private Vector3[][] passageVertices;

		private readonly bool[] flight = new bool[4];

		private readonly float[] flightBegin = new float[4];

		private readonly Vector3[] flightFrom = (Vector3[])(object)new Vector3[4];

		private readonly Vector3[] flightTarget = (Vector3[])(object)new Vector3[4];

		private readonly Quaternion[] flightRotation = (Quaternion[])(object)new Quaternion[4];

		private readonly Quaternion[] flightLanding = (Quaternion[])(object)new Quaternion[4];

		public bool CanTranslate { get; private set; }

		public bool Turning { get; private set; }

		public Quaternion TurnRotation { get; private set; }

		public float SupportHeight { get; private set; }

		public int GroundContacts { get; private set; }

		public bool OnSteps { get; private set; }

		public int RejectedPoses { get; private set; }

		public string LastFailure { get; private set; }

		public int ArmAdjustments { get; private set; }

		public float MaxArmCorrection { get; private set; }

		public float AuthoredTime { get; private set; }

		public string MotionName => motion?.name ?? "idle";

		public bool Initialized { get; private set; }

		private ObruchnikTerrainRig Rig => bridge.poses.rig.source;

		public bool TerrainAdvanceReady { get; private set; }

		public bool TerrainStepInProgress => terrainSwing >= 0;

		public bool TerrainStepTimedOut
		{
			get
			{
				if (terrainSwing >= 0)
				{
					return terrainSwingAge > 3f;
				}
				return false;
			}
		}

		public int TerrainPoseAdjustments { get; private set; }

		public float MaxTerrainPoseCorrection { get; private set; }

		private float TerrainReachReserve
		{
			get
			{
				if (!terrainDescending)
				{
					return 0.12f;
				}
				return 0.04f;
			}
		}

		private float terrainFlightDuration
		{
			get
			{
				if (!terrainDescending)
				{
					return 0.35f;
				}
				return 0.6f;
			}
		}

		public bool TerrainMode { get; private set; }

		public bool NarrowMode { get; private set; }

		public bool CompactMode
		{
			get
			{
				if (!TerrainMode)
				{
					return NarrowMode;
				}
				return true;
			}
		}

		public string TraversalFailure { get; private set; }

		public float PassageWidth { get; private set; }

		public float PassageBodyWidth { get; private set; }

		public float PassageBodyCenter { get; private set; }

		public float PassageCoreWidth { get; private set; }

		private float StrideScale
		{
			get
			{
				if (!NarrowMode)
				{
					if (!TerrainMode)
					{
						return 1f;
					}
					return 0.4f;
				}
				return 0.18f;
			}
		}

		private float MotionDistance => (CompactMode ? virtualDistance : distance) / StrideScale;

		internal Vector3 SightDirection
		{
			get
			{
				//IL_0015: 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 (!NarrowMode)
				{
					return ((Component)this).transform.forward;
				}
				return portalDirection;
			}
		}

		public bool PassageTooSmall
		{
			get
			{
				//IL_0023: 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_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 (NarrowMode && !Turning && compactWeight > 0.99f && Vector3.Angle(((Component)this).transform.forward, Quaternion.Euler(0f, 90f, 0f) * portalDirection) < 2f)
				{
					return PassageWidth < PassageCoreWidth + 0.04f;
				}
				return false;
			}
		}

		public event Action<string> PoseRejected;

		public int PlantSerial(int leg)
		{
			return plantSerial[leg];
		}

		private void Awake()
		{
			if (Object.op_Implicit((Object)(object)bridge) && Object.op_Implicit((Object)(object)bank))
			{
				bridge.poses.walker.InitializeStanding = Standing;
			}
		}

		private bool Standing()
		{
			initialTerrainStanding = false;
			if (TryWideStanding())
			{
				return true;
			}
			return TryTerrainStanding();
		}

		private bool TryWideStanding()
		{
			//IL_0070: 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_0080: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00d5: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_010e: 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_0166: 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)
			if (authored == null)
			{
				authored = (Matrix4x4[])(object)new Matrix4x4[Rig.nodes.Length];
			}
			bank.walkStart.clip.SampleAnimation(((Component)this).gameObject, 0f);
			CaptureAuthored();
			Array.Clear(Rig.authoredArmBias, 0, 4);
			Array.Clear(Rig.authoredArmYawBias, 0, 4);
			Matrix4x4 val = ((Component)this).transform.localToWorldMatrix * Rig.nativeToLocal;
			for (int i = 0; i < 4; i++)
			{
				ObruchnikTerrainRig.Leg leg = Rig.legs[i];
				points[i] = ((Matrix4x4)(ref val)).MultiplyPoint3x4(Vector4.op_Implicit(((Matrix4x4)(ref authored[leg.foot])).GetColumn(3)));
				Quaternion[] array = soles;
				int num = i;
				Matrix4x4 val2 = val * authored[leg.foot] * leg.footOffset;
				array[num] = ((Matrix4x4)(ref val2)).rotation;
				if (!FindGround(i, points[i], soles[i], out var target, out var _))
				{
					LastFailure = "spawn-support-" + i + " at " + ((object)Unsafe.As<Vector3, Vector3>(ref points[i])/*cast due to .constrained prefix*/).ToString();
					return false;
				}
				points[i] = target;
			}
			if (!Rig.PoseAuthored(authored, points, soles, correctFeet: true, out var reason))
			{
				LastFailure = reason;
				return false;
			}
			if (Object.op_Implicit((Object)(object)bridge.poses.walker.guard) && !bridge.poses.walker.guard.Clear())
			{
				LastFailure = bridge.poses.walker.guard.LastFailure;
				return false;
			}
			return true;
		}

		public void InitializeAuthored()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			authored = (Matrix4x4[])(object)new Matrix4x4[Rig.nodes.Length];
			savedPositions = (Vector3[])(object)new Vector3[Rig.bindings.Length];
			savedRotations = (Quaternion[])(object)new Quaternion[Rig.bindings.Length];
			transitionPositions = (Vector3[])(object)new Vector3[Rig.bindings.Length];
			transitionRotations = (Quaternion[])(object)new Quaternion[Rig.bindings.Length];
			blendClock = 1f;
			bridge.poses.walker.InitializeStanding = Standing;
			previousRoot = ((Component)this).transform.position;
			distance = (clock = 0f);
			if (!initialTerrainStanding)
			{
				ResetTraversal();
			}
			bool flag = (Turning = false);
			moving = (starting = flag);
			motion = bank.walkStart;
			AuthoredTime = 0f;
			CanTranslate = false;
			if (!initialTerrainStanding)
			{
				Array.Clear(planted, 0, 4);
			}
			initialTerrainStanding = false;
			Initialized = true;
			Present();
		}

		private void CaptureAuthored()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_0149: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_01ad: 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_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_0118: 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_0122: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			if (bindingForNode == null)
			{
				ObruchnikTerrainRig.Binding[] bindings = Rig.bindings;
				bindingForNode = new int[Rig.nodes.Length];
				inverseBindingOffsets = (Matrix4x4[])(object)new Matrix4x4[bindings.Length];
				for (int i = 0; i < bindings.Length; i++)
				{
					inverseBindingOffsets[i] = ((Matrix4x4)(ref bindings[i].offset)).inverse;
				}
				for (int j = 0; j < bindingForNode.Length; j++)
				{
					int node = j;
					bindingForNode[j] = Array.FindIndex(bindings, (ObruchnikTerrainRig.Binding b) => b.node == node);
				}
			}
			Matrix4x4 val = ((Component)this).transform.localToWorldMatrix * Rig.nativeToLocal;
			Matrix4x4 inverse = ((Matrix4x4)(ref val)).inverse;
			for (int num = 0; num < Rig.nodes.Length; num++)
			{
				int num2 = bindingForNode[num];
				if (num2 >= 0)
				{
					ObruchnikTerrainRig.Binding binding = Rig.bindings[num2];
					authored[num] = inverse * binding.bone.localToWorldMatrix * inverseBindingOffsets[num2];
					continue;
				}
				ObruchnikTerrainRig.Node node2 = Rig.nodes[num];
				Vector3 euler = node2.euler;
				Quaternion val2 = Quaternion.AngleAxis(euler.z * 57.29578f, Vector3.forward) * Quaternion.AngleAxis(euler.y * 57.29578f, Vector3.up) * Quaternion.AngleAxis(euler.x * 57.29578f, Vector3.right);
				Matrix4x4 val3 = Matrix4x4.TRS(node2.position, val2, Vector3.one);
				authored[num] = ((node2.parent < 0) ? val3 : (authored[node2.parent] * val3));
			}
		}

		private void Accumulate()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_001b: 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_003f: 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)
			Vector3 position = ((Component)this).transform.position;
			if (!Turning)
			{
				float num = distance;
				Vector2 val = new Vector2(position.x - previousRoot.x, position.z - previousRoot.z);
				distance = num + ((Vector2)(ref val)).magnitude;
			}
			previousRoot = position;
		}

		private void BeginTransition()
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Rig.bindings.Length; i++)
			{
				transitionPositions[i] = Rig.bindings[i].bone.localPosition;
				transitionRotations[i] = Rig.bindings[i].bone.localRotation;
			}
			transitionContacts = contacts;
			blendClock = 0f;
		}

		private void MatchLoop(bool nextChase)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_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_0103: Unknown result type (might be due to invalid IL or missing references)
			BeginTransition();
			chase = nextChase;
			motion = (chase ? bank.chase : bank.walk);
			moving = true;
			starting = false;
			float num = float.PositiveInfinity;
			int num2 = 0;
			for (int i = 0; i < loopFeet.Length; i++)
			{
				ObruchnikTerrainRig.Binding binding = Rig.bindings[bindingForNode[Rig.legs[i].foot]];
				loopFeet[i] = ((Component)this).transform.InverseTransformPoint(binding.bone.position);
			}
			for (int j = 0; j < motion.times.Length; j++)
			{
				float num3 = (((motion.contacts[j] & contacts) == 0) ? 100 : 0);
				for (int k = 0; k < loopFeet.Length; k++)
				{
					float num4 = num3;
					Vector3 val = loopFeet[k] - motion.feet[j * 4 + k];
					num3 = num4 + ((Vector3)(ref val)).sqrMagnitude * (float)(((contacts & (1 << k)) == 0) ? 1 : 2);
				}
				if (num3 < num)
				{
					num = num3;
					num2 = j;
				}
			}
			distance = motion.times[num2] * motion.speed * StrideScale;
			virtualDistance = distance;
			AuthoredTime = motion.times[num2];
		}

		public void Plan(float dt, float command, Vector3 direction, bool steerWhileMoving = false)
		{
			//IL_0044: 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_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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_0137: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			if (!Initialized)
			{
				InitializeAuthored();
			}
			Accumulate();
			AdvanceTraversal(dt, command);
			clock += dt;
			blendClock += dt;
			TurnRotation = Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f);
			for (int i = 0; i < 4; i++)
			{
				Rig.authoredArmBias[i] = Mathf.MoveTowards(Rig.authoredArmBias[i], 0f, dt * 8f);
				Rig.authoredArmYawBias[i] = Mathf.MoveTowards(Rig.authoredArmYawBias[i], 0f, dt * 2f);
			}
			if (Turning)
			{
				AuthoredTime = Mathf.Min(clock, motion.duration);
				float num = motion.Yaw(AuthoredTime) / motion.yaws[motion.yaws.Length - 1];
				TurnRotation = turnStart * Quaternion.Euler(0f, turnAngle * num, 0f);
				CanTranslate = false;
				if (clock >= motion.duration && Quaternion.Angle(((Component)this).transform.rotation, TurnRotation) < 1f)
				{
					Turning = false;
					moving = false;
					distance = 0f;
				}
				return;
			}
			float num2 = Vector3.SignedAngle(Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up), direction, Vector3.up);
			Vector3 velocity = bridge.poses.body.velocity;
			Vector2 val = new Vector2(velocity.x, velocity.z);
			float magnitude = ((Vector2)(ref val)).magnitude;
			float num3 = (steerWhileMoving ? 30 : (TerrainMode ? 20 : 6));
			if ((command < 0.01f || Mathf.Abs(num2) > num3) && magnitude > 0.05f)
			{
				CanTranslate = false;
				if (moving && !starting)
				{
					AuthoredTime = Mathf.Repeat(MotionDistance / motion.speed, motion.duration);
				}
				return;
			}
			if (command > 0.01f && Mathf.Abs(num2) > num3)
			{
				TurnStart(num2);
				return;
			}
			if (command < 0.01f)
			{
				if (moving || motion != bank.walkStart)
				{
					BeginTransition();
				}
				moving = (starting = false);
				CanTranslate = false;
				motion = bank.walkStart;
				AuthoredTime = 0f;
				return;
			}
			bool flag = command > 2f;
			if (moving && chase != flag)
			{
				MatchLoop(flag);
			}
			if (!moving || chase != flag)
			{
				BeginTransition();
				chase = flag;
				motion = (chase ? bank.chaseStart : bank.walkStart);
				moving = (starting = true);
				clock = (distance = (virtualDistance = 0f));
			}
			if (starting)
			{
				int j;
				for (j = 0; j < motion.distances.Length && motion.distances[j] < 1E-06f; j++)
				{
				}
				float num4 = motion.times[Mathf.Max(0, j - 1)];
				CanTranslate = clock >= num4;
				AuthoredTime = (CanTranslate ? Mathf.Max(num4, motion.TimeAtDistance(MotionDistance)) : clock);
				if (MotionDistance >= motion.cycleDistance - 0.0001f)
				{
					starting = false;
					motion = (chase ? bank.chase : bank.walk);
				}
			}
			if (!starting)
			{
				CanTranslate = true;
				AuthoredTime = Mathf.Repeat(MotionDistance / Mathf.Max(0.01f, motion.speed), motion.duration);
			}
		}

		public void RebaseFlatStance()
		{
			//IL_0066: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_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_00f6: 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_0100: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			BeginTransition();
			motion = bank.walkStart;
			bool flag = (CanTranslate = false);
			bool flag3 = (Turning = flag);
			moving = (starting = flag3);
			float height = (AuthoredTime = (distance = (virtualDistance = (clock = 0f))));
			previousRoot = ((Component)this).transform.position;
			transitionContacts = 0;
			for (int i = 0; i < 4; i++)
			{
				ObruchnikTerrainRig.Leg leg = Rig.legs[i];
				ObruchnikTerrainRig.Binding binding = Rig.bindings[bindingForNode[leg.foot]];
				Matrix4x4 val = binding.bone.localToWorldMatrix * ((Matrix4x4)(ref binding.offset)).inverse;
				Quaternion[] array = anchorSoles;
				int num2 = i;
				Matrix4x4 val2 = val * leg.footOffset;
				array[num2] = ((Matrix4x4)(ref val2)).rotation;
				Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3));
				planted[i] = Ground(i, val3, anchorSoles[i], out anchors[i], out height) && Mathf.Abs(anchors[i].y - val3.y) < 0.04f;
				if (planted[i])
				{
					transitionContacts |= 1 << i;
				}
			}
		}

		private void TurnStart(float angle)
		{
			//IL_003f: 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)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			BeginTransition();
			moving = (starting = false);
			Turning = true;
			turnAngle = Mathf.Clamp(angle, -90f, 90f);
			turnStart = Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f);
			clock = 0f;
			distance = 0f;
			this.motion = bank.turns[0];
			float num = float.PositiveInfinity;
			ObruchnikLocomotionBank.Motion[] turns = bank.turns;
			foreach (ObruchnikLocomotionBank.Motion motion in turns)
			{
				float num2 = motion.yaws[motion.yaws.Length - 1];
				if (Mathf.Sign(num2) == Mathf.Sign(turnAngle))
				{
					float num3 = Mathf.Abs(num2 - turnAngle);
					if (num3 < num)
					{
						num = num3;
						this.motion = motion;
					}
				}
			}
			AuthoredTime = 0f;
			CanTranslate = false;
			TurnRotation = turnStart;
		}

		public void ResetAfterInterrupt()
		{
			Initialized = false;
		}

		private bool Ground(int leg, Vector3 p, Quaternion q, out Vector3 target, out float height)
		{
			//IL_003f: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			ObruchnikTerrainWalker walker = bridge.poses.walker;
			float num = float.PositiveInfinity;
			float num2 = float.NegativeInfinity;
			Vector3[] soleOffsets = walker.rig.legs[leg].soleOffsets;
			RaycastHit val3 = default(RaycastHit);
			foreach (Vector3 val in soleOffsets)
			{
				for (int j = (TerrainMode ? (-1) : 0); j <= (TerrainMode ? 1 : 0); j++)
				{
					Vector3 val2 = p + q * val + traversalDirection * ((float)j * 0.03f);
					if (!Physics.Raycast(val2 + Vector3.up * (CompactMode ? 1f : 0.55f), Vector3.down, ref val3, CompactMode ? 2f : 1.5f, LayerMask.op_Implicit(walker.groundMask), (QueryTriggerInteraction)1) || ((RaycastHit)(ref val3)).normal.y < 0.75f)
					{
						target = p;
						height = 0f;
						return false;
					}
					num = Mathf.Min(num, ((RaycastHit)(ref val3)).point.y - val2.y);
					num2 = Mathf.Max(num2, ((RaycastHit)(ref val3)).point.y - val2.y);
				}
			}
			target = p + Vector3.up * (num2 + 0.001f);
			height = target.y - 0.111f;
			return num2 - num < 0.005f;
		}

		private bool FindGround(int leg, Vector3 p, Quaternion q, out Vector3 target, out float height)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0035: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((CompactMode && !Turning) ? traversalDirection : ((Component)this).transform.forward);
			float[] array = footingOffsets;
			foreach (float num in array)
			{
				if (Ground(leg, p + val * num, q, out target, out height))
				{
					return true;
				}
			}
			if (TerrainMode)
			{
				for (int j = 1; j <= 30; j++)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						if (Ground(leg, p + val * ((float)j * 0.005f * (float)k), q, out target, out height))
						{
							return true;
						}
					}
				}
			}
			target = p;
			height = 0f;
			return false;
		}

		public bool Present()
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_068e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0703: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07da: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0802: Unknown result type (might be due to invalid IL or missing references)
			//IL_0804: Unknown result type (might be due to invalid IL or missing references)
			//IL_0806: Unknown result type (might be due to invalid IL or missing references)
			//IL_0810: Unknown result type (might be due to invalid IL or missing references)
			//IL_0815: Unknown result type (might be due to invalid IL or missing references)
			//IL_081a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0836: Unknown result type (might be due to invalid IL or missing references)
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_084a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_085f: Unknown result type (might be due to invalid IL or missing references)
			//IL_086f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05af: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b71: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b80: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a39: Unknown result type (might be due to invalid IL or missing references)
			if (!bridge.fixtureMode && !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			if (!Initialized || bridge.poses.State != PhysicalPoseState.Ready || bridge.Dead || (Object.op_Implicit((Object)(object)bridge.combat) && bridge.combat.OwnsPose))
			{
				return true;
			}
			Accumulate();
			if (moving && !starting && !Turning)
			{
				AuthoredTime = Mathf.Repeat(MotionDistance / Mathf.Max(0.01f, motion.speed), motion.duration);
			}
			ObruchnikTerrainRig.Binding[] bindings = Rig.bindings;
			for (int i = 0; i < bindings.Length; i++)
			{
				savedPositions[i] = bindings[i].bone.localPosition;
				savedRotations[i] = bindings[i].bone.localRotation;
			}
			bool flag = !CompactMode;
			int num = contacts;
			int groundContacts = GroundContacts;
			float supportHeight = SupportHeight;
			bool onSteps = OnSteps;
			if (flag)
			{
				Array.Copy(anchors, savedAnchors, 4);
				Array.Copy(anchorSoles, savedAnchorSoles, 4);
				Array.Copy(planted, savedPlanted, 4);
				Array.Copy(plantSerial, savedPlantSerial, 4);
			}
			motion.clip.SampleAnimation(((Component)this).gameObject, AuthoredTime);
			float num2 = Mathf.SmoothStep(0f, 1f, blendClock / 0.18f);
			if (num2 < 1f)
			{
				for (int j = 0; j < bindings.Length; j++)
				{
					Transform bone = bindings[j].bone;
					bone.localPosition = Vector3.Lerp(transitionPositions[j], bone.localPosition, num2);
					bone.localRotation = Quaternion.Slerp(transitionRotations[j], bone.localRotation, num2);
				}
			}
			CaptureAuthored();
			ApplyCompactPose();
			int num3 = motion.Frame(AuthoredTime);
			contacts = motion.contacts[num3];
			if (num2 < 1f)
			{
				contacts &= transitionContacts;
			}
			GroundContacts = 0;
			SupportHeight = 0f;
			OnSteps = false;
			float num4 = float.PositiveInfinity;
			float num5 = float.NegativeInfinity;
			bool correction = num2 < 1f;
			Matrix4x4 val = ((Component)this).transform.localToWorldMatrix * Rig.nativeToLocal;
			for (int k = 0; k < 4; k++)
			{
				ObruchnikTerrainRig.Leg leg = Rig.legs[k];
				points[k] = ((Matrix4x4)(ref val)).MultiplyPoint3x4(Vector4.op_Implicit(((Matrix4x4)(ref authored[leg.foot])).GetColumn(3)));
				Quaternion[] array = soles;
				int num6 = k;
				Matrix4x4 val2 = val * authored[leg.foot] * leg.footOffset;
				array[num6] = ((Matrix4x4)(ref val2)).rotation;
			}
			if (TerrainMode && !motion.name.StartsWith("turn"))
			{
				TerrainFeet();
				correction = true;
			}
			else if (NarrowMode && !motion.name.StartsWith("turn"))
			{
				TraversalFeet(num3);
				correction = true;
			}
			RaycastHit val7 = default(RaycastHit);
			RaycastHit val10 = default(RaycastHit);
			for (int l = 0; l < 4; l++)
			{
				if ((contacts & (1 << l)) != 0)
				{
					if (planted[l])
					{
						if (Quaternion.Angle(soles[l], anchorSoles[l]) > 0.001f)
						{
							correction = true;
						}
						soles[l] = anchorSoles[l];
					}
					Quaternion val3 = Quaternion.FromToRotation(soles[l] * (Quaternion.Inverse(Rig.legs[l].soleBasis) * Vector3.up), Vector3.up) * soles[l];
					if (Quaternion.Angle(val3, soles[l]) > 0.001f)
					{
						correction = true;
					}
					soles[l] = val3;
					Vector3 val5;
					if (planted[l])
					{
						Vector3 val4 = points[l];
						val4.x = anchors[l].x;
						val4.z = anchors[l].z;
						val5 = val4 - points[l];
						if (((Vector3)(ref val5)).sqrMagnitude > 5E-06f)
						{
							correction = true;
						}
						points[l] = val4;
					}
					if (planted[l] ? Ground(l, points[l], soles[l], out var target, out var height) : FindGround(l, points[l], soles[l], out target, out height))
					{
						val5 = target - points[l];
						if (((Vector3)(ref val5)).sqrMagnitude > 1E-10f)
						{
							correction = true;
						}
						points[l] = target;
						anchors[l] = target;
						anchorSoles[l] = soles[l];
						if (!planted[l])
						{
							plantSerial[l]++;
						}
						planted[l] = true;
						GroundContacts++;
						SupportHeight += height;
						num4 = Mathf.Min(num4, height);
						num5 = Mathf.Max(num5, height);
					}
					else
					{
						planted[l] = false;
					}
					continue;
				}
				planted[l] = false;
				float num7 = points[l].y - ((Component)this).transform.position.y - 0.11f;
				Vector3 val6 = points[l] + ((Component)this).transform.forward * 0.15f;
				if (!CompactMode && Physics.Raycast(val6 + Vector3.up * 0.5f, Vector3.down, ref val7, 1.5f, LayerMask.op_Implicit(bridge.poses.walker.groundMask), (QueryTriggerInteraction)1) && ((RaycastHit)(ref val7)).normal.y > 0.75f)
				{
					float num8 = ((RaycastHit)(ref val7)).point.y - ((Component)this).transform.position.y;
					if (Mathf.Abs(num8) > 0.04f)
					{
						OnSteps = true;
					}
					if (Mathf.Abs(num8) > 0.01f && Mathf.Abs(num8) < 0.36f)
					{
						points[l].y += num8 * Mathf.SmoothStep(0f, 1f, num7 / 0.06f);
						correction = true;
					}
				}
				float num9 = 0f;
				Vector3[] soleOffsets = bridge.poses.walker.rig.legs[l].soleOffsets;
				foreach (Vector3 val8 in soleOffsets)
				{
					Vector3 val9 = points[l] + soles[l] * val8;
					if (Physics.Raycast(val9 + Vector3.up * 0.5f, Vector3.down, ref val10, 1f, LayerMask.op_Implicit(bridge.poses.walker.groundMask), (QueryTriggerInteraction)1) && ((RaycastHit)(ref val10)).normal.y > 0.75f)
					{
						num9 = Mathf.Max(num9, ((RaycastHit)(ref val10)).point.y + 0.001f - val9.y);
					}
				}
				if (num9 > 1E-05f)
				{
					points[l].y += num9;
					correction = true;
				}
			}
			if (GroundContacts > 0)
			{
				SupportHeight /= GroundContacts;
			}
			if (TerrainMode && terrainDescending)
			{
				SupportHeight += 0.08f;
			}
			if (num5 - num4 > 0.04f)
			{
				OnSteps = true;
			}
			if (GroundContacts > 0)
			{
				LimitSupportHeight();
			}
			if (!SafeAuthored(correction, out var reason))
			{
				RejectedPoses++;
				LastFailure = (reason ?? bridge.poses.walker.guard.LastFailure) + " motion=" + MotionName + " t=" + AuthoredTime;
				for (int n = 0; n < 4; n++)
				{
					LastFailure = LastFailure + " foot" + n + "=" + ((Vector3)(ref points[n])).ToString("F6");
				}
				for (int num10 = 0; num10 < bindings.Length; num10++)
				{
					bindings[num10].bone.localPosition = savedPositions[num10];
					bindings[num10].bone.localRotation = savedRotations[num10];
				}
				if (flag)
				{
					Array.Copy(savedAnchors, anchors, 4);
					Array.Copy(savedAnchorSoles, anchorSoles, 4);
					Array.Copy(savedPlanted, planted, 4);
					Array.Copy(savedPlantSerial, plantSerial, 4);
					contacts = num;
					GroundContacts = groundContacts;
					SupportHeight = supportHeight;
					OnSteps = onSteps;
				}
				CaptureAuthored();
				Rig.PoseAuthored(authored, points, soles, correctFeet: false, out var _, applyArmBias: false);
				this.PoseRejected?.Invoke(LastFailure);
				return false;
			}
			if (TerrainMode)
			{
				for (int num11 = 0; num11 < 4; num11++)
				{
					MaxTerrainPoseCorrection = Mathf.Max(MaxTerrainPoseCorrection, Mathf.Abs(terrainPitchCorrections[num11]));
				}
			}
			Rig.Commit();
			for (int num12 = 0; num12 < 4; num12++)
			{
				ObruchnikTerrainWalker.Foot foot = bridge.poses.walker.feet[num12];
				foot.position = points[num12];
				foot.rotation = soles[num12];
				foot.swing = (contacts & (1 << num12)) == 0;
				bridge.poses.walker.feet[num12] = foot;
			}
			return true;
		}

		private bool SafeAuthored(bool correction, out string reason)
		{
			correctionTrials = 32;
			if (SafeAuthoredCore(correction, out reason))
			{
				return true;
			}
			if (TerrainMode && terrainSwing >= 0 && correctionTrials > 0 && RetryTerrainAirFoot(correction, out reason))
			{
				return true;
			}
			if (correctionTrials == 0)
			{
				reason = "correction-budget: " + (reason ?? bridge.poses.walker.guard.LastFailure);
			}
			return false;
		}

		private bool SafeAuthoredCore(bool correction, out string reason)
		{
			Rig.PreferAuthoredPitch = CompactMode || compactWeight > 0.0001f;
			ObruchnikTerrainSkinGuard guard = bridge.poses.walker.guard;
			if (!Rig.PoseAuthored(authored, points, soles, correction, out reason) && (!TerrainMode || !RetryTerrainReach(out reason)))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)guard) || (guard.Clear() && (!TerrainMode || StepContactsClear())))
			{
				return true;
			}
			if (TerrainMode && RetryTerrainPose())
			{
				return true;
			}
			for (int i = 0; i < 4; i++)
			{
				if (guard.ClearLeg(i) && guard.ArmSelfClear(i))
				{
					continue;
				}
				float num = Rig.authoredArmBias[i];
				float yaw = Rig.authoredArmYawBias[i];
				bool flag = false;
				for (int j = 1; j <= 24; j++)
				{
					if (correctionTrials <= 0)
					{
						break;
					}
					float num2 = num + (float)(((j % 2 == 1) ? 1 : (-1)) * ((j + 1) / 2));
					if (!(Mathf.Abs(num2) > 12f))
					{
						correctionTrials--;
						Rig.authoredArmBias[i] = num2;
						if (Rig.PoseAuthored(authored, points, soles, correction, out reason) && guard.ClearLeg(i) && guard.ArmSelfClear(i))
						{
							flag = true;
							ArmAdjustments++;
							MaxArmCorrection = Mathf.Max(MaxArmCorrection, Mathf.Abs(num2));
							break;
						}
					}
				}
				if (!flag && TerrainMode)
				{
					Rig.authoredArmBias[i] = num;
					float num3 = Rig.authoredArmYawBias[i];
					for (int k = 1; k <= 30; k++)
					{
						if (correctionTrials <= 0)
						{
							break;
						}
						float num4 = num3 + (float)(((k % 2 == 1) ? 1 : (-1)) * ((k + 1) / 2));
						if (!(Mathf.Abs(num4) > 15f))
						{
							correctionTrials--;
							Rig.authoredArmYawBias[i] = num4;
							if (Rig.PoseAuthored(authored, points, soles, correction, out reason) && guard.ClearLeg(i) && guard.ArmSelfClear(i))
							{
								flag = true;
								ArmAdjustments++;
								break;
							}
						}
					}
					if (!flag)
					{
						Rig.authoredArmYawBias[i] = num3;
					}
				}
				if (!flag && TerrainMode)
				{
					flag = TerrainArmCorner(i, num, yaw, correction, out reason);
				}
				if (!flag)
				{
					Rig.authoredArmBias[i] = num;
					if (TerrainMode && RetryTerrainSelfPose(correction, out reason))
					{
						return true;
					}
					reason = reason ?? guard.LastFailure;
					return false;
				}
			}
			bool flag2 = guard.Clear();
			if (!flag2 && TerrainMode)
			{
				flag2 = RetryTerrainSelfPose(correction, out reason);
			}
			reason = (flag2 ? null : guard.LastFailure);
			if (flag2 && TerrainMode)
			{
				TraversalFailure = null;
			}
			return flag2;
		}

		private bool TerrainArmCorner(int arm, float pitch, float yaw, bool correction, out string reason)
		{
			ObruchnikTerrainSkinGuard guard = bridge.poses.walker.guard;
			for (int i = 2; i <= 16; i += 2)
			{
				if (correctionTrials <= 0)
				{
					break;
				}
				for (int j = -12; j <= 12; j += 2)
				{
					if (correctionTrials <= 0)
					{
						break;
					}
					for (int k = -14; k <= 14; k += 2)
					{
						if (correctionTrials <= 0)
						{
							break;
						}
						if (Mathf.Max(Mathf.Abs(j), Mathf.Abs(k)) == i && !(Mathf.Abs(pitch + (float)j) > 12f) && !(Mathf.Abs(yaw + (float)k) > 15f))
						{
							correctionTrials--;
							Rig.authoredArmBias[arm] = pitch + (float)j;
							Rig.authoredArmYawBias[arm] = yaw + (float)k;
							if (Rig.PoseAuthored(authored, points, soles, correction, out reason) && guard.ClearLeg(arm) && guard.ArmSelfClear(arm))
							{
								ArmAdjustments++;
								MaxArmCorrection = Mathf.Max(MaxArmCorrection, Mathf.Abs(pitch + (float)j));
								return true;
							}
						}
					}
				}
			}
			Rig.authoredArmBias[arm] = pitch;
			Rig.authoredArmYawBias[arm] = yaw;
			reason = guard.LastFailure;
			return false;
		}

		private void LateUpdate()
		{
			if (Initialized && bridge.fixtureMode)
			{
				Present();
			}
		}

		private void OnDisable()
		{
			Initialized = false;
		}

		private bool RetryTerrainAirFoot(bool correction, out string reason)
		{
			//IL_000e: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0168: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			int num = terrainSwing;
			Vector3 val = points[num];
			Matrix4x4[] array = (Matrix4x4[])authored.Clone();
			float[] sourceArray = (float[])terrainPitchCorrections.Clone();
			float[] sourceArray2 = (float[])Rig.authoredArmBias.Clone();
			float[] sourceArray3 = (float[])Rig.authoredArmYawBias.Clone();
			Vector3 val2 = Vector3.Cross(Vector3.up, traversalDirection);
			reason = bridge.poses.walker.guard.LastFailure;
			for (int i = 1; i <= 3; i++)
			{
				if (correctionTrials <= 0)
				{
					break;
				}
				for (int j = 0; j < 3; j++)
				{
					if (correctionTrials <= 0)
					{
						break;
					}
					for (int k = -1; k <= 1; k += 2)
					{
						if (correctionTrials <= 0)
						{
							break;
						}
						Vector3 val3 = (Vector3)(j switch
						{
							1 => traversalDirection, 
							0 => val2, 
							_ => Vector3.up, 
						}) * ((float)i * 0.01f * (float)k);
						Vector3 val4 = terrainAirAvoid + val3;
						if (!(((Vector3)(ref val4)).magnitude > 0.12f))
						{
							correctionTrials--;
							Array.Copy(array, authored, array.Length);
							Array.Copy(sourceArray, terrainPitchCorrections, 4);
							Array.Copy(sourceArray2, Rig.authoredArmBias, 4);
							Array.Copy(sourceArray3, Rig.authoredArmYawBias, 4);
							points[num] = val + val3;
							if (SafeAuthoredCore(correction, out reason))
							{
								terrainAirAvoid += val3;
								TraversalFailure = null;
								return true;
							}
						}
					}
				}
			}
			points[num] = val;
			Array.Copy(array, authored, array.Length);
			Array.Copy(sourceArray, terrainPitchCorrections, 4);
			Array.Copy(sourceArray2, Rig.authoredArmBias, 4);
			Array.Copy(sourceArray3, Rig.authoredArmYawBias, 4);
			Rig.PoseAuthored(authored, points, soles, correction, out var _);
			return false;
		}

		public void ObserveStepContact(int leg, Collider own, Collider other, Vector3 normal)
		{
			//IL_0019: 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)
			stepContactOwn[leg] = own;
			stepContactOther[leg] = other;
			stepContactNormal[leg] = normal;
			stepContactUntil[leg] = Time.time + 0.25f;
		}

		private bool HasStepContact(int leg)
		{
			if (Time.time <= stepContactUntil[leg] && Object.op_Implicit((Object)(object)stepContactOwn[leg]))
			{
				return Object.op_Implicit((Object)(object)stepContactOther[leg]);
			}
			return false;
		}

		private float StepContactDepth(int leg)
		{
			//IL_003e: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			Collider val = stepContactOwn[leg];
			Collider val2 = stepContactOther[leg];
			if (Time.time > stepContactUntil[leg] || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return 0f;
			}
			Vector3 val3 = default(Vector3);
			float result = default(float);
			if (!Physics.ComputePenetration(val, ((Component)val).transform.position - stepContactNormal[leg] * 0.018f, ((Component)val).transform.rotation, val2, ((Component)val2).transform.position, ((Component)val2).transform.rotation, ref val3, ref result))
			{
				return 0f;
			}
			return result;
		}

		private bool StepContactClear(int leg)
		{
			return StepContactDepth(leg) <= 0.0005f;
		}

		private bool StepContactsClear()
		{
			for (int i = 0; i < 4; i++)
			{
				if (!StepContactClear(i))
				{
					return false;
				}
			}
			return true;
		}

		private Vector3 TerrainLane(Vector3 direction)
		{
			//IL_0008: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: 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)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: 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)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00b2: 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_00e0: 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_00f7: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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)
			//IL_01c2: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = terrainLaneKnown && Vector3.Dot(direction, terrainLaneDirection) > 0.8f;
			Vector3 val = (flag ? terrainLaneDirection : traversalDirection);
			Vector3 val2 = Vector3.Cross(Vector3.up, val);
			int num = LayerMask.op_Implicit(bridge.poses.solidMask);
			RaycastHit val4 = default(RaycastHit);
			RaycastHit val5 = default(RaycastHit);
			Vector3 val6;
			for (float num2 = 0f; num2 <= 1.21f; num2 += 0.2f)
			{
				Vector3 val3 = ((Component)this).transform.position + val * num2;
				if (!Floor(val3, out var height))
				{
					continue;
				}
				val3.y = height + 1.6f;
				if (((!Physics.Raycast(val3, val2, ref val4, 1.6f, num, (QueryTriggerInteraction)1) || Vector3.Dot(((RaycastHit)(ref val4)).normal, -val2) < 0.9f) && (!Physics.Raycast(val3, -val2, ref val4, 1.6f, num, (QueryTriggerInteraction)1) || Vector3.Dot(((RaycastHit)(ref val4)).normal, val2) < 0.9f)) || !Physics.Raycast(((RaycastHit)(ref val4)).point + ((RaycastHit)(ref val4)).normal * Mathf.Abs(Vector3.Dot(((RaycastHit)(ref val4)).point - val3, ((RaycastHit)(ref val4)).normal)), ((RaycastHit)(ref val4)).normal, ref val5, 1.6f, num, (QueryTriggerInteraction)1) || Vector3.Dot(((RaycastHit)(ref val5)).normal, -((RaycastHit)(ref val4)).normal) < 0.98f)
				{
					continue;
				}
				float num3 = Vector3.Distance(((RaycastHit)(ref val4)).point, ((RaycastHit)(ref val5)).point);
				if (!(num3 < 1.6f) && !(num3 > 2.7f))
				{
					terrainLanePoint = (((RaycastHit)(ref val4)).point + ((RaycastHit)(ref val5)).point) / 2f;
					val6 = ((RaycastHit)(ref val5)).normal - ((RaycastHit)(ref val4)).normal;
					val6 = Vector3.Cross(((Vector3)(ref val6)).normalized, Vector3.up);
					terrainLaneDirection = ((Vector3)(ref val6)).normalized;
					if (Vector3.Dot(terrainLaneDirection, val) < 0f)
					{
						terrainLaneDirection = -terrainLaneDirection;
					}
					terrainLaneUntil = Time.time + 1.5f;
					terrainLaneKnown = true;
					PassageWidth = num3;
					break;
				}
			}
			if (Time.time > terrainLaneUntil && !flag)
			{
				return direction;
			}
			traversalDirection = terrainLaneDirection;
			val2 = Vector3.Cross(Vector3.up, traversalDirection);
			MeasureProfile(val2);
			float num4 = Vector3.Dot(terrainLanePoint - val2 * TerrainChassisCenter(val2) - ((Component)this).transform.position, val2);
			val6 = traversalDirection + val2 * Mathf.Clamp(num4 * 10f, -1f, 1f);
			return ((Vector3)(ref val6)).normalized;
		}

		private float TerrainChassisCenter(Vector3 right)
		{
			//IL_0040: 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_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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			float num = float.PositiveInfinity;
			float num2 = float.NegativeInfinity;
			MeshCollider[] hulls = bridge.poses.hulls;
			for (int i = 0; i < hulls.Length; i++)
			{
				if (!((Object)hulls[i]).name.Contains("_Rib"))
				{
					Matrix4x4 localToWorldMatrix = ((Component)hulls[i]).transform.localToWorldMatrix;
					Vector3[] array = passageVertices[i];
					foreach (Vector3 val in array)
					{
						float num3 = Vector3.Dot(((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(val) - ((Component)this).transform.position, right);
						num = Mathf.Min(num, num3);
						num2 = Mathf.Max(num2, num3);
					}
				}
			}
			return (num + num2) / 2f;
		}

		private bool RetryTerrainSelfPose(bool correction, out string reason)
		{
			ObruchnikTerrainSkinGuard guard = bridge.poses.walker.guard;
			Rig.PoseAuthored(authored, points, soles, correction, out var reason2);
			for (int i = 0; i < 4; i++)
			{
				if (guard.RibSelfClear(i))
				{
					continue;
				}
				Matrix4x4[] array = (Matrix4x4[])authored.Clone();
				float num = TerrainUpperAngle(i);
				bool flag = false;
				for (int j = 1; j <= 120; j++)
				{
					if (correctionTrials <= 0)
					{
						break;
					}
					float num2 = Mathf.Round(num) + (float)(((j % 2 == 1) ? 1 : (-1)) * ((j + 1) / 2));
					if (!(num2 < 25f) && !(num2 > 145f))
					{
						correctionTrials--;
						TerrainHintTrial(array, i, num2);
						if (Rig.PoseAuthored(authored, points, soles, correction, out reason2) && guard.RibClear(i) && guard.RibSelfClear(i))
						{
							AcceptTerrainHint(i, num2, num);
							flag = true;
							break;
						}
					}
				}
				if (!flag)
				{
					Array.Copy(array, authored, authored.Length);
					Rig.PoseAuthored(authored, points, soles, correction, out reason2);
				}
			}
			bool flag2 = guard.Clear();
			if (!flag2 && guard.RibConflict(out var first, out var second))
			{
				flag2 = RetryTerrainPair(first, second, correction);
			}
			reason = (flag2 ? null : guard.LastFailure);
			if (flag2)
			{
				TraversalFailure = null;
			}
			return flag2;
		}

		private bool RetryTerrainPair(int a, int b, bool correction)
		{
			Matrix4x4[] array = (Matrix4x4[])authored.Clone();
			float num = TerrainUpperAngle(a);
			float num2 = TerrainUpperAngle(b);
			float num3 = TerrainWorkingAngle(a);
			float num4 = TerrainWorkingAngle(b);
			if (TerrainPairTrial(array, a, b, num3, num4, correction))
			{
				AcceptTerrainHint(a, num3, num);
				AcceptTerrainHint(b, num4, num2);
				return true;
			}
			for (int i = 5; i <= 20; i += 5)
			{
				if (correctionTrials <= 0)
				{
					break;
				}
				for (int j = -20; j <= 20; j += 5)
				{
					if (correctionTrials <= 0)
					{
						break;
					}
					for (int k = -20; k <= 20; k += 5)
					{
						if (correctionTrials <= 0)
						{
							break;
						}
						if (Mathf.Max(Mathf.Abs(j), Mathf.Abs(k)) == i)
						{
							num3 = Mathf.Round(num) + (float)j;
							num4 = Mathf.Round(num2) + (float)k;
							if (!(num3 < 25f) && !(num3 > 145f) && !(num4 < 25f) && !(num4 > 145f) && TerrainPairTrial(array, a, b, num3, num4, correction))
							{
								AcceptTerrainHint(a, num3, num);
								AcceptTerrainHint(b, num4, num2);
								return true;
							}
						}
					}
				}
			}
			Array.Copy(array, authored, authored.Length);
			Rig.PoseAuthored(authored, points, soles, correction, out var _);
			return false;
		}

		private bool TerrainPairTrial(Matrix4x4[] original, int a, int b, float qa, float qb, bool correction)
		{
			if (correctionTrials == 0)
			{
				return false;
			}
			correctionTrials--;
			TerrainHintTrial(original, a, qa);
			Matrix4x4[] original2 = (Matrix4x4[])authored.Clone();
			TerrainHintTrial(original2, b, qb);
			ObruchnikTerrainSkinGuard guard = bridge.poses.walker.guard;
			if (Rig.PoseAuthored(authored, points, soles, correction, out var _) && guard.RibClear(a) && guard.RibClear(b) && guard.RibSelfClear(a) && guard.RibSelfClear(b))
			{
				return guard.Clear();
			}
			return false;
		}

		private bool TryTerrainStanding()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_00a7: 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_00b3: 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_00bd: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			ResetTraversal();
			SurveyTraversal(((Component)this).transform.forward, 0f);
			if (!TerrainMode)
			{
				return false;
			}
			TerrainLane(traversalDirection);
			compactWeight = 1f;
			motion = bank.walkStart;
			bank.walkStart.clip.SampleAnimation(((Component)this).gameObject, 0f);
			CaptureAuthored();
			for (int i = 0; i < 4; i++)
			{
				terrainUpperPitches[i] = TerrainWorkingAngle(i);
			}
			ApplyCompactPose();
			Matrix4x4 val = ((Component)this).transform.localToWorldMatrix * Rig.nativeToLocal;
			Quaternion val2 = Quaternion.LookRotation(traversalDirection);
			for (int j = 0; j < 4; j++)
			{
				Vector3 hipRestUnity = Rig.legs[j].hipRestUnity;
				hipRestUnity.x = Mathf.Sign(Rig.legs[j].rest.x) * TerrainStanceWidth(j);
				hipRestUnity.y = 0f;
				Vector3 p = TerrainFootTarget(j, ((Matrix4x4)(ref val)).MultiplyPoint3x4(Vector4.op_Implicit(((Matrix4x4)(ref authored[Rig.legs[j].hip])).GetColumn(3))));
				soles[j] = val2 * Rig.legs[j].soleBasis;
				if (!FindGround(j, p, soles[j], out points[j], out var _))
				{
					LastFailure = "compact-spawn-support-" + j;
					return false;
				}
			}
			if (!SafeAuthored(correction: true, out var reason))
			{
				LastFailure = reason ?? bridge.poses.walker.guard.LastFailure;
				return false;
			}
			for (int k = 0; k < 4; k++)
			{
				anchors[k] = points[k];
				anchorSoles[k] = soles[k];
				planted[k] = true;
			}
			contacts = 15;
			terrainPrepared = true;
			initialTerrainStanding = true;
			LastFailure = null;
			return true;
		}

		private float TerrainWorkingAngle(int leg)
		{
			return terrainDescending ? 85 : ((Mathf.Abs(Rig.legs[leg].hipRestUnity.x) > 0.45f) ? 55 : 85);
		}

		private float TerrainStanceWidth(int leg)
		{
			if (!terrainDescending || !(Rig.legs[leg].hipRestUnity.z < 0f))
			{
				return 0.68f;
			}
			return 0.9f;
		}

		private Vector3 TerrainFootTarget(int leg, Vector3 hip)
		{
			//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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c1: 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_0066: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_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)
			Vector3 hipRestUnity = Rig.legs[leg].hipRestUnity;
			hipRestUnity.x = Mathf.Sign(Rig.legs[leg].rest.x) * TerrainStanceWidth(leg);
			hipRestUnity.y = 0f;
			if (!terrainDescending)
			{
				return ((Component)this).transform.position + Quaternion.LookRotation(traversalDirection) * hipRestUnity + traversalDirection * 0.48f;
			}
			Vector3 val = Vector3.Cross(Vector3.up, traversalDirection);
			Vector3 val2 = hip + traversalDirection * 0.48f;
			val2.y = ((Component)this).transform.position.y;
			Vector3 val3 = (terrainLaneKnown ? terrainLanePoint : ((Component)this).transform.position);
			return val2 + val * (hipRestUnity.x - Vector3.Dot(val2 - val3, val));
		}

		private void ResetTerrainSteps()
		{
			terrainSwing = -1;
			terrainSwingClock = (terrainSwingAge = (terrainRestClock = 0f));
			for (int i = 0; i < 4; i++)
			{
				terrainUpperPitches[i] = 85f;
				terrainPitchCorrections[i] = 0f;
			}
			terrainLaneUntil = 0f;
			terrainLaneKnown = false;
			bool flag = (TerrainAdvanceReady = false)