Decompiled source of NPCPHYSICSOVERHAUL v1.1.0

dll/NPCPhysicsOverhaul.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using NpcPhysics;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(MainMod), "NPC Physics Overhaul", "1.1.0", "Custom Mods", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("NPCPhysicsOverhaul")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("NPCPhysicsOverhaul")]
[assembly: AssemblyTitle("NPCPhysicsOverhaul")]
[assembly: AssemblyVersion("1.1.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 NpcPhysics
{
	internal enum CoreBone
	{
		Unknown,
		Hips,
		Chest,
		Head
	}
	internal static class BoneNames
	{
		internal static CoreBone Identify(string? name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return CoreBone.Unknown;
			}
			string text = new string(name.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
			string[] array = new string[3] { "mixamorig", "bip001", "bip01" };
			foreach (string text2 in array)
			{
				if (text.StartsWith(text2, StringComparison.Ordinal))
				{
					string text3 = text;
					int length = text2.Length;
					text = text3.Substring(length, text3.Length - length);
					break;
				}
			}
			switch (text)
			{
			case "hips":
			case "hip":
			case "pelvis":
			case "pelvism":
			case "rootm":
				return CoreBone.Hips;
			case "chest":
			case "chestm":
			case "upperchest":
			case "spine":
			case "spinem":
			case "spine1":
			case "spine2":
			case "spine01":
			case "spine02":
				return CoreBone.Chest;
			case "head":
			case "headm":
				return CoreBone.Head;
			default:
				return CoreBone.Unknown;
			}
		}
	}
	internal readonly record struct DriveArguments(float Weight, float Spring, float Damper);
	internal readonly record struct DriveFactors(float Weight, float Damper, float AddedDamper, float Force);
	internal readonly record struct DriveCaps(float Spring, float Damper, float Force);
	internal static class DriveLimiter
	{
		internal static readonly DriveCaps Arms = new DriveCaps(12f, 1.5f, 5f);

		internal static readonly DriveCaps Head = new DriveCaps(30f, 3f, 15f);

		internal static readonly DriveCaps Spine = new DriveCaps(100f, 8f, 80f);

		internal static readonly DriveCaps Legs = new DriveCaps(180f, 14f, 100f);

		internal static DriveArguments Limit(DriveArguments original, DriveFactors factors, DriveCaps caps, float influence)
		{
			if (!float.IsFinite(influence) || influence <= 0f || !Valid(original.Weight) || !Valid(original.Spring) || !Valid(original.Damper) || !Valid(factors.Weight) || !Valid(factors.Damper) || !Valid(factors.AddedDamper) || !Valid(factors.Force))
			{
				return original;
			}
			double num = Math.Clamp(influence, 0f, 1f);
			double num2 = (double)caps.Spring / (num * num);
			double num3 = (double)caps.Damper / num;
			double num4 = (double)caps.Force / num;
			double num5 = original.Weight;
			double num6 = (double)factors.Weight * (double)factors.Force;
			if (num6 > 0.0)
			{
				num5 = Math.Min(num5, num4 / num6);
			}
			double num7 = num5 * (double)factors.Weight;
			double num8 = ((num7 > 0.0) ? Math.Min(original.Spring, num2 / num7) : ((double)original.Spring));
			double num9 = ((factors.Damper > 0f) ? Math.Min(original.Damper, Math.Max(0.0, num3 - (double)factors.AddedDamper) / (double)factors.Damper) : ((double)original.Damper));
			return new DriveArguments((float)num5, (float)num8, (float)num9);
		}

		private static bool Valid(float value)
		{
			if (float.IsFinite(value))
			{
				return value >= 0f;
			}
			return false;
		}

		internal static DriveCaps LimitFinal(DriveCaps current, DriveCaps caps, float influence)
		{
			if (!float.IsFinite(influence) || influence <= 0f || float.IsNaN(current.Spring) || current.Spring < 0f || float.IsNaN(current.Damper) || current.Damper < 0f || float.IsNaN(current.Force) || current.Force < 0f)
			{
				return current;
			}
			float num = Math.Clamp(influence, 0f, 1f);
			return new DriveCaps(Math.Min(current.Spring, caps.Spring / (num * num)), Math.Min(current.Damper, caps.Damper / num), Math.Min(current.Force, caps.Force / num));
		}
	}
	internal sealed class HitRecoil
	{
		private float lastQueued = float.NegativeInfinity;

		private float pending;

		internal bool Queue(float severity, float now)
		{
			if (!float.IsFinite(severity) || severity <= 0f || !float.IsFinite(now) || now - lastQueued < 0.2f)
			{
				return false;
			}
			pending = Math.Clamp(severity, 0f, 1f);
			lastQueued = now;
			return true;
		}

		internal float Consume(float speedAlongHit, float massScale = 1f)
		{
			float num = pending;
			pending = 0f;
			if (num <= 0f || !float.IsFinite(speedAlongHit))
			{
				return 0f;
			}
			return Math.Min(Math.Min((0.15f + num * 0.65f) / ReactionModel.Safe(massScale, 1f, 0.5f, 1.5f), 0.8f), Math.Max(0f, 2.5f - speedAlongHit));
		}

		internal void Reset()
		{
			pending = 0f;
			lastQueued = float.NegativeInfinity;
		}

		internal bool Expire(float now)
		{
			if (pending <= 0f || now - lastQueued <= 0.15f)
			{
				return false;
			}
			pending = 0f;
			return true;
		}
	}
	public sealed class MainMod : MelonMod
	{
		internal static MainMod Instance;

		internal const string Build = "2026-10-15";

		private bool menuCreated;

		public override void OnInitializeMelon()
		{
			Instance = this;
			ClassInjector.RegisterTypeInIl2Cpp<PushContactRelay>();
			Settings.Initialize();
			Hooking.OnLevelLoading += OnLevelLoading;
			Hooking.OnNPCKillStart += OnKillStart;
			Hooking.OnNPCBrainResurrected += OnResurrected;
			Log($"Version 1.1.0, build {"2026-10-15"} ready. Enabled={Settings.Enabled}; weight={Settings.WeightPercent:F0}%; recovery={Settings.Recovery:F2}s. Open BoneMenu > NPC Physics Overhaul.");
			if (!Settings.Enabled)
			{
				Log("The saved Enabled setting is OFF. Turn it on in BoneMenu for reactions.");
			}
			if (Settings.Recovery < 0.8f)
			{
				Log("Saved recovery is very short. Choose Use recommended settings in BoneMenu for a longer reaction.");
			}
		}

		public override void OnUpdate()
		{
			if (!menuCreated && PageReady())
			{
				try
				{
					Settings.CreateMenu();
					menuCreated = true;
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Warning("Menu unavailable: " + ex.Message);
					menuCreated = true;
				}
			}
			try
			{
				NpcRegistry.UpdatePlayer();
			}
			catch (Exception ex2)
			{
				NpcRegistry.ReportHookError(ex2);
			}
		}

		public override void OnFixedUpdate()
		{
			NpcRegistry.FixedUpdate();
		}

		private static bool PageReady()
		{
			return Page.Root != null;
		}

		private static void OnLevelLoading(LevelInfo _)
		{
			NpcRegistry.Clear();
		}

		private static void OnKillStart(BehaviourBaseNav nav)
		{
			if ((Object)(object)nav != (Object)null && (Object)(object)((BehaviourBase)nav).puppetMaster != (Object)null)
			{
				NpcRegistry.Remove(((BehaviourBase)nav).puppetMaster);
			}
		}

		private static void OnResurrected(AIBrain brain)
		{
			if ((Object)(object)brain != (Object)null && (Object)(object)brain.puppetMaster != (Object)null)
			{
				NpcRegistry.Remove(brain.puppetMaster);
			}
		}

		public override void OnDeinitializeMelon()
		{
			Hooking.OnLevelLoading -= OnLevelLoading;
			Hooking.OnNPCKillStart -= OnKillStart;
			Hooking.OnNPCBrainResurrected -= OnResurrected;
			NpcRegistry.Clear();
		}

		internal static void Log(string text)
		{
			((MelonBase)Instance).LoggerInstance.Msg(text);
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "OnDisable")]
	internal static class DisablePatch
	{
		private static void Prefix(PuppetMaster __instance)
		{
			NpcRegistry.Remove(__instance);
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "OnDestroy")]
	internal static class DestroyPatch
	{
		private static void Prefix(PuppetMaster __instance)
		{
			NpcRegistry.Remove(__instance);
		}
	}
	[HarmonyPatch(typeof(PuppetMaster), "OnPoolSpawn")]
	internal static class RespawnPatch
	{
		private static void Prefix(PuppetMaster __instance)
		{
			NpcRegistry.Remove(__instance);
		}
	}
	[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
	internal static class DamagePatch
	{
		private static void Prefix(SubBehaviourHealth __instance, int __0, Attack __1)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Settings.Enabled && __1 != null && !(__1.damage <= 0f))
				{
					BehaviourBase behaviour = ((SubBehaviourBase)__instance).behaviour;
					PuppetMaster val = ((behaviour != null) ? behaviour.puppetMaster : null);
					if ((Object)(object)val != (Object)null)
					{
						NpcRegistry.Hit(val, __0, ReactionModel.DamageSeverity(__1.damage), __1.direction, addRecoil: true);
					}
				}
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}
	}
	[HarmonyPatch(typeof(MuscleCollisionBroadcaster), "OnCollisionEnter")]
	internal static class CollisionPatch
	{
		private static void Postfix(MuscleCollisionBroadcaster __instance, Collision __0)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!Settings.Enabled || __0 == null || (Object)(object)__instance.puppetMaster == (Object)null)
				{
					return;
				}
				MuscleCollisionBroadcaster val = (Object.op_Implicit((Object)(object)__0.collider) ? ((Component)__0.collider).GetComponentInParent<MuscleCollisionBroadcaster>() : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val.puppetMaster == (Object)(object)__instance.puppetMaster)
				{
					return;
				}
				Vector3 val2 = __0.relativeVelocity;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (float.IsFinite(magnitude) && magnitude > 0.8f)
				{
					val2 = __0.impulse;
					if (((Vector3)(ref val2)).sqrMagnitude > 0.1f && __0.contactCount > 0)
					{
						val2 = Physics.gravity;
						Vector3 val3;
						if (!(((Vector3)(ref val2)).sqrMagnitude > 0.1f))
						{
							val3 = Vector3.up;
						}
						else
						{
							val2 = Physics.gravity;
							val3 = -((Vector3)(ref val2)).normalized;
						}
						Vector3 val4 = val3;
						ContactPoint contact = __0.GetContact(0);
						if (Mathf.Abs(Vector3.Dot(((ContactPoint)(ref contact)).normal, val4)) < 0.55f)
						{
							NpcRegistry.Trip(__instance.puppetMaster, __instance.muscleIndex, Mathf.Clamp01(0.3f + magnitude * 0.08f), __0.impulse);
						}
					}
				}
				if (float.IsFinite(magnitude) && !(magnitude < 1.4f))
				{
					val2 = __0.impulse;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.25f))
					{
						NpcRegistry.Hit(__instance.puppetMaster, __instance.muscleIndex, Mathf.Clamp01((magnitude - 1.4f) / 6f), __0.impulse);
					}
				}
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}
	}
	[HarmonyPatch(typeof(MuscleCollisionBroadcaster), "ReceiveAttack")]
	internal static class AttackPatch
	{
		private static void Prefix(MuscleCollisionBroadcaster __instance, Attack __0)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Settings.Enabled && __0 != null && !((Object)(object)__instance.puppetMaster == (Object)null))
				{
					NpcRegistry.Hit(__instance.puppetMaster, __instance.muscleIndex, ReactionModel.DamageSeverity(__0.damage), __0.direction, addRecoil: true);
				}
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}
	}
	[HarmonyPatch(typeof(Muscle), "MusclePdDrive")]
	internal static class MotorPatch
	{
		[HarmonyPriority(0)]
		private static void Prefix(Muscle __instance, ref float __0, ref float __1, ref float __2)
		{
			try
			{
				NpcRegistry.AdjustDrive(__instance, ref __0, ref __1, ref __2);
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}

		[HarmonyPriority(0)]
		private static void Postfix(Muscle __instance)
		{
			try
			{
				NpcRegistry.FinalizeDrive(__instance);
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}
	}
	[HarmonyPatch(typeof(Muscle), "Map")]
	internal static class MappingPatch
	{
		[HarmonyPriority(0)]
		private static void Prefix(Muscle __instance, ref float __0)
		{
			try
			{
				NpcRegistry.AdjustMapping(__instance, ref __0);
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
			}
		}
	}
	[HarmonyPatch(typeof(BehaviourBaseNav), "SwitchLocoState")]
	internal static class RecoveryPatch
	{
		private static bool Prefix(BehaviourBaseNav __instance, LocoState __0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			try
			{
				return (int)__0 != 3 || NpcRegistry.AllowGetUp(__instance);
			}
			catch (Exception ex)
			{
				NpcRegistry.ReportHookError(ex);
				return true;
			}
		}
	}
	internal sealed class NpcController
	{
		private sealed class BodySlot
		{
			internal readonly Muscle Muscle;

			internal readonly Rigidbody Body;

			internal readonly int Index;

			internal readonly int Id;

			internal readonly Collider[] Colliders;

			internal PushContactRelay? ContactRelay;

			internal Group Group;

			internal float Shock;

			internal float LastHit = -10f;

			internal float MotorInfluence;

			private DriveArguments originalDrive;

			private bool driveChanged;

			private bool massInitialized;

			private bool massChanged;

			private float originalMass;

			private float appliedMass;

			private Vector3 originalInertia;

			private Vector3 appliedInertia;

			internal BodySlot(Muscle muscle, Rigidbody body, int index)
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				Muscle = muscle;
				Body = body;
				Index = index;
				Id = ((Object)body).GetInstanceID();
				Group = muscle.props.group;
				Colliders = ((IEnumerable<Collider>)((Component)body).GetComponentsInChildren<Collider>()).Where((Collider c) => (Object)(object)c != (Object)null && (Object)(object)c.attachedRigidbody == (Object)(object)body && !c.isTrigger).ToArray();
			}

			internal void EnableContacts()
			{
				if (CanMove(Body))
				{
					if ((Object)(object)ContactRelay == (Object)null)
					{
						ContactRelay = ((Component)Body).gameObject.AddComponent<PushContactRelay>();
					}
					ContactRelay.BodyId = Id;
					((Behaviour)ContactRelay).enabled = true;
				}
			}

			internal bool AdjustDrive(ref float weight, ref float spring, ref float damper)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0055: Expected I4, but got Unknown
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: 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)
				if (MotorInfluence <= 0f || !CanMove(Body))
				{
					return false;
				}
				Props props = Muscle.props;
				State state = Muscle.state;
				Group val = Group;
				DriveCaps driveCaps;
				switch (val - 1)
				{
				case 2:
				case 3:
					driveCaps = DriveLimiter.Arms;
					break;
				case 1:
					driveCaps = DriveLimiter.Head;
					break;
				case 0:
					driveCaps = DriveLimiter.Spine;
					break;
				default:
					driveCaps = DriveLimiter.Legs;
					break;
				}
				DriveCaps caps = driveCaps;
				DriveArguments driveArguments = new DriveArguments(weight, spring, damper);
				DriveFactors factors = new DriveFactors(props.muscleWeight * state.muscleWeightMlp, props.muscleDamper * state.muscleDamperMlp, state.muscleDamperAdd, Muscle._maxForce * state.maxForceMlp);
				DriveArguments driveArguments2 = DriveLimiter.Limit(driveArguments, factors, caps, MotorInfluence);
				originalDrive = driveArguments;
				driveChanged = true;
				if (driveArguments2 == driveArguments)
				{
					return false;
				}
				weight = driveArguments2.Weight;
				spring = driveArguments2.Spring;
				damper = driveArguments2.Damper;
				return true;
			}

			internal void LimitFinalDrive()
			{
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Invalid comparison between Unknown and I4
				//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_0064: 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_007d: Expected I4, but got Unknown
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				ConfigurableJoint val = default(ConfigurableJoint);
				if (driveChanged && !(MotorInfluence <= 0f) && CanMove(Body) && !((Object)(object)Muscle.marrowJoint == (Object)null) && Muscle.marrowJoint.TryGetConfigurableJoint(ref val) && !((Object)(object)val == (Object)null) && (int)val.rotationDriveMode == 1)
				{
					Group val2 = Group;
					DriveCaps driveCaps;
					switch (val2 - 1)
					{
					case 2:
					case 3:
						driveCaps = DriveLimiter.Arms;
						break;
					case 1:
						driveCaps = DriveLimiter.Head;
						break;
					case 0:
						driveCaps = DriveLimiter.Spine;
						break;
					default:
						driveCaps = DriveLimiter.Legs;
						break;
					}
					DriveCaps caps = driveCaps;
					JointDrive slerpDrive = val.slerpDrive;
					DriveCaps driveCaps2 = DriveLimiter.LimitFinal(new DriveCaps(((JointDrive)(ref slerpDrive)).positionSpring, ((JointDrive)(ref slerpDrive)).positionDamper, ((JointDrive)(ref slerpDrive)).maximumForce), caps, MotorInfluence);
					if (((JointDrive)(ref slerpDrive)).positionSpring != driveCaps2.Spring || ((JointDrive)(ref slerpDrive)).positionDamper != driveCaps2.Damper || ((JointDrive)(ref slerpDrive)).maximumForce != driveCaps2.Force)
					{
						((JointDrive)(ref slerpDrive)).positionSpring = driveCaps2.Spring;
						((JointDrive)(ref slerpDrive)).positionDamper = driveCaps2.Damper;
						((JointDrive)(ref slerpDrive)).maximumForce = driveCaps2.Force;
						val.slerpDrive = slerpDrive;
					}
				}
			}

			internal void Restore()
			{
				MotorInfluence = 0f;
				if (driveChanged)
				{
					driveChanged = false;
					if ((Object)(object)Body != (Object)null && (Object)(object)Muscle.marrowJoint != (Object)null)
					{
						Muscle._lastSlerpSpring = -1f;
						Muscle.MusclePdDrive(originalDrive.Weight, originalDrive.Spring, originalDrive.Damper);
					}
				}
			}

			internal void ApplyMass()
			{
				//IL_0049: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: 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)
				if (massInitialized || !CanMove(Body))
				{
					return;
				}
				massInitialized = true;
				float massScale = Settings.MassScale;
				if (!Mathf.Approximately(massScale, 1f))
				{
					originalMass = Body.mass;
					originalInertia = Body.inertiaTensor;
					if (float.IsFinite(originalMass) && !(originalMass <= 0f) && Finite(originalInertia))
					{
						appliedMass = originalMass * massScale;
						appliedInertia = originalInertia * massScale;
						massChanged = true;
						Body.mass = appliedMass;
						Body.inertiaTensor = appliedInertia;
					}
				}
			}

			internal void RestoreMass()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: 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)
				if (massChanged && (Object)(object)Body != (Object)null && Mathf.Approximately(Body.mass, appliedMass))
				{
					Vector3 val = Body.inertiaTensor - appliedInertia;
					if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
					{
						Body.mass = originalMass;
						Body.inertiaTensor = originalInertia;
					}
				}
				massChanged = (massInitialized = false);
			}
		}

		private readonly PuppetMaster puppet;

		private readonly BehaviourBaseNav behaviour;

		private readonly BodySlot[] bodies;

		private readonly Dictionary<IntPtr, BodySlot> bodyLookup;

		private readonly BodySlot hips;

		private readonly BodySlot chest;

		private readonly BodySlot head;

		private readonly BodySlot[] feet;

		private readonly BodySlot[] hands;

		private readonly ReactionModel reaction = new ReactionModel();

		private readonly HitRecoil recoil = new HitRecoil();

		private readonly RecoveryPlanner recovery = new RecoveryPlanner();

		private readonly PushDetector push = new PushDetector();

		private readonly Il2CppReferenceArray<Collider> nearby = new Il2CppReferenceArray<Collider>(32L);

		private readonly Il2CppStructArray<RaycastHit> rayHits = new Il2CppStructArray<RaycastHit>(16L);

		private readonly HashSet<int> ownBodies;

		private readonly int muscleCount;

		private Vector3 support;

		private Vector3 supportVelocity;

		private Vector3 impactDirection;

		private bool grounded;

		private bool fallTriggered;

		private float airborneSeconds;

		private float nextGroundCheck;

		private float nextStep;

		private int stepFoot = -1;

		private int activeStep = -1;

		private float stepStartTime;

		private Vector3 stepStart;

		private Vector3 stepEnd;

		private Transform? stepSurface;

		private Rigidbody? stepPlatform;

		private Vector3 stepStartLocal;

		private Vector3 stepEndLocal;

		private float testAt = -1f;

		private bool motorsAllowed;

		private int motorCalls;

		private int motorChanges;

		private int recoilCount;

		private int mappingCalls;

		private BodySlot? recoilBody;

		private Vector3 recoilDirection;

		private Vector3 firstSupport;

		private Vector3 secondSupport;

		private int supportCount;

		private int stumbleCount;

		private int getUpCount;

		private float supportFriction = 0.6f;

		private float nextStumble;

		private float nextThreatScan;

		private float nextThreatReaction;

		private float knockdownAt = -1f;

		private float lastKnockdown = -10f;

		private float balanceAuthority;

		private bool wasHeld;

		private bool isHeld;

		private bool recovering;

		private float totalMass;

		private int pushIndex;

		private int pushCount;

		private int contactSamples;

		private Vector3 pushDirection;

		internal PuppetMaster Puppet => puppet;

		internal string Status { get; private set; } = "Ready";

		internal string Description => $"{((Object)puppet).name} ({bodies.Length} bodies, {feet.Length} feet, {hands.Length} hands, {bodies.Where((BodySlot b) => (Object)(object)b.Body != (Object)null).Sum((BodySlot b) => b.Body.mass):F1} kg)";

		internal IEnumerable<IntPtr> MusclePointers => bodyLookup.Keys;

		internal IEnumerable<int> BodyIds => ownBodies;

		internal string MotorStatus => $"motor calls={motorCalls}; modified={motorChanges}; mapping calls={mappingCalls}; hit flinches={recoilCount}; contact samples={contactSamples}; pushes={pushCount}; stumbles={stumbleCount}; get-ups requested={getUpCount}; recovery={recovery.Phase}";

		internal bool AllowGetUp
		{
			get
			{
				if (puppet.isAlive && !puppet.isKilling)
				{
					if (Settings.GetUp && !isHeld)
					{
						return !recovery.BlockGetUp;
					}
					return false;
				}
				return true;
			}
		}

		internal string JointStatus
		{
			get
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: 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_00c9: Invalid comparison between Unknown and I4
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				MarrowJoint marrowJoint = chest.Muscle.marrowJoint;
				ConfigurableJoint val = default(ConfigurableJoint);
				if ((Object)(object)marrowJoint == (Object)null || !marrowJoint.TryGetConfigurableJoint(ref val) || (Object)(object)val == (Object)null)
				{
					return "torso joint unavailable";
				}
				JointDrive slerpDrive = val.slerpDrive;
				string text = $"torso drive mode={val.rotationDriveMode}; actual slerp spring={((JointDrive)(ref slerpDrive)).positionSpring:F1}; damping={((JointDrive)(ref slerpDrive)).positionDamper:F1}; force={((JointDrive)(ref slerpDrive)).maximumForce:F1}";
				if ((int)val.rotationDriveMode != 1)
				{
					JointDrive angularXDrive = val.angularXDrive;
					JointDrive angularYZDrive = val.angularYZDrive;
					text += $"; X spring/damping={((JointDrive)(ref angularXDrive)).positionSpring:F1}/{((JointDrive)(ref angularXDrive)).positionDamper:F1}; YZ spring/damping={((JointDrive)(ref angularYZDrive)).positionSpring:F1}/{((JointDrive)(ref angularYZDrive)).positionDamper:F1}";
				}
				return text;
			}
		}

		internal bool CanTest
		{
			get
			{
				if (IsAvailable && puppet.isAlive && !puppet.isKilling)
				{
					return CanMove(hips.Body);
				}
				return false;
			}
		}

		internal bool IsAvailable
		{
			get
			{
				if ((Object)(object)puppet != (Object)null && ((Behaviour)puppet).isActiveAndEnabled)
				{
					return !puppet.hasBeenDespawned;
				}
				return false;
			}
		}

		internal Vector3 Position
		{
			get
			{
				//IL_002f: 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)
				if (!((Object)(object)hips.Body != (Object)null))
				{
					return ((Component)puppet).transform.position;
				}
				return hips.Body.worldCenterOfMass;
			}
		}

		private NpcController(PuppetMaster puppet, BehaviourBaseNav behaviour, BodySlot[] bodies, BodySlot hips, BodySlot chest, BodySlot head, BodySlot[] feet, BodySlot[] hands)
		{
			this.puppet = puppet;
			this.behaviour = behaviour;
			this.bodies = bodies;
			this.hips = hips;
			this.chest = chest;
			this.head = head;
			this.feet = feet;
			this.hands = hands;
			bodyLookup = bodies.ToDictionary((BodySlot b) => ((Il2CppObjectBase)b.Muscle).Pointer);
			muscleCount = ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length;
			ownBodies = new HashSet<int>(bodies.Select((BodySlot b) => b.Id));
		}

		internal static NpcController? TryCreate(PuppetMaster pm, out string reason)
		{
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			reason = "waiting for muscles and behaviours";
			BehaviourBaseNav val = null;
			if (pm.behaviours == null || pm.muscles == null)
			{
				return null;
			}
			foreach (BehaviourBase item in (Il2CppArrayBase<BehaviourBase>)(object)pm.behaviours)
			{
				val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<BehaviourBaseNav>() : null);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				reason = "not a navigation NPC";
				return null;
			}
			if (((Il2CppArrayBase<Muscle>)(object)pm.muscles).Length < 5 || ((Il2CppArrayBase<Muscle>)(object)pm.muscles).Length > 64)
			{
				reason = $"unsupported muscle count {((Il2CppArrayBase<Muscle>)(object)pm.muscles).Length}";
				return null;
			}
			List<BodySlot> slots = new List<BodySlot>();
			Rigidbody rb = default(Rigidbody);
			for (int i = 0; i < ((Il2CppArrayBase<Muscle>)(object)pm.muscles).Length; i++)
			{
				Muscle val2 = ((Il2CppArrayBase<Muscle>)(object)pm.muscles)[i];
				if (val2 != null && val2.props != null && !((Object)(object)val2.marrowBody == (Object)null) && val2.marrowBody.TryGetRigidbody(ref rb) && (Object)(object)rb != (Object)null && slots.All((BodySlot s) => s.Id != ((Object)rb).GetInstanceID()))
				{
					slots.Add(new BodySlot(val2, rb, i));
				}
			}
			BodySlot hips = Bone((HumanBodyBones)0) ?? Named(CoreBone.Hips) ?? slots.FirstOrDefault((BodySlot s) => (int)s.Group == 0);
			BodySlot chest = Bone((HumanBodyBones)8) ?? Bone((HumanBodyBones)7) ?? Named(CoreBone.Chest) ?? slots.FirstOrDefault((BodySlot s) => (int)s.Group == 1);
			BodySlot head = Bone((HumanBodyBones)10) ?? Named(CoreBone.Head) ?? slots.FirstOrDefault((BodySlot s) => (int)s.Group == 2);
			BodySlot[] array = slots.Where((BodySlot s) => (int)s.Group == 6).Take(2).ToArray();
			BodySlot[] array2 = slots.Where((BodySlot s) => (int)s.Group == 4).Take(2).ToArray();
			if (array.Length != 2)
			{
				array = new BodySlot[2]
				{
					Bone((HumanBodyBones)5),
					Bone((HumanBodyBones)6)
				}.OfType<BodySlot>().Distinct().ToArray();
			}
			if (array2.Length != 2)
			{
				array2 = new BodySlot[2]
				{
					Bone((HumanBodyBones)17),
					Bone((HumanBodyBones)18)
				}.OfType<BodySlot>().Distinct().ToArray();
			}
			if (hips == null || chest == null || head == null || hips == chest || hips == head || chest == head)
			{
				reason = "missing distinct torso bones; bodies=" + string.Join(",", slots.Select((BodySlot s) => ((Object)s.Body).name));
				return null;
			}
			hips.Group = (Group)0;
			chest.Group = (Group)1;
			head.Group = (Group)2;
			array = array.Where((BodySlot s) => s != hips && s != chest && s != head).ToArray();
			array2 = array2.Where((BodySlot s) => s != hips && s != chest && s != head).ToArray();
			reason = "ready";
			return new NpcController(pm, val, slots.ToArray(), hips, chest, head, array, array2);
			BodySlot? Bone(HumanBodyBones bone)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)pm.targetAnimator == (Object)null || !pm.targetAnimator.isHuman)
				{
					return null;
				}
				int index = pm.GetMuscleIndex(bone);
				return slots.FirstOrDefault((BodySlot s) => s.Index == index);
			}
			BodySlot? Named(CoreBone bone)
			{
				return slots.FirstOrDefault((BodySlot s) => BoneNames.Identify(((Object)s.Body).name) == bone || ((Object)(object)s.Muscle.target != (Object)null && BoneNames.Identify(((Object)s.Muscle.target).name) == bone));
			}
		}

		internal bool Hit(int index, float severity, Vector3 direction, bool addRecoil = false)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Invalid comparison between Unknown and I4
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			if (!puppet.isAlive || puppet.isKilling || !float.IsFinite(severity))
			{
				return false;
			}
			BodySlot bodySlot = Array.Find(bodies, (BodySlot s) => s.Index == index);
			if (bodySlot == null || !CanMove(bodySlot.Body))
			{
				return false;
			}
			if ((int)bodySlot.Group == 6 && severity < 0.25f)
			{
				return false;
			}
			severity = Mathf.Clamp01(severity * Settings.Reaction);
			if (severity <= 0.02f)
			{
				return false;
			}
			bool flag = Time.time - bodySlot.LastHit < 0.08f;
			bodySlot.Shock = Mathf.Max(bodySlot.Shock, severity);
			if (!flag || severity > reaction.Shock)
			{
				reaction.Hit(severity);
				recovery.Hit();
				if (!flag)
				{
					bodySlot.LastHit = Time.time;
				}
				if (Settings.Stumbling && (severity >= 0.82f || (severity >= 0.45f && (int)behaviour.locoState == 3)))
				{
					knockdownAt = Time.time;
				}
			}
			if (Finite(direction) && ((Vector3)(ref direction)).sqrMagnitude > 0.001f)
			{
				impactDirection = ((Vector3)(ref direction)).normalized;
			}
			if (addRecoil && recoil.Queue(severity, Time.time))
			{
				recoilBody = (((int)bodySlot.Group == 0) ? chest : bodySlot);
				recoilDirection = (Finite(direction) ? direction : Vector3.zero);
			}
			return !flag;
		}

		internal void TestReaction()
		{
			testAt = Time.time + 1f;
		}

		internal void ObservePush(int bodyId, Collision collision)
		{
			//IL_0053: 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: Invalid comparison between Unknown and I4
			//IL_00be: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			contactSamples++;
			if (!motorsAllowed || !grounded || isHeld || !puppet.isAlive || puppet.isKilling || ((int)behaviour.locoState != 0 && (int)behaviour.locoState != 1) || collision.contactCount == 0)
			{
				return;
			}
			Rigidbody rigidbody = collision.rigidbody;
			if ((Object)(object)rigidbody != (Object)null && ownBodies.Contains(((Object)rigidbody).GetInstanceID()))
			{
				return;
			}
			BodySlot bodySlot = Array.Find(bodies, (BodySlot b) => b.Id == bodyId);
			if (bodySlot != null && CanMove(bodySlot.Body))
			{
				Vector3 val = Physics.gravity;
				Vector3 val2;
				if (!(((Vector3)(ref val)).sqrMagnitude > 0.1f))
				{
					val2 = Vector3.up;
				}
				else
				{
					val = Physics.gravity;
					val2 = -((Vector3)(ref val)).normalized;
				}
				Vector3 val3 = val2;
				Vector3 val4 = Vector3.ProjectOnPlane(collision.impulse, val3);
				float magnitude = ((Vector3)(ref val4)).magnitude;
				float mass = totalMass;
				float fixedDeltaTime = Time.fixedDeltaTime;
				val = collision.relativeVelocity;
				float magnitude2 = ((Vector3)(ref val)).magnitude;
				ContactPoint contact = collision.GetContact(0);
				float severity = PushDetector.Severity(magnitude, mass, fixedDeltaTime, magnitude2, Vector3.Dot(((ContactPoint)(ref contact)).normal, val3));
				if (push.Observe(severity))
				{
					pushIndex = bodySlot.Index;
					pushDirection = val4;
				}
			}
		}

		internal void Trip(int index, float severity, Vector3 direction)
		{
			//IL_0037: 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_004a: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_0083: 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_0078: Invalid comparison between Unknown and I4
			if (Settings.Stumbling && grounded && !isHeld && !(Time.time < nextStumble) && ((int)behaviour.locoState == 0 || (int)behaviour.locoState == 1))
			{
				BodySlot bodySlot = Array.Find(bodies, (BodySlot b) => b.Index == index);
				if (bodySlot != null && ((int)bodySlot.Group == 6 || (int)bodySlot.Group == 5) && Hit(index, severity, direction))
				{
					nextStumble = Time.time + 0.7f;
					stumbleCount++;
				}
			}
		}

		internal void AdjustDrive(Muscle muscle, ref float weight, ref float spring, ref float damper)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			motorCalls++;
			if (!motorsAllowed || !puppet.isAlive || puppet.isKilling || !bodyLookup.TryGetValue(((Il2CppObjectBase)muscle).Pointer, out BodySlot value))
			{
				return;
			}
			float value2 = spring;
			float value3 = damper;
			if (value.AdjustDrive(ref weight, ref spring, ref damper))
			{
				motorChanges++;
				if (motorChanges == 1)
				{
					MainMod.Log($"Motor response active on {value.Group}: spring argument {value2:F0} -> {spring:F1}, damping {value3:F0} -> {damper:F1}.");
				}
			}
		}

		internal void AdjustMapping(Muscle muscle, ref float mapping)
		{
			mappingCalls++;
			if (motorsAllowed && puppet.isAlive && !puppet.isKilling && bodyLookup.TryGetValue(((Il2CppObjectBase)muscle).Pointer, out BodySlot value) && !(value.MotorInfluence <= 0f))
			{
				mapping = Mathf.Max(mapping, Mathf.Lerp(mapping, 1f, Mathf.Clamp01(value.MotorInfluence * 3f)));
			}
		}

		internal void FinalizeDrive(Muscle muscle)
		{
			if (motorsAllowed && puppet.isAlive && !puppet.isKilling && bodyLookup.TryGetValue(((Il2CppObjectBase)muscle).Pointer, out BodySlot value))
			{
				value.LimitFinalDrive();
			}
		}

		internal void Tick()
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: 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_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: 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_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: 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_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: 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_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_052b: 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_053e: Invalid comparison between Unknown and I4
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Invalid comparison between Unknown and I4
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_068e: Invalid comparison between Unknown and I4
			//IL_08ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0735: Unknown result type (might be due to invalid IL or missing references)
			//IL_073a: Unknown result type (might be due to invalid IL or missing references)
			//IL_073c: Unknown result type (might be due to invalid IL or missing references)
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0755: Expected I4, but got Unknown
			//IL_0811: Unknown result type (might be due to invalid IL or missing references)
			//IL_0816: Unknown result type (might be due to invalid IL or missing references)
			//IL_0818: Unknown result type (might be due to invalid IL or missing references)
			//IL_081b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0831: Expected I4, but got Unknown
			//IL_079a: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a0: Invalid comparison between Unknown and I4
			//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ae: Invalid comparison between Unknown and I4
			//IL_07bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c3: Invalid comparison between Unknown and I4
			//IL_08a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a8: Invalid comparison between Unknown and I4
			//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cd: Invalid comparison between Unknown and I4
			//IL_09f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a00: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a02: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b2: Invalid comparison between Unknown and I4
			//IL_0a4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a43: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a1e: Unknown result type (might be due to invalid IL or missing references)
			if (puppet.muscles == null || ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length != muscleCount || (Object)(object)behaviour == (Object)null)
			{
				Status = "Rig changed; rediscovering";
				NpcRegistry.Remove(puppet);
				return;
			}
			bool flag = false;
			BodySlot[] array = bodies;
			foreach (BodySlot bodySlot in array)
			{
				if (!((Object)(object)bodySlot.Body == (Object)null))
				{
					flag |= NpcRegistry.IsHeld(bodySlot.Id);
				}
			}
			bool flag2 = puppet.isAlive && !puppet.isKilling && !puppet.isFrozen && (int)puppet.mode == 0 && behaviour.health != null && behaviour.health.cur_hp > 0f;
			if (!flag2)
			{
				Restore();
				Status = "Dead, frozen, inactive, or no health";
				return;
			}
			isHeld = flag;
			if (flag && !Settings.GrabReactions)
			{
				Suspend();
				isHeld = true;
				Status = "Player is holding this NPC";
				return;
			}
			if (!CanMove(hips.Body) || !CanMove(head.Body))
			{
				Restore();
				Status = "Core rigidbody unavailable or kinematic";
				return;
			}
			array = bodies;
			foreach (BodySlot obj in array)
			{
				obj.ApplyMass();
				obj.EnableContacts();
			}
			motorsAllowed = true;
			if (flag && !wasHeld)
			{
				reaction.Hit(0.35f * Settings.Reaction);
			}
			wasHeld = flag;
			if (recoil.Expire(Time.time))
			{
				recoilBody = null;
			}
			Vector3 val;
			if (testAt >= 0f && Time.time >= testAt)
			{
				testAt = -1f;
				val = Vector3.ProjectOnPlane(Position - NpcRegistry.PlayerPosition, Vector3.up);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				Hit(chest.Index, ReactionModel.DamageSeverity(3.5f), normalized, addRecoil: true);
			}
			float fixedDeltaTime = Time.fixedDeltaTime;
			if (!float.IsFinite(fixedDeltaTime) || fixedDeltaTime <= 0f || fixedDeltaTime > 0.1f)
			{
				Restore();
				return;
			}
			val = Physics.gravity;
			Vector3 val2;
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.1f))
			{
				val2 = Vector3.up;
			}
			else
			{
				val = Physics.gravity;
				val2 = -((Vector3)(ref val)).normalized;
			}
			Vector3 val3 = val2;
			Vector3 v = head.Body.worldCenterOfMass - hips.Body.worldCenterOfMass;
			if (!Finite(v) || ((Vector3)(ref v)).sqrMagnitude < 0.01f)
			{
				Restore();
				return;
			}
			float num = Vector3.Dot(((Vector3)(ref v)).normalized, val3);
			if (Time.time >= nextGroundCheck)
			{
				nextGroundCheck = Time.time + 0.065f;
				ProbeSupport(val3);
			}
			if (grounded)
			{
				airborneSeconds = 0f;
				fallTriggered = false;
			}
			else
			{
				airborneSeconds += fixedDeltaTime;
				if (!fallTriggered && airborneSeconds > 0.18f && Vector3.Dot(hips.Body.velocity, val3) < -1.8f)
				{
					reaction.Hit(Mathf.Clamp01(0.55f * Settings.Reaction));
					fallTriggered = true;
				}
				else if (fallTriggered && reaction.TimeSinceHit > 0.4f && Vector3.Dot(hips.Body.velocity, val3) < -1.8f)
				{
					reaction.Hit(0.3f * Settings.Reaction);
				}
			}
			Vector3 val4 = Vector3.zero;
			Vector3 val5 = Vector3.zero;
			float num2 = 0f;
			array = bodies;
			foreach (BodySlot bodySlot2 in array)
			{
				if (!((Object)(object)bodySlot2.Body == (Object)null) && !bodySlot2.Body.isKinematic)
				{
					float mass = bodySlot2.Body.mass;
					val4 += bodySlot2.Body.worldCenterOfMass * mass;
					val5 += bodySlot2.Body.velocity * mass;
					num2 += mass;
				}
			}
			if (num2 <= 0f || !float.IsFinite(num2))
			{
				Restore();
				return;
			}
			totalMass = num2;
			val4 /= num2;
			val5 /= num2;
			if (!Finite(val4) || !Finite(val5))
			{
				Restore();
				return;
			}
			Vector3 val6 = val5 - supportVelocity;
			val = Vector3.ProjectOnPlane(val6, val3);
			float magnitude = ((Vector3)(ref val)).magnitude;
			float error = SupportError(val4 + Vector3.ProjectOnPlane(val6, val3) * 0.12f, val3);
			Stability stability = StabilityModel.Evaluate(grounded, num, error, magnitude, supportFriction);
			bool flag3 = (int)behaviour.locoState == 0 || (int)behaviour.locoState == 1;
			float num3 = push.Tick(fixedDeltaTime);
			if (Settings.Stumbling && flag3 && grounded && !flag && num3 > 0f && Hit(pushIndex, num3, pushDirection))
			{
				pushCount++;
			}
			if (Settings.Stumbling && flag3 && !flag && Time.time >= nextStumble && stability.Risk > 0.65f)
			{
				reaction.Hit((0.3f + 0.35f * stability.Risk) * Settings.Reaction);
				stumbleCount++;
				nextStumble = Time.time + 0.7f;
			}
			if (!flag && Settings.Stumbling && ((knockdownAt >= 0f && Time.time - knockdownAt <= 0.15f) || (flag3 && grounded && num < 0.42f)))
			{
				RequestFall();
			}
			knockdownAt = -1f;
			if (!Settings.GetUp && (int)behaviour.locoState == 3)
			{
				RequestFall();
			}
			UpdateRecovery(fixedDeltaTime, flag, val3);
			flag3 = (int)behaviour.locoState == 0 || (int)behaviour.locoState == 1;
			if (!flag && Settings.Threats && Settings.Reaction > 0f)
			{
				CheckMovingObjects();
			}
			reaction.Tick(fixedDeltaTime, flag2, grounded, held: false, num, Settings.Recovery);
			array = bodies;
			foreach (BodySlot bodySlot3 in array)
			{
				if (Time.time - bodySlot3.LastHit > 0.2f)
				{
					bodySlot3.Shock = Mathf.Max(0f, bodySlot3.Shock - fixedDeltaTime / Settings.Recovery);
				}
				if ((Object)(object)bodySlot3.Body == (Object)null)
				{
					continue;
				}
				float num5;
				if (Settings.ActiveRagdoll && flag3)
				{
					Group val7 = bodySlot3.Group;
					float num4;
					switch (val7 - 1)
					{
					case 2:
					case 3:
						num4 = 0.1f;
						break;
					case 0:
						num4 = 0.06f;
						break;
					case 1:
						num4 = 0.035f;
						break;
					default:
						num4 = 0f;
						break;
					}
					num5 = num4;
				}
				else
				{
					num5 = 0f;
				}
				float num6 = num5;
				if (Settings.ActiveRagdoll && !flag && ((int)behaviour.locoState == 2 || (int)behaviour.locoState == 5))
				{
					num6 = Mathf.Max(num6, ((int)bodySlot3.Group == 0) ? 0f : (((int)bodySlot3.Group == 5 || (int)bodySlot3.Group == 6) ? 0.18f : 0.3f));
				}
				if (reaction.Shock > 0f || num6 > 0f || recovering)
				{
					Group val7 = bodySlot3.Group;
					switch (val7 - 1)
					{
					case 2:
					case 3:
						num5 = reaction.Shock;
						break;
					case 1:
						num5 = reaction.Shock * 0.3f;
						break;
					case 0:
						num5 = reaction.Shock * 0.45f;
						break;
					default:
						num5 = 0f;
						break;
					}
					float num7 = num5;
					bodySlot3.MotorInfluence = Mathf.Clamp01(Mathf.Max(num6, Mathf.Max(num7, bodySlot3.Shock)));
					if (recovering && ((int)bodySlot3.Group == 3 || (int)bodySlot3.Group == 4))
					{
						bodySlot3.MotorInfluence = Mathf.Max(bodySlot3.MotorInfluence, 0.6f);
					}
				}
				else
				{
					bodySlot3.Restore();
				}
			}
			if (!flag)
			{
				ApplyHitRecoil(val3);
			}
			balanceAuthority = stability.Authority * (1f - reaction.Shock * 0.65f) * Mathf.Max(Mathf.Clamp01(reaction.Shock * 4f), Settings.ActiveRagdoll ? stability.Risk : 0f) * (flag ? 0.35f : 1f);
			Status = $"{(flag ? "Grab response" : recovery.Phase)}; shock={reaction.Shock:F2}; support={supportCount}; instability={stability.Risk:F2}";
			if (balanceAuthority > 0f && (flag3 || flag))
			{
				ApplyBalance(val3, ((Vector3)(ref v)).normalized, val4, val6);
				if (Settings.Steps && Settings.Stumbling && !flag)
				{
					ApplyStep(val3, val4, val6);
				}
				else
				{
					activeStep = -1;
				}
			}
			else
			{
				activeStep = -1;
			}
			if (recovering && !flag)
			{
				ApplyRecoveryHands(val3);
			}
			else
			{
				ApplyBrace(val3, val6);
			}
			if (activeStep >= 0 && activeStep < feet.Length)
			{
				LoosenStepLeg(feet[activeStep]);
			}
		}

		private void ApplyHitRecoil(Vector3 up)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_00a1: 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_00ae: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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)
			BodySlot bodySlot = recoilBody;
			recoilBody = null;
			if (bodySlot == null || !CanMove(bodySlot.Body))
			{
				recoil.Consume(float.NaN);
				return;
			}
			Vector3 val = Vector3.ProjectOnPlane(recoilDirection, up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = Vector3.ProjectOnPlane(Position - NpcRegistry.PlayerPosition, up);
			}
			if (!Finite(val) || ((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				recoil.Consume(float.NaN);
				return;
			}
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = bodySlot.Body.velocity - (grounded ? supportVelocity : Vector3.zero);
			float num = recoil.Consume(Vector3.Dot(val2, val), Settings.MassScale);
			if (!(num <= 0f))
			{
				bodySlot.Body.AddForce(val * num, (ForceMode)2);
				recoilCount++;
			}
		}

		private void RequestFall()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			if (!isHeld && !(Time.time - lastKnockdown < 1.2f) && puppet.isAlive && !puppet.isKilling && (int)behaviour.locoState != 2)
			{
				lastKnockdown = Time.time;
				recovery.Hit();
				behaviour.SwitchLocoState((LocoState)2, 0.8f, true);
			}
		}

		private void UpdateRecovery(float dt, bool held, Vector3 up)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0075: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Invalid comparison between Unknown and I4
			bool flag = (int)behaviour.locoState == 2;
			bool flag2 = (int)behaviour.locoState == 3;
			if (!flag && !flag2)
			{
				recovery.Tick(dt, puppet.isAlive && !puppet.isKilling, held, supported: false, 0f, fallen: false, gettingUp: false, Settings.GetUp);
				recovering = false;
				return;
			}
			bool flag3 = false;
			Rigidbody platform = null;
			if (NearSupport(hips, up, out var hit) || NearSupport(chest, up, out hit))
			{
				flag3 = true;
				platform = ((RaycastHit)(ref hit)).rigidbody;
			}
			else
			{
				BodySlot[] array = feet;
				foreach (BodySlot body in array)
				{
					if (NearSupport(body, up, out hit))
					{
						flag3 = true;
						platform = ((RaycastHit)(ref hit)).rigidbody;
						break;
					}
				}
			}
			float speed = 0f;
			float angularSpeed = 0f;
			MeasureRecoveryMotion(hips, platform, ref speed, ref angularSpeed);
			MeasureRecoveryMotion(chest, platform, ref speed, ref angularSpeed);
			MeasureRecoveryMotion(head, platform, ref speed, ref angularSpeed);
			if (recovery.Tick(dt, puppet.isAlive && !puppet.isKilling, held, flag3, speed, flag, flag2, Settings.GetUp, angularSpeed))
			{
				behaviour.SwitchLocoState((LocoState)3, 0.5f, true);
				getUpCount++;
			}
			recovering = Settings.GetUp && flag3 && !held && ((int)behaviour.locoState == 3 || (flag && RecoveryPlanner.IsSettled(speed, angularSpeed) && reaction.TimeSinceHit > 0.8f));
		}

		private bool NearSupport(BodySlot body, Vector3 up, out RaycastHit hit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			hit = default(RaycastHit);
			if ((Object)(object)body.Body == (Object)null || !Ground(body.Body.worldCenterOfMass + up * 0.1f, up, 1.2f, out hit))
			{
				return false;
			}
			Collider[] colliders = body.Colliders;
			foreach (Collider val in colliders)
			{
				if ((Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy)
				{
					Vector3 val2 = val.ClosestPoint(((RaycastHit)(ref hit)).point) - ((RaycastHit)(ref hit)).point;
					if (((Vector3)(ref val2)).sqrMagnitude <= 0.0064f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void MeasureRecoveryMotion(BodySlot body, Rigidbody? platform, ref float speed, ref float angularSpeed)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!CanMove(body.Body))
			{
				speed = (angularSpeed = float.PositiveInfinity);
				return;
			}
			Rigidbody body2 = body.Body;
			Vector3 val = (((Object)(object)platform != (Object)null) ? platform.GetPointVelocity(body2.worldCenterOfMass) : Vector3.zero);
			Vector3 val2 = (((Object)(object)platform != (Object)null) ? platform.angularVelocity : Vector3.zero);
			float num = speed;
			Vector3 val3 = body2.velocity - val;
			speed = Mathf.Max(num, ((Vector3)(ref val3)).magnitude);
			float num2 = angularSpeed;
			val3 = body2.angularVelocity - val2;
			angularSpeed = Mathf.Max(num2, ((Vector3)(ref val3)).magnitude);
		}

		private float SupportError(Vector3 predicted, Vector3 up)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Vector3 right = Vector3.ProjectOnPlane(Vector3.right, up);
			if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
			{
				right = Vector3.ProjectOnPlane(Vector3.forward, up);
			}
			((Vector3)(ref right)).Normalize();
			Vector3 forward = Vector3.Cross(right, up);
			return StabilityModel.SupportError(Flat(predicted), Flat(firstSupport), Flat(secondSupport), supportCount);
			Vector2 Flat(Vector3 p)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: 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)
				return new Vector2(Vector3.Dot(p, right), Vector3.Dot(p, forward));
			}
		}

		private void LoosenStepLeg(BodySlot foot)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			BodySlot bodySlot = foot;
			ConfigurableJoint val = default(ConfigurableJoint);
			for (int i = 0; i < 3; i++)
			{
				if (bodySlot == null)
				{
					break;
				}
				if (bodySlot == hips)
				{
					break;
				}
				if ((int)bodySlot.Group == 5 || (int)bodySlot.Group == 6)
				{
					bodySlot.MotorInfluence = Mathf.Max(bodySlot.MotorInfluence, 0.55f);
					MarrowJoint marrowJoint = bodySlot.Muscle.marrowJoint;
					if (!((Object)(object)marrowJoint == (Object)null) && marrowJoint.TryGetConfigurableJoint(ref val) && !((Object)(object)val == (Object)null) && !((Object)(object)((Joint)val).connectedBody == (Object)null))
					{
						int parentId = ((Object)((Joint)val).connectedBody).GetInstanceID();
						bodySlot = bodies.FirstOrDefault((BodySlot b) => b.Id == parentId);
						continue;
					}
					break;
				}
				break;
			}
		}

		private void ApplyRecoveryHands(Vector3 up)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a8: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			BodySlot[] array = hands;
			foreach (BodySlot bodySlot in array)
			{
				if (CanMove(bodySlot.Body) && !NpcRegistry.IsHeld(bodySlot.Id))
				{
					Vector3 origin = bodySlot.Body.worldCenterOfMass + up * 0.25f;
					if (Ground(origin, up, 0.65f, out var ground))
					{
						Vector3 targetVelocity = (((Object)(object)((RaycastHit)(ref ground)).rigidbody != (Object)null) ? ((RaycastHit)(ref ground)).rigidbody.GetPointVelocity(((RaycastHit)(ref ground)).point) : Vector3.zero);
						PullLimb(bodySlot.Body, chest.Body, ((RaycastHit)(ref ground)).point + up * 0.045f, targetVelocity, 70f, 8f, 35f, Settings.Brace);
					}
				}
			}
		}

		private void CheckMovingObjects()
		{
			//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_003d: 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_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_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)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_014b: 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)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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)
			if (Time.time < nextThreatScan || Time.time < nextThreatReaction)
			{
				return;
			}
			nextThreatScan = Time.time + 0.15f;
			Vector3 worldCenterOfMass = chest.Body.worldCenterOfMass;
			int num = Physics.OverlapSphereNonAlloc(worldCenterOfMass, 1.5f, nearby, -5, (QueryTriggerInteraction)1);
			if (num >= ((Il2CppArrayBase<Collider>)(object)nearby).Length)
			{
				return;
			}
			for (int i = 0; i < num; i++)
			{
				Collider val = ((Il2CppArrayBase<Collider>)(object)nearby)[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Rigidbody attachedRigidbody = val.attachedRigidbody;
				if (!((Object)(object)attachedRigidbody == (Object)null) && !ownBodies.Contains(((Object)attachedRigidbody).GetInstanceID()) && !(attachedRigidbody.mass < 0.2f) && !((Object)(object)((Component)val).GetComponentInParent<MuscleCollisionBroadcaster>() != (Object)null) && (!((Object)(object)Player.RigManager != (Object)null) || !((Component)val).transform.IsChildOf(((Component)Player.RigManager).transform)))
				{
					Vector3 val2 = val.ClosestPoint(worldCenterOfMass) - worldCenterOfMass;
					Vector3 val3 = attachedRigidbody.velocity - chest.Body.velocity;
					if (ThreatPrediction.Approaching(new Vector3(val2.x, val2.y, val2.z), new Vector3(val3.x, val3.y, val3.z)) && (!EnvironmentRay(worldCenterOfMass, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude + 0.05f, out var ground, Vector3.zero, -1f) || !((Object)(object)((RaycastHit)(ref ground)).rigidbody != (Object)(object)attachedRigidbody)))
					{
						impactDirection = -((Vector3)(ref val2)).normalized;
						reaction.Hit(0.4f * Settings.Reaction);
						nextThreatReaction = Time.time + 0.65f;
						break;
					}
				}
			}
		}

		private void ProbeSupport(Vector3 up)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a9: 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_0092: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			supportFriction = 1f;
			firstSupport = (secondSupport = Vector3.zero);
			support = Vector3.zero;
			supportVelocity = Vector3.zero;
			BodySlot[] array = feet;
			foreach (BodySlot bodySlot in array)
			{
				if (!((Object)(object)bodySlot.Body == (Object)null) && Ground(bodySlot.Body.worldCenterOfMass + up * 0.12f, up, 0.36f, out var ground))
				{
					if (num == 0)
					{
						firstSupport = (secondSupport = ((RaycastHit)(ref ground)).point);
					}
					else
					{
						secondSupport = ((RaycastHit)(ref ground)).point;
					}
					num++;
					support += ((RaycastHit)(ref ground)).point;
					PhysicMaterial sharedMaterial = ((RaycastHit)(ref ground)).collider.sharedMaterial;
					supportFriction = Mathf.Min(supportFriction, ((Object)(object)sharedMaterial != (Object)null) ? sharedMaterial.dynamicFriction : 0.6f);
					if ((Object)(object)((RaycastHit)(ref ground)).rigidbody != (Object)null)
					{
						supportVelocity += ((RaycastHit)(ref ground)).rigidbody.GetPointVelocity(((RaycastHit)(ref ground)).point);
					}
				}
			}
			grounded = num > 0;
			supportCount = num;
			if (num > 0)
			{
				support /= (float)num;
				supportVelocity /= (float)num;
			}
		}

		private bool Ground(Vector3 origin, Vector3 up, float distance, out RaycastHit ground)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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)
			return EnvironmentRay(origin, -up, distance, out ground, up, 0.6f);
		}

		private bool EnvironmentRay(Vector3 origin, Vector3 direction, float distance, out RaycastHit ground, Vector3 normalReference, float minimumDot)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			ground = default(RaycastHit);
			int num = Physics.RaycastNonAlloc(origin, direction, rayHits, distance, -5, (QueryTriggerInteraction)1);
			if (num >= ((Il2CppArrayBase<RaycastHit>)(object)rayHits).Length)
			{
				return false;
			}
			float num2 = float.PositiveInfinity;
			bool result = false;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)rayHits)[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !(Vector3.Dot(((RaycastHit)(ref val)).normal, normalReference) < minimumDot) && !(((RaycastHit)(ref val)).distance >= num2))
				{
					Rigidbody rigidbody = ((RaycastHit)(ref val)).rigidbody;
					if ((!((Object)(object)rigidbody != (Object)null) || !ownBodies.Contains(((Object)rigidbody).GetInstanceID())) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<MuscleCollisionBroadcaster>() != (Object)null) && (!((Object)(object)Player.RigManager != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)Player.RigManager).transform)))
					{
						ground = val;
						num2 = ((RaycastHit)(ref val)).distance;
						result = true;
					}
				}
			}
			return result;
		}

		private void ApplyBalance(Vector3 up, Vector3 axis, Vector3 com, Vector3 velocity)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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)
			//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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00f2: 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)
			float num = Settings.Balance * balanceAuthority;
			if (!(num <= 0f))
			{
				Vector3 val = Vector3.ClampMagnitude(Vector3.ProjectOnPlane(support - com, up) * 8f - Vector3.ProjectOnPlane(velocity, up) * 1.5f, 4f);
				if (!NpcRegistry.IsHeld(hips.Id))
				{
					hips.Body.AddForce(val * num, (ForceMode)5);
				}
				Vector3 val2 = Vector3.Cross(axis, up) * 12f - Vector3.ProjectOnPlane(chest.Body.angularVelocity, up) * 1.4f;
				if (CanMove(chest.Body) && !NpcRegistry.IsHeld(chest.Id) && Finite(val2))
				{
					chest.Body.AddTorque(Vector3.ClampMagnitude(val2, 12f) * num, (ForceMode)5);
				}
			}
		}

		private void ApplyStep(Vector3 up, Vector3 com, Vector3 velocity)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: 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_0068: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b5: 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_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_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: 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_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: 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_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: 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_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_01bb: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: 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_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: 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_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			if (feet.Length < 2)
			{
				activeStep = -1;
				return;
			}
			Vector3 right;
			Vector3 forward;
			RaycastHit ground;
			if (activeStep < 0)
			{
				if (Time.time < nextStep || reaction.Shock < 0.2f || reaction.TimeSinceHit > 1.2f)
				{
					return;
				}
				Vector3 val = com + Vector3.ProjectOnPlane(velocity, up) * 0.16f;
				Vector3 val2 = Vector3.ProjectOnPlane(val - support, up);
				if (((Vector3)(ref val2)).magnitude < 0.16f)
				{
					return;
				}
				right = Vector3.ProjectOnPlane(Vector3.right, up);
				if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
				{
					right = Vector3.ProjectOnPlane(Vector3.forward, up);
				}
				((Vector3)(ref right)).Normalize();
				forward = Vector3.Cross(right, up);
				bool flag = CanMove(feet[0].Body) && !NpcRegistry.IsHeld(feet[0].Id);
				bool flag2 = CanMove(feet[1].Body) && !NpcRegistry.IsHeld(feet[1].Id);
				if (!flag || !flag2)
				{
					return;
				}
				bool firstSupported = Ground(feet[0].Body.worldCenterOfMass + up * 0.12f, up, 0.36f, out ground);
				bool secondSupported = Ground(feet[1].Body.worldCenterOfMass + up * 0.12f, up, 0.36f, out ground);
				int num = StepPlanner.ChooseFoot(Flat(feet[0].Body.worldCenterOfMass), Flat(feet[1].Body.worldCenterOfMass), Flat(val), flag, flag2, firstSupported, secondSupported, stepFoot);
				if (num < 0)
				{
					return;
				}
				stepFoot = num;
				Rigidbody body = feet[stepFoot].Body;
				if (!CanMove(body))
				{
					return;
				}
				Rigidbody body2 = feet[(stepFoot + 1) % feet.Length].Body;
				if (!Ground(body2.worldCenterOfMass + up * 0.12f, up, 0.36f, out ground))
				{
					return;
				}
				stepStart = body.worldCenterOfMass;
				Vector3 val3 = stepStart + Vector3.ClampMagnitude(val2, 0.32f);
				if (!Ground(val3 + up * 0.4f, up, 0.85f, out var ground2))
				{
					return;
				}
				stepEnd = ((RaycastHit)(ref ground2)).point + up * 0.09f;
				if (Mathf.Abs(Vector3.Dot(stepEnd - stepStart, up)) > 0.25f)
				{
					return;
				}
				stepSurface = ((Component)((RaycastHit)(ref ground2)).collider).transform;
				stepPlatform = ((RaycastHit)(ref ground2)).rigidbody;
				stepStartLocal = stepSurface.InverseTransformPoint(stepStart);
				stepEndLocal = stepSurface.InverseTransformPoint(stepEnd);
				activeStep = stepFoot;
				stepStartTime = Time.time;
				nextStep = Time.time + 0.65f;
			}
			float num2 = (Time.time - stepStartTime) / 0.3f;
			if (num2 >= 1f)
			{
				activeStep = -1;
				return;
			}
			Rigidbody body3 = feet[activeStep].Body;
			Rigidbody body4 = feet[(activeStep + 1) % feet.Length].Body;
			if ((Object)(object)stepSurface == (Object)null || !((Component)stepSurface).gameObject.activeInHierarchy || !CanMove(body3) || !CanMove(body4) || NpcRegistry.IsHeld(feet[activeStep].Id) || !Ground(body4.worldCenterOfMass + up * 0.12f, up, 0.36f, out ground))
			{
				activeStep = -1;
				return;
			}
			stepStart = stepSurface.TransformPoint(stepStartLocal);
			stepEnd = stepSurface.TransformPoint(stepEndLocal);
			if (Finite(stepEnd))
			{
				Vector3 val4 = stepEnd - body3.worldCenterOfMass;
				if (!(((Vector3)(ref val4)).sqrMagnitude > 0.36f) && Ground(stepEnd + up * 0.15f, up, 0.32f, out var ground3) && !((Object)(object)((Component)((RaycastHit)(ref ground3)).collider).transform != (Object)(object)stepSurface))
				{
					Vector3 val5 = Vector3.Lerp(stepStart, stepEnd, num2) + up * (Mathf.Sin(num2 * (float)Math.PI) * 0.09f);
					Vector3 targetVelocity = (((Object)(object)stepPlatform != (Object)null) ? stepPlatform.GetPointVelocity(val5) : Vector3.zero);
					PullLimb(body3, hips.Body, val5, targetVelocity, 100f, 9f, 24f, balanceAuthority);
					return;
				}
			}
			activeStep = -1;
			Vector2 Flat(Vector3 p)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: 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)
				return new Vector2(Vector3.Dot(p, right), Vector3.Dot(p, forward));
			}
		}

		private void ApplyBrace(Vector3 up, Vector3 velocity)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: