Decompiled source of ReimaginedPhysics v1.1.2

ImprovedPhysics2.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using MoveClasses;
using PlayerHelpers;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ImprovedPhysics2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImprovedPhysics2")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4d345681-e68b-4a0a-a057-049a123a1d00")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.yourname.ImprovedPhysics2", "Imnproved Physics 2", "1.0.3")]
[DisallowMultipleComponent]
public class ImprovedPhysics : BaseUnityPlugin
{
	public class RigidbodyAutoConfig : MonoBehaviour
	{
		[Header("Normalization / tuning (tweak these)")]
		[SerializeField]
		private float sizeScale = 10f;

		[SerializeField]
		private float distScale = 2f;

		[SerializeField]
		private float dragMultiplier = 0.5f;

		[SerializeField]
		private float baseDrag = 0.05f;

		[SerializeField]
		private float minDrag = 0f;

		[SerializeField]
		private float maxDrag = 1f;

		[Header("Angular velocity limits")]
		[SerializeField]
		private float minAngularVelocity = 6f;

		[SerializeField]
		private float maxAngularVelocity = 20f;

		private void Start()
		{
			//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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00e8: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_027e: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			ApplyRealWeights(component);
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>();
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				ApplyDefaults(component, 0f);
				return;
			}
			float num = 0f;
			Vector3 worldCenterOfMass = component.worldCenterOfMass;
			float num2 = 0f;
			float num3 = Mathf.Max(component.mass, 0.01f);
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null || val.isTrigger || (Object)(object)val.attachedRigidbody != (Object)(object)component)
				{
					continue;
				}
				Bounds bounds = val.bounds;
				float num4 = (((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y + ((Bounds)(ref bounds)).size.y * ((Bounds)(ref bounds)).size.z + ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.z) / 3f;
				num += num4;
				Vector3[] array2 = (Vector3[])(object)new Vector3[8]
				{
					((Bounds)(ref bounds)).min,
					new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.z),
					new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).min.z),
					new Vector3(((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).min.z),
					new Vector3(((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).min.z),
					new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).max.z),
					new Vector3(((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.z),
					((Bounds)(ref bounds)).max
				};
				for (int j = 0; j < array2.Length; j++)
				{
					float num5 = Vector3.Distance(worldCenterOfMass, array2[j]);
					if (num5 > num2)
					{
						num2 = num5;
					}
				}
			}
			float num6 = num / num3;
			float num7 = Mathf.Clamp01(num6 / Mathf.Max(sizeScale, 0.0001f));
			float num8 = Mathf.Clamp01(num2 / Mathf.Max(distScale, 0.0001f));
			float num9 = (num7 + num8 + num8) / 3f;
			float num10 = baseDrag + num9 * dragMultiplier;
			component.linearDamping = Mathf.Clamp(num10, minDrag, maxDrag);
			component.angularDamping = Mathf.Clamp(num10, minDrag, maxDrag);
			component.maxAngularVelocity = Mathf.Lerp(maxAngularVelocity, minAngularVelocity, num9 * 1.5f);
		}

		private void ApplyRealWeights(Rigidbody rb)
		{
			if (((Object)((Component)rb).gameObject).name.ToLower() == "hip")
			{
				rb.mass = 11f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower() == "spine1")
			{
				rb.mass = 12f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower() == "spine2")
			{
				rb.mass = 13f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("scapula"))
			{
				rb.mass = 0.7f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("shoulder"))
			{
				rb.mass = 1.8f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("elbow"))
			{
				rb.mass = 1.4f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("wrist"))
			{
				rb.mass = 0.5f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("hip_joint"))
			{
				rb.mass = 8f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
			if (((Object)((Component)rb).gameObject).name.ToLower().Contains("knee"))
			{
				rb.mass = 3.6f;
				Debug.Log((object)(((Object)((Component)rb).gameObject).name + " detected, new weight assigned"));
			}
		}

		private void ApplyDefaults(Rigidbody rb, float combinedPenalty)
		{
			rb.linearDamping = baseDrag;
			rb.angularDamping = baseDrag;
			rb.maxAngularVelocity = maxAngularVelocity;
		}
	}

	private class HipData
	{
		public GameObject hip;

		public float defaultDamper;

		public float defaultSpring;

		public bool wasTilted;

		public CharacterGroundChecker Grounder;

		public HipData(GameObject hip, float defaultDamper, float defaultSpring, CharacterGroundChecker grounder)
		{
			this.hip = hip;
			this.defaultDamper = defaultDamper;
			this.defaultSpring = defaultSpring;
			Grounder = grounder;
		}
	}

	private bool isHipUnlock;

	private ConfigEntry<bool> configUseRealisticHipUnlocker;

	private ConfigEntry<bool> configUseWeaponClash;

	public bool UseRealisticHipUnlocker;

	public bool UseWeaponClashScript;

	private InputAction toggleMenuAction;

	private bool showMenu = false;

	private Coroutine hipUnlockCoroutine;

	private List<HipData> AnimatorHips = new List<HipData>();

	public static ImprovedPhysics Instance { get; private set; }

	private void Awake()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Expected O, but got Unknown
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Expected O, but got Unknown
		((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
		Harmony val = new Harmony("com.example.ImprovedPhysics2");
		val.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
		isHipUnlock = Chainloader.PluginInfos.ContainsKey("com.morsecodeguy.hipunlocker");
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"hipUnlock:{isHipUnlock}");
		configUseRealisticHipUnlocker = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseRealisticHipUnlocker", true, new ConfigDescription("If true, the realistic hip unlocker behaviour will be applied when hipunlock plugin is present.", (AcceptableValueBase)null, Array.Empty<object>()));
		configUseWeaponClash = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseWeaponClash", true, new ConfigDescription("If true, the stagger occars when weapon and weapon collided.", (AcceptableValueBase)null, Array.Empty<object>()));
		LoadConfig();
		SceneManager.sceneLoaded += OnSceneLoaded;
		((MonoBehaviour)this).StartCoroutine(SetPrefabPhysics());
		((MonoBehaviour)this).StartCoroutine(FloorColliderSetting());
		toggleMenuAction = new InputAction("ToggleMenu", (InputActionType)1, "<Keyboard>/f8", (string)null, (string)null, (string)null);
		toggleMenuAction.performed += delegate
		{
			showMenu = !showMenu;
		};
		toggleMenuAction.Enable();
		Instance = this;
	}

	private void OnDestroy()
	{
		if (toggleMenuAction != null)
		{
			toggleMenuAction.Disable();
			toggleMenuAction.performed -= delegate
			{
				showMenu = !showMenu;
			};
			toggleMenuAction.Dispose();
			toggleMenuAction = null;
		}
		SceneManager.sceneLoaded -= OnSceneLoaded;
		if (hipUnlockCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(hipUnlockCoroutine);
			hipUnlockCoroutine = null;
		}
	}

	private void OnEnable()
	{
	}

	private void OnDisable()
	{
	}

	private void LoadConfig()
	{
		UseRealisticHipUnlocker = configUseRealisticHipUnlocker.Value;
		UseWeaponClashScript = configUseWeaponClash.Value;
		ApplyHipUnlockSetting();
		EnabeleOrDisableWeaponClashScript(UseWeaponClashScript);
	}

	private void SaveConfig()
	{
		configUseRealisticHipUnlocker.Value = UseRealisticHipUnlocker;
		configUseWeaponClash.Value = UseWeaponClashScript;
		((BaseUnityPlugin)this).Config.Save();
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Config saved: UseRealisticHipUnlocker = {UseRealisticHipUnlocker}");
		ApplyHipUnlockSetting();
		EnabeleOrDisableWeaponClashScript(UseWeaponClashScript);
	}

	private void ApplyHipUnlockSetting()
	{
		if (!isHipUnlock)
		{
			if (hipUnlockCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(hipUnlockCoroutine);
				hipUnlockCoroutine = null;
			}
		}
		else if (UseRealisticHipUnlocker)
		{
			if (hipUnlockCoroutine == null)
			{
				hipUnlockCoroutine = ((MonoBehaviour)this).StartCoroutine(HipUnlocks());
			}
		}
		else if (hipUnlockCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(hipUnlockCoroutine);
			hipUnlockCoroutine = null;
		}
	}

	private void EnabeleOrDisableWeaponClashScript(bool enableWeaponClashScript)
	{
		if (!enableWeaponClashScript)
		{
			WeaponClashScript[] array = Resources.FindObjectsOfTypeAll<WeaponClashScript>();
			Debug.Log((object)$"clashScripts{array}");
			WeaponClashScript[] array2 = array;
			foreach (WeaponClashScript weaponClashScript in array2)
			{
				Debug.Log((object)("WeaponClashScript from " + ((Object)((Component)weaponClashScript).gameObject).name));
				Debug.Log((object)$"Setting {enableWeaponClashScript} WeaponClashScript from {((Object)((Component)weaponClashScript).gameObject).name}");
				Object.Destroy((Object)(object)weaponClashScript);
			}
			return;
		}
		Rigidbody[] array3 = Resources.FindObjectsOfTypeAll<Rigidbody>();
		Rigidbody[] array4 = array3;
		foreach (Rigidbody val in array4)
		{
			if (((Component)val).gameObject.layer == LayerMask.NameToLayer("Weapons"))
			{
				((Component)val).gameObject.AddComponent<WeaponClashScript>();
			}
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		((BaseUnityPlugin)this).Logger.LogInfo((object)("SCENE LOADED: " + ((Scene)(ref scene)).name));
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"[FeelThePunch] OnSceneLoaded: {((Scene)(ref scene)).name}, mode={mode}, time={Time.realtimeSinceStartup}");
		string[] source = new string[7] { "Menu", "Setting", "Preview", "Lobby", "List", "Select", "Option" };
		if (source.Any(((Scene)(ref scene)).name.Contains))
		{
			Debug.Log((object)("dont apply sceneLoaded functions; " + ((Scene)(ref scene)).name));
			return;
		}
		if (((Scene)(ref scene)).name.Contains("Editor"))
		{
			((MonoBehaviour)this).StartCoroutine(SetPrefabPhysics());
		}
		if (isHipUnlock)
		{
			((MonoBehaviour)this).StartCoroutine(DelayedSetup());
		}
		((MonoBehaviour)this).StartCoroutine(FloorColliderSetting());
	}

	public IEnumerator HipUnlocks()
	{
		while (true)
		{
			for (int i = AnimatorHips.Count - 1; i >= 0; i--)
			{
				HipData hipData = AnimatorHips[i];
				if ((Object)(object)hipData.hip == (Object)null)
				{
					AnimatorHips.RemoveAt(i);
				}
				else if (!((Object)(object)hipData.hip.GetComponentInParent<PlayerHealth>() == (Object)null))
				{
					float angle = Vector3.Angle(hipData.hip.transform.up, Vector3.up);
					List<FighterJoint> fjs = hipData.hip.GetComponentInParent<PlayerHealth>().playerAnimator.FighterJoints;
					foreach (FighterJoint fj in fjs)
					{
						if (fj == null || (Object)(object)fj.jointStrength == (Object)null || fj.jointStrength.jointName != "HIP" || (Object)(object)fj.jointStrength.joint == (Object)null)
						{
							continue;
						}
						JointDrive drive = fj.jointStrength.joint.angularXDrive;
						if (angle > 20f && !hipData.Grounder.GetIsGrounded())
						{
							if (!hipData.wasTilted)
							{
								((JointDrive)(ref drive)).positionDamper = 1f;
								((JointDrive)(ref drive)).positionSpring = 1f;
								fj.jointStrength.joint.angularXDrive = drive;
								fj.jointStrength.joint.angularYZDrive = drive;
								hipData.wasTilted = true;
							}
						}
						else if (hipData.wasTilted)
						{
							((JointDrive)(ref drive)).positionDamper = hipData.defaultDamper;
							((JointDrive)(ref drive)).positionSpring = hipData.defaultSpring;
							fj.jointStrength.joint.angularXDrive = drive;
							fj.jointStrength.joint.angularYZDrive = drive;
							hipData.wasTilted = false;
						}
						drive = default(JointDrive);
					}
				}
			}
			yield return (object)new WaitForSeconds(0.05f);
		}
	}

	private IEnumerator SetPrefabPhysics()
	{
		yield return (object)new WaitForSeconds(2f);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"setting physics of HideAndDontSave");
		List<GameObject> weapons = new List<GameObject>();
		Rigidbody[] rigidbodies = Resources.FindObjectsOfTypeAll<Rigidbody>();
		PhysicsMaterial mat = new PhysicsMaterial("WeaponBouncy");
		mat.bounciness = 0.8f;
		mat.bounceCombine = (PhysicsMaterialCombine)2;
		mat.staticFriction = 0.9f;
		mat.dynamicFriction = 0.9f;
		mat.frictionCombine = (PhysicsMaterialCombine)0;
		Rigidbody[] array = rigidbodies;
		foreach (Rigidbody rb in array)
		{
			Collider[] colliders = ((Component)rb).GetComponentsInChildren<Collider>();
			if ((Object)(object)((Component)rb).GetComponent<RigidbodyAutoConfig>() == (Object)null)
			{
				((Component)rb).gameObject.AddComponent<RigidbodyAutoConfig>();
			}
			if (((Component)rb).gameObject.layer == LayerMask.NameToLayer("Weapons"))
			{
				weapons.Add(((Component)rb).gameObject);
				Collider[] array2 = colliders;
				foreach (Collider col in array2)
				{
					col.material = mat;
				}
			}
		}
		EnabeleOrDisableWeaponClashScript(UseWeaponClashScript);
		Debug.Log((object)"Improved Physics!");
		Debug.Log((object)"Improved Physics!");
		Debug.Log((object)"Improved Physics!");
		Debug.Log((object)"Improved Physics!");
	}

	private IEnumerator FloorColliderSetting()
	{
		yield return (object)new WaitForSeconds(0.1f);
		PhysicsMaterial[] mats = Resources.FindObjectsOfTypeAll<PhysicsMaterial>();
		Debug.Log((object)$"Found {mats.Length} PhysicMaterials:");
		PhysicsMaterial[] array = mats;
		foreach (PhysicsMaterial mat in array)
		{
			if (((Object)mat).name == "Floor_GladioMori")
			{
				mat.bounciness = 0.1f;
				mat.bounceCombine = (PhysicsMaterialCombine)2;
				mat.frictionCombine = (PhysicsMaterialCombine)0;
				Debug.Log((object)$"- {((Object)mat).name} | StaticFriction={mat.staticFriction} | DynamicFriction={mat.dynamicFriction} | Bounciness={mat.bounciness}");
			}
		}
	}

	public IEnumerator DelayedSetup()
	{
		yield return (object)new WaitForSecondsRealtime(2f);
		PlayerHealth[] players = Object.FindObjectsByType<PlayerHealth>((FindObjectsSortMode)0);
		AnimatorHips.Clear();
		PlayerHealth[] array = players;
		foreach (PlayerHealth player in array)
		{
			if (!((Object)(object)player.playerAnimator != (Object)null) || ((Component)player.playerAnimator).transform.childCount <= 0)
			{
				continue;
			}
			GameObject hipGO = ((Component)((Component)player.playerAnimator).transform.GetChild(0)).gameObject;
			FighterJoint fj = ((IEnumerable<FighterJoint>)player.playerAnimator.FighterJoints).FirstOrDefault((Func<FighterJoint, bool>)((FighterJoint f) => f != null && f.jointStrength.jointName == "HIP"));
			if (fj != null)
			{
				JointDrive angularXDrive = fj.jointStrength.joint.angularXDrive;
				float damper = ((JointDrive)(ref angularXDrive)).positionDamper;
				angularXDrive = fj.jointStrength.joint.angularXDrive;
				float spring = ((JointDrive)(ref angularXDrive)).positionSpring;
				if (isHipUnlock && UseRealisticHipUnlocker)
				{
					CharacterGroundChecker Grounder = ((Component)player).gameObject.AddComponent<CharacterGroundChecker>();
					AnimatorHips.Add(new HipData(hipGO, damper, spring, Grounder));
				}
			}
		}
		if (isHipUnlock && UseRealisticHipUnlocker && hipUnlockCoroutine == null)
		{
			hipUnlockCoroutine = ((MonoBehaviour)this).StartCoroutine(HipUnlocks());
		}
	}

	private void OnGUI()
	{
		//IL_0033: 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_0088: 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_00e7: 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_0144: Unknown result type (might be due to invalid IL or missing references)
		if (showMenu)
		{
			int num = 400;
			int num2 = 400;
			GUI.Box(new Rect((float)num2 - 10f, (float)num, 360f, 160f), "Reimagined Physics Config");
			num += 30;
			GUI.Label(new Rect((float)num2, (float)num, 320f, 20f), $"Use Realistic Hip Unlocker: {UseRealisticHipUnlocker}");
			UseRealisticHipUnlocker = GUI.Toggle(new Rect((float)num2, (float)(num + 20), 320f, 20f), UseRealisticHipUnlocker, "Enable realistic hip unlock behaviour");
			num += 40;
			GUI.Label(new Rect((float)num2, (float)num, 320f, 20f), $"Use Weapon Clash Stagger : {UseWeaponClashScript}");
			UseWeaponClashScript = GUI.Toggle(new Rect((float)num2, (float)(num + 20), 320f, 20f), UseWeaponClashScript, "Enable weapon clash stagger behaviour");
			num += 60;
			if (GUI.Button(new Rect((float)num2, (float)num, 160f, 30f), "Apply Settings"))
			{
				SaveConfig();
			}
			if (GUI.Button(new Rect((float)(num2 + 180), (float)num, 160f, 30f), "Reset to Default"))
			{
				UseRealisticHipUnlocker = true;
				UseWeaponClashScript = true;
				SaveConfig();
			}
		}
	}
}
public class CharacterGroundChecker : MonoBehaviour
{
	[Tooltip("Grace time (seconds) to keep the character considered grounded after losing contact.")]
	[SerializeField]
	private float coyoteTime = 0.08f;

	private List<FootGroundSensor> sensors = new List<FootGroundSensor>();

	private float lastGroundedTime = float.NegativeInfinity;

	public bool IsGrounded { get; private set; }

	private void Start()
	{
		Rigidbody[] componentsInChildren = ((Component)this).GetComponentsInChildren<Rigidbody>();
		Rigidbody[] array = componentsInChildren;
		foreach (Rigidbody val in array)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)((Component)val).gameObject).name.IndexOf("knee", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				FootGroundSensor footGroundSensor = ((Component)val).gameObject.AddComponent<FootGroundSensor>();
				footGroundSensor.Owner = this;
				sensors.Add(footGroundSensor);
			}
		}
	}

	public bool GetIsGrounded()
	{
		bool flag = false;
		for (int i = 0; i < sensors.Count; i++)
		{
			FootGroundSensor footGroundSensor = sensors[i];
			if (!((Object)(object)footGroundSensor == (Object)null) && footGroundSensor.IsFootGrounded)
			{
				flag = true;
				break;
			}
		}
		if (flag)
		{
			IsGrounded = true;
			lastGroundedTime = Time.fixedTime;
			return IsGrounded;
		}
		if (Time.fixedTime - lastGroundedTime <= coyoteTime)
		{
			IsGrounded = true;
			return IsGrounded;
		}
		IsGrounded = false;
		return IsGrounded;
	}

	public void SetCoyoteTime(float seconds)
	{
		coyoteTime = Mathf.Max(0f, seconds);
	}
}
public class FootGroundSensor : MonoBehaviour
{
	public CharacterGroundChecker Owner;

	private float lastStayTime;

	[SerializeField]
	private float stayGrace = 0.04f;

	public bool IsFootGrounded => Time.fixedTime - lastStayTime <= stayGrace;

	private void OnCollisionStay(Collision collision)
	{
		if (IsFloor(collision))
		{
			lastStayTime = Time.fixedTime;
		}
	}

	private bool IsFloor(Collision collision)
	{
		Collider collider = collision.collider;
		PhysicsMaterial val = ((collider != null) ? collider.sharedMaterial : null);
		return (Object)(object)val != (Object)null && ((Object)val).name.IndexOf("floor", StringComparison.OrdinalIgnoreCase) >= 0;
	}
}
[RequireComponent(typeof(Rigidbody))]
public class WeaponClashScript : MonoBehaviour
{
	[Tooltip("Scale applied to collision impulse to produce visible bounce.")]
	[SerializeField]
	private float forceMultiplier = 0.4f;

	[Tooltip("Maximum impulse magnitude to avoid extreme launches.")]
	[SerializeField]
	private float maxImpulse = 50f;

	private bool isMoveEditor = true;

	private bool clashEnabled = true;

	public void SetEnable(bool enable)
	{
		clashEnabled = enable;
		Debug.Log((object)$"clashEnabled{clashEnabled}");
	}

	private void Awake()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).name == "MoveEditor")
		{
			Object.Destroy((Object)(object)this);
		}
		else
		{
			isMoveEditor = false;
		}
	}

	private void OnCollisionEnter(Collision collision)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: 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_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		if (!clashEnabled || isMoveEditor || collision.gameObject.layer != LayerMask.NameToLayer("Weapons"))
		{
			return;
		}
		Rigidbody rigidbody = collision.rigidbody;
		if ((Object)(object)rigidbody == (Object)null)
		{
			return;
		}
		ContactPoint[] contacts = collision.contacts;
		if (contacts == null || contacts.Length == 0)
		{
			return;
		}
		Vector3 impulse = collision.impulse;
		if (((Vector3)(ref impulse)).magnitude < 5f || (Object)(object)((Component)this).GetComponentInParent<PlayerHealth>() == (Object)(object)((Component)collision.rigidbody).gameObject.GetComponentInParent<PlayerHealth>())
		{
			return;
		}
		Vector3 val = Vector3.zero;
		for (int i = 0; i < contacts.Length; i++)
		{
			val += ((ContactPoint)(ref contacts[i])).point;
		}
		val /= (float)contacts.Length;
		impulse = collision.impulse;
		float num = ((Vector3)(ref impulse)).magnitude * forceMultiplier;
		num = Mathf.Min(num, maxImpulse);
		Weapon component = ((Component)rigidbody).GetComponent<Weapon>();
		Equipment component2 = ((Component)rigidbody).GetComponent<Equipment>();
		if ((Object)(object)component != (Object)null)
		{
			List<Hand> grabbingHands = ((Equipment)component).GetGrabbingHands();
			if (grabbingHands != null && grabbingHands.Count > 0)
			{
				applyStagger(grabbingHands, num, rigidbody, val, collision);
			}
		}
		if ((Object)(object)component2 != (Object)null)
		{
			List<Hand> grabbingHands2 = component2.GetGrabbingHands();
			if (grabbingHands2 != null && grabbingHands2.Count > 0)
			{
				applyStagger(grabbingHands2, num, rigidbody, val, collision);
			}
		}
	}

	public void applyStagger(List<Hand> hands, float impulse, Rigidbody otherRB, Vector3 hitPoint, Collision collision)
	{
		//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_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: 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_0136: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp(impulse * (3.2f / Mathf.Log(otherRB.mass + 1f)), 1f, 100f);
		if (hands.Count == 2)
		{
			Hand val = hands[0];
			Hand val2 = hands[1];
			float num2 = Vector3.Distance(((Component)val).transform.position, hitPoint);
			float num3 = Vector3.Distance(((Component)val2).transform.position, hitPoint);
			float num4 = num2 + num3 + 0.001f;
			float num5 = num3;
			float num6 = num2;
			float num7 = Vector3.Distance(((Component)val).transform.position, ((Component)val2).transform.position);
			float num8 = Mathf.Clamp01((0.1f + num7) / 1f);
			float num9 = num * (2f - num8);
			ApplyStaggerToHand(val, num9 * num5 / 2f, otherRB, hitPoint);
			ApplyStaggerToHand(val2, num9 * num6 / 2f, otherRB, hitPoint);
		}
		else
		{
			foreach (Hand hand in hands)
			{
				float num10 = Vector3.Distance(((Component)hand).transform.position, hitPoint);
				float reducePercent = num * num10;
				ApplyStaggerToHand(hand, reducePercent, otherRB, hitPoint);
			}
		}
		Transform parent = ((Component)hands[0]).gameObject.transform.parent.parent.parent.parent.parent.parent.parent;
		Vector3 val3 = hitPoint - parent.position;
		val3.y = 0f;
		Vector3 impulse2 = collision.impulse;
		impulse2.y = 0f;
		Vector3 val4 = Vector3.Cross(val3, impulse2);
		float magnitude = ((Vector3)(ref val4)).magnitude;
		ApplyStaggerToHip(parent, magnitude);
	}

	private void ApplyStaggerToHip(Transform hip, float hipTorque)
	{
		float num = Mathf.Clamp(hipTorque * 0.6f, 10f, 150f);
		float num2 = num * 0.3f;
		JointStrength component = ((Component)hip).GetComponent<JointStrength>();
		JointStrength val = ((Component)hip).GetComponents<JointStrength>()[2];
		JointStrength component2 = ((Component)((Joint)((Component)hip).GetComponents<ConfigurableJoint>()[2]).connectedBody).GetComponent<JointStrength>();
		JointStrength val2 = ((Component)hip).GetComponents<JointStrength>()[3];
		JointStrength component3 = ((Component)((Joint)((Component)hip).GetComponents<ConfigurableJoint>()[3]).connectedBody).GetComponent<JointStrength>();
		component.currentPercent -= num;
		component.updateStrengthPercent = true;
		val.currentPercent -= num2;
		val.updateStrengthPercent = true;
		component2.currentPercent -= num2;
		component2.updateStrengthPercent = true;
		val2.currentPercent -= num2;
		val2.updateStrengthPercent = true;
		component3.currentPercent -= num2;
		component3.updateStrengthPercent = true;
		float waitTime = Mathf.Min(hipTorque / 300f, 0.7f);
		((MonoBehaviour)this).StartCoroutine(RestoreHipAfterImpact(component, val, component2, val2, component3, waitTime, num, num2));
	}

	public IEnumerator RestoreHipAfterImpact(JointStrength hipStrength, JointStrength hipJointLeftStrength, JointStrength kneeLeftStrength, JointStrength hipJointRightStrength, JointStrength kneeRightStrength, float waitTime, float hipIncreasePercent, float legIncreasePercent)
	{
		yield return (object)new WaitForSeconds(waitTime * 0.15f);
		hipStrength.currentPercent += hipIncreasePercent * 0.5f;
		hipJointLeftStrength.currentPercent += legIncreasePercent * 0.2f;
		kneeLeftStrength.currentPercent += legIncreasePercent * 0.2f;
		hipJointRightStrength.currentPercent += legIncreasePercent * 0.2f;
		kneeRightStrength.currentPercent += legIncreasePercent * 0.2f;
		hipStrength.updateStrengthPercent = true;
		hipJointLeftStrength.updateStrengthPercent = true;
		kneeLeftStrength.updateStrengthPercent = true;
		hipJointRightStrength.updateStrengthPercent = true;
		kneeRightStrength.updateStrengthPercent = true;
		yield return (object)new WaitForSeconds(waitTime * 0.35f);
		hipStrength.currentPercent += hipIncreasePercent * 0.25f;
		hipJointLeftStrength.currentPercent += legIncreasePercent * 0.4f;
		kneeLeftStrength.currentPercent += legIncreasePercent * 0.4f;
		hipJointRightStrength.currentPercent += legIncreasePercent * 0.4f;
		kneeRightStrength.currentPercent += legIncreasePercent * 0.4f;
		hipStrength.updateStrengthPercent = true;
		hipJointLeftStrength.updateStrengthPercent = true;
		kneeLeftStrength.updateStrengthPercent = true;
		hipJointRightStrength.updateStrengthPercent = true;
		kneeRightStrength.updateStrengthPercent = true;
		yield return (object)new WaitForSeconds(waitTime * 0.5f);
		hipStrength.currentPercent += hipIncreasePercent * 0.25f;
		hipJointLeftStrength.currentPercent += legIncreasePercent * 0.4f;
		kneeLeftStrength.currentPercent += legIncreasePercent * 0.4f;
		hipJointRightStrength.currentPercent += legIncreasePercent * 0.4f;
		kneeRightStrength.currentPercent += legIncreasePercent * 0.4f;
		hipStrength.updateStrengthPercent = true;
		hipJointLeftStrength.updateStrengthPercent = true;
		kneeLeftStrength.updateStrengthPercent = true;
		hipJointRightStrength.updateStrengthPercent = true;
		kneeRightStrength.updateStrengthPercent = true;
	}

	private void ApplyStaggerToHand(Hand hand, float reducePercent, Rigidbody otherRB, Vector3 hitPoint)
	{
		JointStrength componentInParent = ((Component)hand).gameObject.GetComponentInParent<JointStrength>();
		JointStrength component = ((Component)((Component)componentInParent).gameObject.transform.parent).GetComponent<JointStrength>();
		JointStrength component2 = ((Component)((Component)component).gameObject.transform.parent).GetComponent<JointStrength>();
		JointStrength component3 = ((Component)((Component)component2).gameObject.transform.parent).GetComponent<JointStrength>();
		componentInParent.currentPercent -= reducePercent * 0.5f * 2f;
		component.currentPercent -= reducePercent * 1f * 2f;
		component2.currentPercent -= reducePercent * 0.5f * 2f;
		component3.currentPercent -= reducePercent * 0.25f * 2f;
		componentInParent.updateStrengthPercent = true;
		component.updateStrengthPercent = true;
		component2.updateStrengthPercent = true;
		component3.updateStrengthPercent = true;
		float waitTime = Mathf.Min(reducePercent / 25f / otherRB.mass, 1f);
		((MonoBehaviour)this).StartCoroutine(RestoreLimbsAfterImpact(componentInParent, component, component2, component3, waitTime, reducePercent));
	}

	public IEnumerator RestoreLimbsAfterImpact(JointStrength wrist, JointStrength elbow, JointStrength shoulder, JointStrength scapula, float waitTime, float increasePercent)
	{
		yield return (object)new WaitForSeconds(waitTime * 0.15f);
		wrist.currentPercent += increasePercent * 0.5f * 1f;
		elbow.currentPercent += increasePercent * 1f * 1f;
		shoulder.currentPercent += increasePercent * 0.5f * 1f;
		scapula.currentPercent += increasePercent * 0.25f * 1f;
		wrist.updateStrengthPercent = true;
		elbow.updateStrengthPercent = true;
		shoulder.updateStrengthPercent = true;
		scapula.updateStrengthPercent = true;
		yield return (object)new WaitForSeconds(waitTime * 0.35f);
		wrist.currentPercent += increasePercent * 0.5f * 0.5f;
		elbow.currentPercent += increasePercent * 1f * 0.5f;
		shoulder.currentPercent += increasePercent * 0.5f * 0.5f;
		scapula.currentPercent += increasePercent * 0.25f * 0.5f;
		wrist.updateStrengthPercent = true;
		elbow.updateStrengthPercent = true;
		shoulder.updateStrengthPercent = true;
		scapula.updateStrengthPercent = true;
		yield return (object)new WaitForSeconds(waitTime * 0.5f);
		wrist.currentPercent += increasePercent * 0.5f * 0.5f;
		elbow.currentPercent += increasePercent * 1f * 0.5f;
		shoulder.currentPercent += increasePercent * 0.5f * 0.5f;
		scapula.currentPercent += increasePercent * 0.25f * 0.5f;
		wrist.updateStrengthPercent = true;
		elbow.updateStrengthPercent = true;
		shoulder.updateStrengthPercent = true;
		scapula.updateStrengthPercent = true;
	}
}
[HarmonyPatch(typeof(PlayerJointHelpers))]
public static class PlayerJointHelpersPatch
{
	[HarmonyPatch("GetMaxForceForJointType")]
	[HarmonyPrefix]
	public static bool GetMaxForceForJointType_Prefix(JointType jointType, bool legacy, ref float __result)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Expected I4, but got Unknown
		float num = 0.4f;
		float num2 = 0.4f;
		if (legacy)
		{
			__result = float.MaxValue;
			return false;
		}
		float num3 = 100f;
		switch ((int)jointType)
		{
		case 0:
			num3 = 2500f;
			break;
		case 12:
		case 13:
			num3 = 1500f * num2;
			break;
		case 14:
		case 15:
			num3 = 1500f * num2;
			break;
		case 11:
			num3 = 150f;
			break;
		case 1:
			num3 = 1400f * num;
			break;
		case 2:
			num3 = 1400f * num;
			break;
		case 3:
		case 4:
			num3 = 800f * num;
			break;
		case 5:
		case 6:
			num3 = 646f * num;
			break;
		case 7:
		case 8:
			num3 = 476f * num;
			break;
		case 9:
		case 10:
			num3 = 300f * num;
			break;
		}
		__result = num3;
		return false;
	}

	[HarmonyPatch("GetMaxJointSpringForJointType")]
	[HarmonyPrefix]
	public static bool GetMaxJointSpringForJointType_Prefix(JointType jointType, bool legacy, ref float __result)
	{
		//IL_0029: 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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected I4, but got Unknown
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		float num = 1.4f;
		float num2 = 1.4f;
		if (legacy)
		{
			__result = PlayerJointHelpers.GetMaxJointSpringForJointTypeLegacy(jointType);
			return false;
		}
		float num3 = 100f;
		switch ((int)jointType)
		{
		case 0:
			num3 = 10000f;
			break;
		case 12:
		case 13:
		case 14:
		case 15:
			num3 = 10000f * num2;
			break;
		case 11:
			num3 = 1000f;
			break;
		case 1:
		case 2:
			num3 = 7000f * num;
			break;
		case 3:
		case 4:
			num3 = 4000f * num;
			break;
		case 5:
		case 6:
			num3 = 1700f * num;
			break;
		case 7:
		case 8:
			num3 = 1700f * num;
			break;
		case 9:
		case 10:
			num3 = 1000f * num;
			break;
		}
		__result = num3;
		return false;
	}
}
[HarmonyPatch(typeof(Blade))]
public static class BladeCuttingPatch
{
	[HarmonyPatch("CheckBoneBreak")]
	[HarmonyPrefix]
	public static bool CheckBoneBreak_Prefix(Blade __instance, IWeaponDamageable damageable, Collider collision, ref bool __result, float collisionMagnitude = -1f)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_007a: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)collision.attachedRigidbody == (Object)null)
		{
			__result = false;
			return false;
		}
		Vector3 val = collision.ClosestPoint(((Component)__instance).gameObject.transform.position);
		Vector3 val2 = __instance.bladeTriggerCollider.ClosestPoint(((Component)collision.attachedRigidbody).transform.position);
		Vector3 val3 = (val + val2) / 2f;
		if (collisionMagnitude < 0f)
		{
			Vector3 pointVelocity = collision.attachedRigidbody.GetPointVelocity(val3);
			Vector3 pointVelocity2 = __instance.weaponRigidbody.GetPointVelocity(val3);
			Vector3 val4 = pointVelocity - pointVelocity2;
			float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
			Vector3 up = ((Component)__instance.bladeTriggerCollider).transform.up;
			Vector3 normalized = ((Vector3)(ref up)).normalized;
			float num = Vector3.Dot(val4, normalized);
			float num2 = Mathf.Abs(num) * 1f;
			collisionMagnitude = sqrMagnitude + num2;
		}
		float num3 = ((!__instance.IsStabbing(collision)) ? (collisionMagnitude * __instance.slashBoneMultiplier) : (collisionMagnitude * __instance.stabBoneMultiplier));
		if (num3 > 9f)
		{
			__result = true;
			return false;
		}
		__result = false;
		return false;
	}
}
[HarmonyPatch(typeof(Blade))]
public static class BladeCuttingJointPatch
{
	private static readonly FieldInfo forceNotAsleepField = AccessTools.Field(typeof(Blade), "forceNotAsleepThisFrame");

	private static readonly FieldInfo cutResistanceField = AccessTools.Field(typeof(Blade), "cutResistanceIncreaseVariable");

	private static readonly FieldInfo collisionEnterPosField = AccessTools.Field(typeof(Blade), "collisionEnterPos");

	private static readonly MethodInfo addPenetratingMethod = AccessTools.Method(typeof(Blade), "AddPenetratingGameObject", (Type[])null, (Type[])null);

	[HarmonyPatch("HandleBladeCutStart")]
	[HarmonyPrefix]
	public static bool HandleBladeCutStart_Prefix(Blade __instance, Collider collision, IBlade iBlade)
	{
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Unknown result type (might be due to invalid IL or missing references)
		//IL_032e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		forceNotAsleepField.SetValue(__instance, true);
		GameObject gameObject = ((Component)collision).gameObject;
		IWeaponDamageable component = ((Component)((Component)collision).transform).GetComponent<IWeaponDamageable>();
		if (component == null && (Object)(object)((Component)collision).transform.parent != (Object)null)
		{
			component = ((Component)((Component)collision).transform.parent).GetComponent<IWeaponDamageable>();
			gameObject = ((Component)((Component)collision).transform.parent).gameObject;
		}
		if (component != null)
		{
			if (component.IsOrgan())
			{
				if (__instance.disableLocalLogic)
				{
					return false;
				}
				if (component.IsBone())
				{
					if (__instance.CheckBoneBreak(component, collision, -1f))
					{
						component.Destory((DamageOrigin?)null, true);
					}
				}
				else
				{
					component.Destory((DamageOrigin?)null, true);
				}
				return false;
			}
			__instance.bladePenetrating = true;
			__instance.colliderTagName = ((Component)collision).gameObject.tag;
			((Component)collision).GetComponents<Collider>();
			addPenetratingMethod.Invoke(__instance, new object[5]
			{
				gameObject,
				collision,
				iBlade,
				component.bladePaintables,
				component.GetCuttableGameObjects()
			});
			if (__instance.disableLocalLogic)
			{
				return false;
			}
			collisionEnterPosField.SetValue(__instance, ((Component)__instance).gameObject.transform.position);
			object obj = ((Component)collision).GetComponent<Rigidbody>();
			if (obj == null)
			{
				Transform parent = ((Component)collision).transform.parent;
				obj = ((parent != null) ? ((Component)parent).GetComponent<Rigidbody>() : null);
			}
			Rigidbody val = (Rigidbody)obj;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if ((Object)(object)__instance.joint == (Object)null || (Object)(object)((Joint)__instance.joint).connectedBody == (Object)null)
			{
				ConfigurableJoint val2 = (__instance.joint = ((Component)__instance.weaponRigidbody).gameObject.AddComponent<ConfigurableJoint>());
				((Joint)val2).anchor = __instance.dragPoint.transform.localPosition;
				((Joint)val2).connectedBody = val;
				val2.angularXMotion = (ConfigurableJointMotion)2;
				val2.angularYMotion = (ConfigurableJointMotion)0;
				val2.angularZMotion = (ConfigurableJointMotion)0;
				val2.xMotion = (ConfigurableJointMotion)0;
				val2.yMotion = (ConfigurableJointMotion)2;
				val2.zMotion = (ConfigurableJointMotion)2;
				((Joint)val2).enableCollision = true;
				float num = 3000f;
				float num2 = (float)cutResistanceField.GetValue(__instance);
				float num3 = 1000f * __instance.slashMultiplier - num2;
				float num4 = 1000f * __instance.stabMultiplier;
				num3 = Mathf.Min(num3, num);
				num4 = Mathf.Min(num4, num);
				float num5 = 2f;
				float positionDamper = Mathf.Max(50f, num - num3 * num5);
				float positionDamper2 = Mathf.Max(50f, num - num4 * num5);
				JointDrive val3 = default(JointDrive);
				((JointDrive)(ref val3)).positionSpring = 0f;
				((JointDrive)(ref val3)).positionDamper = positionDamper;
				((JointDrive)(ref val3)).maximumForce = float.MaxValue;
				JointDrive val4 = val3;
				val3 = default(JointDrive);
				((JointDrive)(ref val3)).positionSpring = 0f;
				((JointDrive)(ref val3)).positionDamper = positionDamper2;
				((JointDrive)(ref val3)).maximumForce = float.MaxValue;
				JointDrive val5 = val3;
				val2.angularXDrive = val4;
				val2.angularYZDrive = val4;
				val2.xDrive = val5;
				val2.yDrive = val5;
				val2.zDrive = val4;
			}
			else
			{
				((Joint)__instance.joint).connectedBody = val;
			}
		}
		else
		{
			object obj2 = ((Component)((Component)collision).transform).GetComponent<CuttableObject>();
			if (obj2 == null)
			{
				Transform parent2 = ((Component)collision).transform.parent;
				obj2 = ((parent2 != null) ? ((Component)parent2).GetComponent<CuttableObject>() : null);
			}
			CuttableObject val6 = (CuttableObject)obj2;
			if ((Object)(object)val6 != (Object)null)
			{
				addPenetratingMethod.Invoke(__instance, new object[5]
				{
					((Component)collision).gameObject,
					collision,
					iBlade,
					null,
					null
				});
			}
		}
		return false;
	}
}
[HarmonyPatch]
public static class CalculateKineticEnergyMultiplierPatch
{
	private const float GLOBAL_BLUNT_DAMAGE_MULTIPLIER = 0.33f;

	private const float BODYPART_DAMAGE_COMPENSATION = 4f;

	private const float BODYPARTLEG_DAMAGE_COMPENSATION = 3f;

	private const float GLOBAL_BLUNT_KNOCKBACK_MULTIPLIER = 0.4f;

	private const float BODYPART_KNOCKBACK_COMPENSATION = 1f;

	private const float BODYPARTLEG_KNOCKBACK_COMPENSATION = 1f;

	private static MethodBase TargetMethod()
	{
		Type type = AccessTools.TypeByName("BluntDamageHelpers");
		return AccessTools.Method(type, "CalculateKineticEnergyMultiplier", (Type[])null, (Type[])null);
	}

	private static void Postfix(BluntDamageDealer bluntDamageDealer, Vector3 contactPointLocal, ref Vector3 collisionDirection, ref float __result)
	{
		//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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Invalid comparison between Unknown and I4
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Invalid comparison between Unknown and I4
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		if (bluntDamageDealer != null && !float.IsNaN(__result) && !(__result <= 0f))
		{
			float num = 1f;
			float num2 = 1f;
			BluntDamageType bluntDamageType = bluntDamageDealer.bluntDamageType;
			if ((int)bluntDamageType == 5)
			{
				num = 4f;
				num2 = 1f;
			}
			else if ((int)bluntDamageType == 7)
			{
				num = 3f;
				num2 = 1f;
			}
			float num3 = Mathf.Clamp(0.33f * num, 0f, 10f);
			float num4 = Mathf.Clamp(0.4f * num2, 0f, 10f);
			__result *= num3;
			float magnitude = ((Vector3)(ref collisionDirection)).magnitude;
			if (magnitude > 0f)
			{
				float num5 = Mathf.Clamp(magnitude * num4, 0f, 10f);
				collisionDirection = ((Vector3)(ref collisionDirection)).normalized * num5;
			}
		}
	}
}