Decompiled source of UnnarmedCombat v1.6.28

FeelThePunchMod.dll

Decompiled 2 weeks 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 HarmonyLib;
using MoveClasses;
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("FeelThePunchMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FeelThePunchMod")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("71a8e523-4572-4091-bcc9-e6ec99e7a428")]
[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.feelthepunch", "Feel The Punch", "1.6.28")]
[DisallowMultipleComponent]
public class FeelThePunch : BaseUnityPlugin
{
	private bool showMenu = false;

	private InputAction toggleMenuAction;

	public bool EnableBerserkersDeath = true;

	public bool BerserkerDisarm = true;

	public bool DisarmOnKO = true;

	public float KOKnockbackMultiplier = 10f;

	public float KODurationMultiplier = 10f;

	public static FeelThePunch Instance { get; private set; }

	private void Awake()
	{
		((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
		Instance = this;
		Harmony.CreateAndPatchAll(typeof(FeelThePunch), (string)null);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
		SceneManager.sceneLoaded += OnSceneLoaded;
	}

	private void OnEnable()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		toggleMenuAction = new InputAction("ToggleMenu", (InputActionType)1, "<Keyboard>/f8", (string)null, (string)null, (string)null);
		toggleMenuAction.performed += delegate
		{
			ToggleMenu();
		};
		toggleMenuAction.Enable();
	}

	private void OnDisable()
	{
		toggleMenuAction.Disable();
		toggleMenuAction.performed -= delegate
		{
			ToggleMenu();
		};
	}

	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}");
		((MonoBehaviour)this).StartCoroutine(DelayedSetup());
	}

	public IEnumerator DelayedSetup()
	{
		yield return (object)new WaitForSecondsRealtime(3f);
		Hand[] hands = Object.FindObjectsOfType<Hand>();
		if (hands != null)
		{
			Hand[] array = hands;
			foreach (Hand hand in array)
			{
				if ((Object)(object)((Component)((Component)hand).transform.parent).gameObject.GetComponent<BluntTransmitter>() == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Hand found " + ((Object)((Component)hand).gameObject).name));
					((Component)((Component)hand).transform.parent).gameObject.AddComponent<BluntTransmitter>();
					((Component)((Component)hand).transform.parent).gameObject.GetComponent<Rigidbody>();
					BoxCollider handColl = ((Component)((Component)hand).transform.parent).GetComponentInChildren<BoxCollider>();
					if (!((Object)(object)handColl != (Object)null))
					{
					}
				}
			}
		}
		GameObject[] bodyparts = Object.FindObjectsOfType<GameObject>();
		GameObject[] array2 = bodyparts;
		foreach (GameObject bodypart in array2)
		{
			if (((((Object)bodypart).name.ToLower().Contains("knee") && Object.op_Implicit((Object)(object)bodypart.GetComponent<Rigidbody>())) || (((Object)bodypart).name.ToLower().Contains("elbow") && Object.op_Implicit((Object)(object)bodypart.GetComponent<Rigidbody>())) || (((Object)bodypart).name.ToLower().Contains("neck") && Object.op_Implicit((Object)(object)bodypart.GetComponent<Rigidbody>()))) && (Object)(object)bodypart.gameObject.GetComponent<BluntTransmitter>() == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("bodypart Found " + ((Object)bodypart.gameObject).name));
				bodypart.gameObject.AddComponent<BluntTransmitter>();
			}
		}
	}

	private void ToggleMenu()
	{
		showMenu = !showMenu;
	}

	private void OnGUI()
	{
		//IL_0027: 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_007b: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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)
		if (showMenu)
		{
			GUI.Box(new Rect(10f, 10f, 420f, 240f), "UnarmedCombat Mod Menu");
			EnableBerserkersDeath = GUI.Toggle(new Rect(20f, 40f, 380f, 20f), EnableBerserkersDeath, "Enable Berserker's Death Buff");
			BerserkerDisarm = GUI.Toggle(new Rect(20f, 65f, 380f, 20f), BerserkerDisarm, "Disarm Enemies on Berserker Death");
			DisarmOnKO = GUI.Toggle(new Rect(20f, 90f, 380f, 20f), DisarmOnKO, "Disarm on KO");
			GUI.Label(new Rect(20f, 120f, 400f, 20f), "KO Knockback Multiplier: " + Mathf.RoundToInt(KOKnockbackMultiplier));
			KOKnockbackMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 140f, 380f, 20f), KOKnockbackMultiplier, 0f, 200f));
			GUI.Label(new Rect(20f, 170f, 400f, 20f), "KO Duration Multiplier: " + Mathf.RoundToInt(KODurationMultiplier));
			KODurationMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 190f, 380f, 20f), KODurationMultiplier, 0f, 60f));
		}
	}
}
[DisallowMultipleComponent]
public class BluntTransmitter : MonoBehaviour
{
	public struct ContactInfo
	{
		public Collider closestCollider;

		public Vector3 worldAnchor;

		public Vector3 moverLocalAnchor;

		public Vector3 targetLocalAnchor;
	}

	public float MagicHipSpringX = 0f;

	public float MagicHipDamperX = 0f;

	public float MagicHipStrengthX = 0f;

	public float MagicHipSpringYZ = 0f;

	public float MagicHipDamperYZ = 0f;

	public float MagicHipStrengthYZ = 0f;

	public float forceMultiplier = 2f;

	public float torqueMultiplier = 1f;

	private Rigidbody objectRigidbody;

	private static HashSet<PlayerHealth> recoveringPlayers = new HashSet<PlayerHealth>();

	private static Dictionary<string, float> lastGrabTimes = new Dictionary<string, float>();

	private static HashSet<PlayerHealth> globallyModifiedEnemies = new HashSet<PlayerHealth>();

	private static HashSet<Hand> activeGrapplingHands = new HashSet<Hand>();

	private static Dictionary<PlayerHealth, int> currentlyGrabbedEnemyCounts = new Dictionary<PlayerHealth, int>();

	private static HashSet<PlayerHealth> BerserkerPlayers = new HashSet<PlayerHealth>();

	private static bool isSlowMotionRunning = false;

	public bool runningForce = false;

	private PlayerHealth character;

	private Hand hand;

	private Coroutine forceLoopInstance;

	private float requiredDuration = 7f * (FeelThePunch.Instance.KODurationMultiplier / 10f);

	private Coroutine watchdogCoroutine;

	private List<HandState> stateHistory = new List<HandState>();

	private void Start()
	{
		//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_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if ((Object)(object)FeelThePunch.Instance == (Object)null)
		{
			Debug.Log((object)"UnarmedMod Handler not found.");
		}
		objectRigidbody = ((Component)this).GetComponent<Rigidbody>();
		if ((Object)(object)objectRigidbody == (Object)null)
		{
			Debug.LogError((object)"BluntTransmitter script requires a Rigidbody on the object!");
			Object.Destroy((Object)(object)this);
		}
		character = ((Component)this).GetComponentInParent<PlayerHealth>();
		if ((Object)(object)character == (Object)null)
		{
			Debug.LogError((object)"BluntTransmitter script requires a PlayerHealth on the Character!");
			Object.Destroy((Object)(object)this);
		}
		JointDrive val = character.ballHolderjoint.angularXDrive;
		MagicHipSpringX = ((JointDrive)(ref val)).positionSpring;
		val = character.ballHolderjoint.angularXDrive;
		MagicHipDamperX = ((JointDrive)(ref val)).positionDamper;
		val = character.ballHolderjoint.angularXDrive;
		MagicHipStrengthX = ((JointDrive)(ref val)).maximumForce;
		val = character.ballHolderjoint.angularYZDrive;
		MagicHipSpringYZ = ((JointDrive)(ref val)).positionSpring;
		val = character.ballHolderjoint.angularYZDrive;
		MagicHipDamperYZ = ((JointDrive)(ref val)).positionDamper;
		val = character.ballHolderjoint.angularYZDrive;
		MagicHipStrengthYZ = ((JointDrive)(ref val)).maximumForce;
		watchdogCoroutine = ((MonoBehaviour)this).StartCoroutine(KOWatchdog());
		hand = ((Component)this).GetComponentInChildren<Hand>();
		if ((Object)(object)hand != (Object)null && (Object)(object)character != (Object)null && !((Object)((Component)this).gameObject).name.ToLower().Contains("elbow"))
		{
			Debug.Log((object)("Starting ForceLoop Coroutine" + ((Object)((Component)this).gameObject).name));
			if (forceLoopInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(forceLoopInstance);
			}
			forceLoopInstance = ((MonoBehaviour)this).StartCoroutine(ForceLoop());
		}
	}

	private void OnDisable()
	{
		if (watchdogCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(watchdogCoroutine);
		}
	}

	private IEnumerator KOWatchdog()
	{
		PlayerHealth health = ((Component)this).GetComponentInParent<PlayerHealth>();
		FighterJoint hip = null;
		foreach (FighterJoint joint in health.playerAnimator.FighterJoints)
		{
			if (((Object)joint.jointStrength.joint).name.ToLower() == "hip")
			{
				hip = joint;
			}
		}
		if (hip == null)
		{
			Debug.Log((object)"KO WATCHDOG IS NOT WORKING BECAUSE THE HIP WASNT DETECTED");
		}
		else
		{
			Debug.Log((object)("KO WATCHDO IS RUNNING AS EXPECTED:" + ((Object)hip.jointStrength.joint).name));
		}
		float timer = 0f;
		do
		{
			yield return (object)new WaitForSeconds(1f);
			if (hip.jointStrength.currentPercent <= 5f)
			{
				timer += 1f;
				if (timer >= requiredDuration)
				{
					((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(health, 1f));
					Debug.Log((object)("restored" + health.playerName + "joints because they stayed KOd too long"));
					timer = 0f;
				}
			}
			else
			{
				timer = 0f;
			}
		}
		while (health.alive);
	}

	private void OnCollisionEnter(Collision collision)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		HandleCollision(collision);
		Hand componentInChildren = ((Component)this).gameObject.GetComponentInChildren<Hand>();
		if ((Object)(object)componentInChildren != (Object)null && (int)componentInChildren.handState == 0 && !componentInChildren.grabbed && !((Object)((Component)this).gameObject).name.ToLower().Contains("elbow"))
		{
			((MonoBehaviour)this).StartCoroutine(Grapple(componentInChildren, ((Component)this).gameObject, collision));
		}
	}

	private IEnumerator ForceLoop()
	{
		yield return (object)new WaitForEndOfFrame();
		if (!FeelThePunch.Instance.EnableBerserkersDeath)
		{
			yield break;
		}
		Debug.Log((object)"Starting Ability Listener");
		HandState previousState = hand.handState;
		while ((Object)(object)character != (Object)null)
		{
			HandState currentState = hand.handState;
			if (currentState != previousState)
			{
				stateHistory.Add(currentState);
				if (stateHistory.Count > 8)
				{
					stateHistory.RemoveAt(0);
				}
				if (stateHistory.Count == 8 && (int)stateHistory[0] == 2 && (int)stateHistory[1] == 1 && (int)stateHistory[2] == 0 && (int)stateHistory[3] == 2 && (int)stateHistory[4] == 1 && (int)stateHistory[5] == 0 && (int)stateHistory[6] == 2 && (int)stateHistory[7] == 1)
				{
					((MonoBehaviour)this).StartCoroutine(ActivateForce(hand));
					stateHistory.Clear();
				}
				previousState = currentState;
			}
			else
			{
				stateHistory.Clear();
			}
			yield return (object)new WaitForSeconds(0.25f);
		}
	}

	private IEnumerator ActivateForce(Hand hand)
	{
		PlayerHealth player = ((Component)hand).GetComponentInParent<PlayerHealth>();
		List<ConfigurableJoint> joints = new List<ConfigurableJoint>();
		foreach (FighterJoint fj in player.playerAnimator.FighterJoints)
		{
			if ((Object)(object)fj.jointStrength?.joint != (Object)null)
			{
				joints.Add(fj.jointStrength.joint);
			}
		}
		if (BerserkerPlayers.Contains(player))
		{
			Debug.Log((object)("couldnt activate Berserker's Death Because " + player.playerName + " already activated it"));
			yield break;
		}
		Debug.Log((object)("Activating Berserker's Death for:" + player.playerName));
		BerserkerPlayers.Add(player);
		if (currentlyGrabbedEnemyCounts.ContainsKey(player))
		{
			currentlyGrabbedEnemyCounts.Remove(player);
		}
		foreach (FighterJoint fj2 in player.playerAnimator.FighterJoints)
		{
			fj2.jointStrength.instancesOfDamage = 0;
			fj2.jointStrength.SetStrengthPercent(100f);
		}
		yield return (object)new WaitForSeconds(0.1f);
		Rigidbody[] bodies = ((Component)player).GetComponentsInChildren<Rigidbody>();
		((MonoBehaviour)this).StartCoroutine(ApplyFakeGravity(bodies, joints, 15f));
		List<PlayerHealth> enemies = new List<PlayerHealth>();
		float explosionRadius = 4f;
		float explosionForce = 16f;
		Collider[] colliders = Physics.OverlapSphere(((Component)player.ballHolderjoint).transform.position, explosionRadius, -1, (QueryTriggerInteraction)1);
		Collider[] array = colliders;
		foreach (Collider collider in array)
		{
			Rigidbody rb = collider.attachedRigidbody;
			if (!((Object)(object)rb != (Object)null) || !((Component)rb).gameObject.activeInHierarchy || bodies.Contains(rb))
			{
				continue;
			}
			PlayerHealth enemigo = ((Component)rb).GetComponentInParent<PlayerHealth>();
			float distance = Vector3.Distance(((Component)player.ballHolderjoint).transform.position, ((Component)rb).transform.position);
			float forceApplied = explosionForce / Mathf.Clamp(distance * distance / 2f, 1f, 100f);
			Vector3 val = rb.position - ((Component)player.ballHolderjoint).transform.position;
			Vector3 direction2 = ((Vector3)(ref val)).normalized;
			if ((Object)(object)enemigo != (Object)null && (Object)(object)enemigo != (Object)(object)player)
			{
				if (!enemies.Contains(enemigo))
				{
					Debug.Log((object)(enemigo.playerName + ((Object)enemigo).name + "Is not in the list, KOing them and adding to the list"));
					enemies.Add(enemigo);
					bool Disarm = false;
					if (FeelThePunch.Instance.BerserkerDisarm && distance <= explosionRadius / 2f)
					{
						Disarm = true;
					}
					val = ((Component)enemigo.ballHolderjoint).transform.position - ((Component)player.ballHolderjoint).transform.position;
					direction2 = ((Vector3)(ref val)).normalized;
					((MonoBehaviour)this).StartCoroutine(KO(enemigo, forceApplied * 50f, direction2, forceApplied * 50f, Disarm));
				}
			}
			else
			{
				rb.AddForce(direction2 * forceApplied, (ForceMode)1);
			}
		}
	}

	private IEnumerator ApplyFakeGravity(Rigidbody[] bodies, List<ConfigurableJoint> joints, float duration)
	{
		PlayerHealth player = ((Component)((Component)bodies[0]).transform.root).GetComponentInChildren<PlayerHealth>();
		double bloodAmount = player.bloodAmount;
		float timer = 0f;
		List<JointDrive> storedXDrives = new List<JointDrive>();
		List<JointDrive> storedYZDrives = new List<JointDrive>();
		foreach (ConfigurableJoint joint3 in joints)
		{
			JointDrive xDrive2 = joint3.angularXDrive;
			JointDrive yzDrive2 = joint3.angularYZDrive;
			((JointDrive)(ref xDrive2)).positionSpring = ((JointDrive)(ref xDrive2)).positionSpring * 1.5f;
			((JointDrive)(ref yzDrive2)).positionSpring = ((JointDrive)(ref yzDrive2)).positionSpring * 1.5f;
			joint3.angularXDrive = xDrive2;
			joint3.angularYZDrive = yzDrive2;
			xDrive2 = default(JointDrive);
			yzDrive2 = default(JointDrive);
		}
		foreach (ConfigurableJoint joint2 in joints)
		{
			storedXDrives.Add(joint2.angularXDrive);
			storedYZDrives.Add(joint2.angularYZDrive);
		}
		while (timer < duration)
		{
			if (player.alive)
			{
				for (int i = 0; i < joints.Count; i++)
				{
					if ((Object)(object)joints[i] != (Object)null)
					{
						joints[i].angularXDrive = storedXDrives[i];
						joints[i].angularYZDrive = storedYZDrives[i];
					}
				}
			}
			player.bloodAmount = bloodAmount;
			timer += Time.fixedDeltaTime;
			yield return (object)new WaitForFixedUpdate();
		}
		foreach (ConfigurableJoint joint in joints)
		{
			JointDrive xDrive = joint.angularXDrive;
			JointDrive yzDrive = joint.angularYZDrive;
			((JointDrive)(ref xDrive)).positionSpring = ((JointDrive)(ref xDrive)).positionSpring / 3f;
			((JointDrive)(ref yzDrive)).positionSpring = ((JointDrive)(ref yzDrive)).positionSpring / 3f;
			((JointDrive)(ref xDrive)).positionDamper = ((JointDrive)(ref xDrive)).positionDamper * 200f;
			((JointDrive)(ref yzDrive)).positionDamper = ((JointDrive)(ref yzDrive)).positionDamper * 200f;
			if (((Object)joint).name.ToLower() == "hip")
			{
				((JointDrive)(ref xDrive)).positionSpring = ((JointDrive)(ref xDrive)).positionSpring / 30f;
				((JointDrive)(ref yzDrive)).positionSpring = ((JointDrive)(ref yzDrive)).positionSpring / 30f;
				((JointDrive)(ref yzDrive)).positionDamper = ((JointDrive)(ref yzDrive)).positionDamper / 200f;
				((JointDrive)(ref xDrive)).positionDamper = ((JointDrive)(ref xDrive)).positionDamper / 200f;
			}
			joint.angularXDrive = xDrive;
			joint.angularYZDrive = yzDrive;
			xDrive = default(JointDrive);
			yzDrive = default(JointDrive);
		}
		Debug.Log((object)"TIMER DONE, YOU LOST YOUR STRENGTH");
		yield return (object)new WaitForSeconds(2f);
		yield return (object)new WaitForSeconds(2f);
		player.Die((DeathReason)3);
	}

	public void HandleCollision(Collision collision)
	{
		//IL_0009: 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)
		//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_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_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: 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)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: 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_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: 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_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: 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_0214: 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_0222: 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_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: 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_0252: 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_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: 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_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05db: Unknown result type (might be due to invalid IL or missing references)
		//IL_05de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0600: Unknown result type (might be due to invalid IL or missing references)
		//IL_0605: Unknown result type (might be due to invalid IL or missing references)
		//IL_0615: Unknown result type (might be due to invalid IL or missing references)
		//IL_061a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0622: Unknown result type (might be due to invalid IL or missing references)
		//IL_0672: Unknown result type (might be due to invalid IL or missing references)
		Rigidbody rigidbody = collision.rigidbody;
		Vector3 val = collision.impulse;
		float magnitude = ((Vector3)(ref val)).magnitude;
		if (magnitude < 25f || (Object)(object)rigidbody == (Object)null || (((Object)rigidbody).name.ToLower().Contains("left") && ((Object)((Component)this).gameObject).name.ToLower().Contains("neck")) || (((Object)rigidbody).name.ToLower().Contains("right") && ((Object)((Component)this).gameObject).name.ToLower().Contains("neck")))
		{
			return;
		}
		val = collision.impulse;
		Vector3 val2 = ((Vector3)(ref val)).normalized;
		Vector3 val3 = Vector3.zero;
		int contactCount = collision.contactCount;
		for (int i = 0; i < contactCount; i++)
		{
			Vector3 val4 = val3;
			ContactPoint contact = collision.GetContact(i);
			val3 = val4 + ((ContactPoint)(ref contact)).normal;
		}
		Vector3 normalized = ((Vector3)(ref val3)).normalized;
		if (Vector3.Dot(val2, normalized) > 0f)
		{
			val2 = -val2;
		}
		Vector3 val5 = val2;
		float num = magnitude * forceMultiplier;
		PlayerHealth[] componentsInParent = ((Component)objectRigidbody).GetComponentsInParent<PlayerHealth>();
		PlayerHealth[] componentsInParent2 = ((Component)rigidbody).GetComponentsInParent<PlayerHealth>();
		if (componentsInParent.Intersect(componentsInParent2).Any())
		{
			return;
		}
		Debug.Log((object)$"{((Object)((Component)objectRigidbody).gameObject).name} collided with {((Object)rigidbody).name} with an impulse magnitude of {magnitude}. Impact Force: {num}");
		if (((Object)rigidbody).name.ToLower().Contains("cuttable") || (((Object)rigidbody).name.ToLower().Contains("neck") && ((Object)((Component)rigidbody).transform.parent).name.ToLower().Contains("cuttable")))
		{
			Debug.Log((object)"FOOOOOOOOOTBALL");
			rigidbody.AddForce(val5 * num * 4f, (ForceMode)1);
			val = objectRigidbody.velocity;
			Vector3 val6 = Vector3.Cross(val5, ((Vector3)(ref val)).normalized) * (num * torqueMultiplier);
			rigidbody.AddTorque(val6, (ForceMode)1);
			if ((Object)(object)objectRigidbody != (Object)null)
			{
				Vector3 val7 = -objectRigidbody.velocity * objectRigidbody.mass;
				objectRigidbody.AddForce(val7, (ForceMode)1);
			}
			SphereCollider component = ((Component)rigidbody).GetComponent<SphereCollider>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.Log((object)"Neck found! Adding sphere collider...");
				SphereCollider val8 = ((Component)rigidbody).gameObject.AddComponent<SphereCollider>();
				val8.radius = 0.16f;
				((Collider)val8).isTrigger = false;
				Vector3 center = ((Component)rigidbody).transform.InverseTransformPoint(rigidbody.worldCenterOfMass);
				val8.center = center;
			}
		}
		PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>();
		PlayerHealth[] array2 = array;
		foreach (PlayerHealth val9 in array2)
		{
			Rigidbody[] componentsInChildren = ((Component)val9).GetComponentsInChildren<Rigidbody>();
			Rigidbody[] array3 = componentsInChildren;
			foreach (Rigidbody val10 in array3)
			{
				if (!((Object)(object)val10 == (Object)(object)rigidbody) || ((Component)val10).gameObject.layer == LayerMask.NameToLayer("Weapons"))
				{
					continue;
				}
				string text = ((Object)val10).name.ToLower();
				float num2 = 1f;
				float num3 = 0f;
				if (text.Contains("neck"))
				{
					num2 = 1f;
					num3 = Mathf.Clamp(magnitude / 75f, 0f, 0.5f) * num2;
				}
				else if (text.Contains("left") || text.Contains("right"))
				{
					num2 = 0.4f;
					num3 = Mathf.Clamp(magnitude / 75f, 0f, 0.5f) * num2;
					if (val9.bloodAmount - (double)num3 <= 0.0)
					{
						num3 = 0f;
						JointStrength[] components = ((Component)((Component)val10).transform.parent).GetComponents<JointStrength>();
						JointStrength[] array4 = components;
						foreach (JointStrength val11 in array4)
						{
							bool flag = val11.jointName == ((Object)((Component)val10).gameObject).name;
							string text2 = ((Object)((Component)val10).gameObject).name.ToLower();
							if (flag)
							{
								val11.DealMuscleDamage();
								val11.DealMuscleDamage();
								val11.DealMuscleDamage();
								val11.DealMuscleDamage();
							}
						}
					}
				}
				else
				{
					num2 = 0.8f;
					num3 = Mathf.Clamp(magnitude / 75f, 0f, 0.5f) * num2;
				}
				val9.bloodAmount -= (double)num3;
				val9.UpdateBloodVignette();
				Debug.Log((object)$"{val9.playerName} blood amount is {val9.bloodAmount}");
				if (val9.bloodAmount <= 0.0 && val9.alive)
				{
					val9.Die((DeathReason)3);
					num *= 5f;
					((MonoBehaviour)this).StartCoroutine(DestroyBluntTransmiters(val9));
				}
				if (!text.Contains("left") && !text.Contains("right"))
				{
					rigidbody.AddForce(val5 * num, (ForceMode)1);
					val = objectRigidbody.velocity;
					Vector3 val12 = Vector3.Cross(val5, ((Vector3)(ref val)).normalized) * (num * torqueMultiplier);
					rigidbody.AddTorque(val12, (ForceMode)1);
					if ((Object)(object)objectRigidbody != (Object)null)
					{
						Vector3 val13 = -objectRigidbody.velocity * objectRigidbody.mass;
						objectRigidbody.AddForce(val13, (ForceMode)1);
					}
				}
				if (((num2 >= 0.8f && magnitude >= 47f) || (text.Contains("neck") && magnitude >= 37f)) && !recoveringPlayers.Contains(val9))
				{
					((MonoBehaviour)this).StartCoroutine(KO(val9, magnitude, val5, num, FeelThePunch.Instance.DisarmOnKO));
				}
				else
				{
					if (!Object.op_Implicit((Object)(object)((Component)((Component)val10).transform.parent).GetComponent<JointStrength>()) || !(magnitude < 47f) || !(magnitude > 25f))
					{
						continue;
					}
					JointStrength[] components2 = ((Component)((Component)val10).transform.parent).GetComponents<JointStrength>();
					JointStrength[] array5 = components2;
					foreach (JointStrength val14 in array5)
					{
						bool flag2 = val14.jointName == ((Object)((Component)val10).gameObject).name;
						string text3 = ((Object)((Component)val10).gameObject).name.ToLower();
						if (flag2 && !text3.Contains("elbow") && !text3.Contains("shoulder"))
						{
							((MonoBehaviour)this).StartCoroutine(React(val14, magnitude, val9));
						}
						else if (flag2 && (text3.Contains("elbow") || text3.Contains("shoulder")))
						{
							((MonoBehaviour)this).StartCoroutine(React(val14, magnitude, null));
						}
					}
				}
			}
		}
	}

	private IEnumerator React(JointStrength joint, float impulseMagnitude, PlayerHealth enemy)
	{
		joint.SetStrengthPercent(5f);
		if ((Object)(object)enemy != (Object)null && (Object)(object)enemy.playerAnimator != (Object)null && enemy.playerAnimator.FighterJoints != null)
		{
			foreach (FighterJoint fighterJoint in enemy.playerAnimator.FighterJoints)
			{
				if (((Object)(object)fighterJoint.jointStrength != (Object)null && ((Object)fighterJoint.joint).name.ToLower().Contains("knee")) || ((Object)(object)fighterJoint.jointStrength != (Object)null && ((Object)fighterJoint.joint).name.ToLower().Contains("hip_joint")))
				{
					fighterJoint.jointStrength.SetStrengthPercent(1f);
				}
			}
			((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemy, 0.3f));
			yield return (object)new WaitForSeconds(1f);
		}
		joint.SetStrengthPercent(5f);
		yield return (object)new WaitForSeconds(impulseMagnitude / 20f);
		joint.SetStrengthPercent(100f);
	}

	public IEnumerator KO(PlayerHealth playerCharacter, float impulseMagnitude, Vector3 impactDirection, float impactForce, bool Disarm)
	{
		//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)
		recoveringPlayers.Add(playerCharacter);
		if (playerCharacter.bloodAmount <= 0.0)
		{
			((MonoBehaviour)this).StartCoroutine(GradualSlowMotion(0.3f, 0.5f, 1f));
		}
		if (Disarm)
		{
			((MonoBehaviour)playerCharacter).Invoke("HandleHandsOnDeath", 0.4f);
		}
		Rigidbody[] playerRigidbodies = ((Component)playerCharacter).gameObject.GetComponentsInChildren<Rigidbody>();
		Rigidbody[] array = playerRigidbodies;
		foreach (Rigidbody pr in array)
		{
			pr.AddForce(impactDirection * (impactForce / 8f) * (FeelThePunch.Instance.KOKnockbackMultiplier / 10f), (ForceMode)1);
		}
		ConfigurableJoint ballHolderjoint = playerCharacter.ballHolderjoint;
		JointDrive val = default(JointDrive);
		((JointDrive)(ref val)).positionSpring = 1f;
		((JointDrive)(ref val)).positionDamper = 1f;
		((JointDrive)(ref val)).maximumForce = 1f;
		ballHolderjoint.angularXDrive = val;
		ConfigurableJoint ballHolderjoint2 = playerCharacter.ballHolderjoint;
		val = default(JointDrive);
		((JointDrive)(ref val)).positionSpring = 1f;
		((JointDrive)(ref val)).positionDamper = 1f;
		((JointDrive)(ref val)).maximumForce = 1f;
		ballHolderjoint2.angularYZDrive = val;
		if ((Object)(object)playerCharacter.playerAnimator != (Object)null && playerCharacter.playerAnimator.FighterJoints != null)
		{
			foreach (FighterJoint fighterJoint in playerCharacter.playerAnimator.FighterJoints)
			{
				if ((Object)(object)fighterJoint.jointStrength != (Object)null)
				{
					fighterJoint.jointStrength.SetStrengthPercent(1f);
				}
			}
		}
		float koDuration = Mathf.Clamp(impulseMagnitude / 30f / Mathf.Max((float)playerCharacter.bloodAmount, 0.2f), 1f, 5f);
		yield return (object)new WaitForSeconds(koDuration * (FeelThePunch.Instance.KODurationMultiplier / 10f));
		((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(playerCharacter, koDuration / 5f));
		Debug.Log((object)("BallHolderJoint restored for " + playerCharacter.playerName));
		recoveringPlayers.Remove(playerCharacter);
	}

	private IEnumerator GradualSlowMotion(float slowMultiplier, float transitionDuration, float holdTime)
	{
		if (!isSlowMotionRunning)
		{
			isSlowMotionRunning = true;
			Type gmType = typeof(GameMaster);
			FieldInfo singletonField = gmType.GetField("singleton", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			object gmInstance = singletonField.GetValue(null);
			FieldInfo currentGameSpeedField = gmType.GetField("currentGameSpeed", BindingFlags.Instance | BindingFlags.NonPublic);
			float baseTimeScale = (float)currentGameSpeedField.GetValue(gmInstance);
			MethodInfo setTimeScaleMethod = gmType.GetMethod("SetTimeScale", BindingFlags.Instance | BindingFlags.NonPublic);
			float baseDeltaTime = Time.fixedDeltaTime;
			float targetTimeScale = baseTimeScale * slowMultiplier;
			setTimeScaleMethod.Invoke(gmInstance, new object[1] { targetTimeScale });
			Time.fixedDeltaTime = baseDeltaTime;
			yield return (object)new WaitForSecondsRealtime(holdTime);
			float elapsed = 0f;
			while (elapsed < transitionDuration)
			{
				float newScale = Mathf.Lerp(targetTimeScale, baseTimeScale, elapsed / transitionDuration);
				setTimeScaleMethod.Invoke(gmInstance, new object[1] { newScale });
				elapsed += Time.unscaledDeltaTime;
				yield return null;
			}
			setTimeScaleMethod.Invoke(gmInstance, new object[1] { baseTimeScale });
			Time.fixedDeltaTime = baseDeltaTime;
			isSlowMotionRunning = false;
		}
	}

	private IEnumerator Grapple(Hand hand, GameObject wrist, Collision collision)
	{
		if (activeGrapplingHands.Contains(hand))
		{
			Debug.Log((object)("This hand of " + ((Component)hand).GetComponentInParent<PlayerHealth>().playerName + " is already in the process of grappling someone."));
			yield break;
		}
		if ((Object)(object)wrist == (Object)null)
		{
			Debug.LogError((object)("[Grapple] wrist is NULL on coroutine start for hand " + ((Object)hand).name));
			yield break;
		}
		if (collision == null)
		{
			Debug.LogError((object)("[Grapple] collision is NULL on coroutine start for hand " + ((Object)hand).name));
			yield break;
		}
		if ((Object)(object)collision.rigidbody == (Object)null)
		{
			Debug.LogError((object)("[Grapple] collision.rigidbody is NULL on coroutine start for hand " + ((Object)hand).name));
			yield break;
		}
		activeGrapplingHands.Add(hand);
		try
		{
			yield return (object)new WaitForSeconds(0.1f);
			float HoldElapsed = 0f;
			float HoldMaxDuration = 1f;
			Collider initialCollider = collision.collider;
			Vector3 initialContactPoint = ((ContactPoint)(ref collision.contacts[0])).point;
			float initialDistance = Vector3.Distance(((Component)hand).transform.position, initialContactPoint);
			while (HoldElapsed < HoldMaxDuration && (int)hand.handState != 1)
			{
				HoldElapsed += Time.deltaTime;
				Vector3 currentClosestPoint = initialCollider.ClosestPoint(((Component)hand).transform.position);
				float currentDistance = Vector3.Distance(((Component)hand).transform.position, currentClosestPoint);
				if (currentDistance > initialDistance + 0.03f)
				{
					yield break;
				}
				yield return null;
			}
			Rigidbody targetRigidbody = collision.rigidbody;
			if ((Object)(object)targetRigidbody == (Object)null)
			{
				yield break;
			}
			PlayerHealth[] handPHs = ((Component)objectRigidbody).GetComponentsInParent<PlayerHealth>();
			PlayerHealth[] targetPHs = ((Component)targetRigidbody).GetComponentsInParent<PlayerHealth>();
			if (handPHs.Intersect(targetPHs).Any())
			{
				yield break;
			}
			PlayerHealth enemyCharacter = ((Component)targetRigidbody).GetComponentInParent<PlayerHealth>();
			if ((Object)(object)enemyCharacter == (Object)null)
			{
				GameObject cuttedLimb = ((Component)((Component)targetRigidbody).transform.root).gameObject;
				if (!((Object)cuttedLimb).name.ToLower().Contains("cuttablegameobject"))
				{
					yield break;
				}
				enemyCharacter = cuttedLimb.AddComponent<PlayerHealth>();
				((Behaviour)enemyCharacter).enabled = false;
			}
			if ((Object)(object)initialCollider == (Object)null || initialCollider.isTrigger)
			{
				Debug.Log((object)"Grapple canceled: Invalid target");
			}
			else
			{
				if ((int)hand.handState != 1)
				{
					yield break;
				}
				string key = ((Object)hand).GetInstanceID() + "_" + ((Object)enemyCharacter).GetInstanceID();
				if (lastGrabTimes.ContainsKey(key) && Time.time - lastGrabTimes[key] < 15f)
				{
					Debug.Log((object)"This hand recently grabbed this enemy, waiting for cooldown.");
					yield break;
				}
				lastGrabTimes[key] = Time.time;
				_ = ((Component)initialCollider.attachedRigidbody).transform.position;
				ContactInfo ci = MoveToTouch(wrist.transform, ((Component)hand).transform, initialCollider, 0.05f);
				hand.grabbed = true;
				ConfigurableJoint joint = wrist.gameObject.AddComponent<ConfigurableJoint>();
				((Joint)joint).connectedBody = targetRigidbody;
				joint.xMotion = (ConfigurableJointMotion)0;
				joint.yMotion = (ConfigurableJointMotion)0;
				joint.zMotion = (ConfigurableJointMotion)0;
				joint.angularXMotion = (ConfigurableJointMotion)2;
				joint.angularYMotion = (ConfigurableJointMotion)2;
				joint.angularZMotion = (ConfigurableJointMotion)2;
				((Joint)joint).autoConfigureConnectedAnchor = false;
				((Joint)joint).anchor = ci.moverLocalAnchor;
				((Joint)joint).connectedAnchor = ci.targetLocalAnchor;
				((Joint)joint).breakForce = float.PositiveInfinity;
				((Joint)joint).breakTorque = float.PositiveInfinity;
				yield return (object)new WaitForFixedUpdate();
				yield return (object)new WaitForFixedUpdate();
				yield return (object)new WaitForFixedUpdate();
				yield return (object)new WaitForFixedUpdate();
				((Joint)joint).breakForce = 20000f;
				if (currentlyGrabbedEnemyCounts.ContainsKey(enemyCharacter))
				{
					currentlyGrabbedEnemyCounts[enemyCharacter]++;
				}
				else
				{
					currentlyGrabbedEnemyCounts[enemyCharacter] = 1;
				}
				Rigidbody[] enemyLimbs = ((Component)enemyCharacter).GetComponentsInChildren<Rigidbody>();
				Rigidbody[] array = enemyLimbs;
				foreach (Rigidbody enemyLimb in array)
				{
					if ((Object)(object)((Component)enemyLimb).GetComponent<ReceiveEnvironmentalDamage>() == (Object)null && !((Object)enemyLimb).name.ToLower().Contains("knee") && !((Object)enemyLimb).name.ToLower().Contains("wrist") && !((Object)enemyLimb).name.ToLower().Contains("elbow"))
					{
						Debug.Log((object)((Object)enemyLimb).name);
						((Component)enemyLimb).gameObject.AddComponent<ReceiveEnvironmentalDamage>();
					}
				}
				if (((Behaviour)enemyCharacter).enabled && Object.op_Implicit((Object)(object)((Component)((Component)targetRigidbody).transform.parent).GetComponent<JointStrength>()))
				{
					JointStrength[] joints = ((Component)((Component)targetRigidbody).transform.parent).GetComponents<JointStrength>();
					JointStrength[] array2 = joints;
					foreach (JointStrength jointy in array2)
					{
						if (jointy.jointName == ((Object)((Component)targetRigidbody).gameObject).name)
						{
							((MonoBehaviour)this).StartCoroutine(React(jointy, 40f, null));
						}
					}
				}
				float ReleaseElapsed = 0f;
				float ReleaseMaxDuration = 5f;
				if (((Behaviour)enemyCharacter).enabled && !enemyCharacter.alive)
				{
					ReleaseMaxDuration = 10f;
				}
				if (!((Behaviour)enemyCharacter).enabled)
				{
					ReleaseMaxDuration = 10f;
				}
				bool alreadyModified = globallyModifiedEnemies.Contains(enemyCharacter);
				Transform leftFoot = null;
				Transform rightFoot = null;
				if ((Object)(object)leftFoot == (Object)null || (Object)(object)rightFoot == (Object)null)
				{
					Rigidbody[] allChildren = ((Component)enemyCharacter).GetComponentsInChildren<Rigidbody>();
					Rigidbody[] array3 = allChildren;
					foreach (Rigidbody child in array3)
					{
						if (((Object)child).name == "KNEE_LEFT")
						{
							leftFoot = ((Component)child).gameObject.transform;
						}
						if (((Object)child).name == "KNEE_RIGHT")
						{
							rightFoot = ((Component)child).gameObject.transform;
						}
					}
				}
				Rigidbody hip = ((IEnumerable<Rigidbody>)((Component)enemyCharacter).GetComponentsInChildren<Rigidbody>()).FirstOrDefault((Func<Rigidbody, bool>)((Rigidbody rb) => ((Object)rb).name == "HIP"));
				JointDrive val;
				if ((Object)(object)enemyCharacter.ballHolderjoint != (Object)null && ((Behaviour)enemyCharacter).enabled)
				{
					ConfigurableJoint ballHolderjoint = enemyCharacter.ballHolderjoint;
					val = default(JointDrive);
					JointDrive val2 = enemyCharacter.ballHolderjoint.angularXDrive;
					((JointDrive)(ref val)).positionSpring = ((JointDrive)(ref val2)).positionSpring * 0.9f;
					val2 = enemyCharacter.ballHolderjoint.angularXDrive;
					((JointDrive)(ref val)).positionDamper = ((JointDrive)(ref val2)).positionDamper * 0.9f;
					val2 = enemyCharacter.ballHolderjoint.angularXDrive;
					((JointDrive)(ref val)).maximumForce = ((JointDrive)(ref val2)).maximumForce * 0.9f;
					ballHolderjoint.angularXDrive = val;
					ConfigurableJoint ballHolderjoint2 = enemyCharacter.ballHolderjoint;
					val = default(JointDrive);
					val2 = enemyCharacter.ballHolderjoint.angularYZDrive;
					((JointDrive)(ref val)).positionSpring = ((JointDrive)(ref val2)).positionSpring * 0.9f;
					val2 = enemyCharacter.ballHolderjoint.angularYZDrive;
					((JointDrive)(ref val)).positionDamper = ((JointDrive)(ref val2)).positionDamper * 0.9f;
					val2 = enemyCharacter.ballHolderjoint.angularYZDrive;
					((JointDrive)(ref val)).maximumForce = ((JointDrive)(ref val2)).maximumForce * 0.9f;
					ballHolderjoint2.angularYZDrive = val;
					if ((Object)(object)enemyCharacter.playerAnimator != (Object)null && enemyCharacter.playerAnimator.FighterJoints != null)
					{
						foreach (FighterJoint fighterJoint2 in enemyCharacter.playerAnimator.FighterJoints)
						{
							if ((Object)(object)fighterJoint2.jointStrength != (Object)null && !((Object)fighterJoint2.joint).name.ToLower().Contains("wrist") && !((Object)fighterJoint2.joint).name.ToLower().Contains("elbow") && !((Object)fighterJoint2.joint).name.ToLower().Contains("shoulder") && !((Object)fighterJoint2.joint).name.ToLower().Contains("scapula") && !((Object)fighterJoint2.joint).name.ToLower().Contains("spine2"))
							{
								fighterJoint2.jointStrength.SetStrengthPercent(fighterJoint2.jointStrength.currentPercent * 0.5f);
							}
						}
					}
				}
				while (ReleaseElapsed < ReleaseMaxDuration && (int)hand.handState == 1 && (Object)(object)joint != (Object)null && currentlyGrabbedEnemyCounts.ContainsKey(enemyCharacter))
				{
					ReleaseElapsed += 0.1f;
					Vector3 val3;
					if (!alreadyModified && (Object)(object)leftFoot != (Object)null && (Object)(object)rightFoot != (Object)null && ((Behaviour)enemyCharacter).enabled)
					{
						Vector3 worldCOM2 = CalculateCenterOfMass(enemyCharacter);
						Vector3 avgFeetPos2 = (leftFoot.position + rightFoot.position) / 2f;
						val3 = worldCOM2 - avgFeetPos2;
						Vector3 dirToCOM2 = ((Vector3)(ref val3)).normalized;
						float angle2 = Vector3.Angle(dirToCOM2, Vector3.up);
						if (angle2 > 20f && (Object)(object)enemyCharacter.ballHolderjoint != (Object)null)
						{
							ConfigurableJoint ballHolderjoint3 = enemyCharacter.ballHolderjoint;
							val = default(JointDrive);
							((JointDrive)(ref val)).positionSpring = MagicHipSpringX * 1E-05f;
							((JointDrive)(ref val)).positionDamper = MagicHipDamperX * 1E-05f;
							((JointDrive)(ref val)).maximumForce = MagicHipStrengthX * 1E-05f;
							ballHolderjoint3.angularXDrive = val;
							ConfigurableJoint ballHolderjoint4 = enemyCharacter.ballHolderjoint;
							val = default(JointDrive);
							((JointDrive)(ref val)).positionSpring = MagicHipSpringYZ * 1E-05f;
							((JointDrive)(ref val)).positionDamper = MagicHipDamperYZ * 1E-05f;
							((JointDrive)(ref val)).maximumForce = MagicHipStrengthYZ * 1E-05f;
							ballHolderjoint4.angularYZDrive = val;
							if ((Object)(object)enemyCharacter.playerAnimator != (Object)null && enemyCharacter.playerAnimator.FighterJoints != null)
							{
								foreach (FighterJoint fighterJoint in enemyCharacter.playerAnimator.FighterJoints)
								{
									if ((Object)(object)fighterJoint.jointStrength != (Object)null && fighterJoint.jointStrength.instancesOfDamage < 1 && fighterJoint.jointStrength.jointName == "HIP")
									{
										fighterJoint.jointStrength.SetStrengthPercent(1f);
										Debug.Log((object)("DECREASED Strength for HIPS, Takedown Succesfull " + fighterJoint.jointStrength.jointName));
									}
								}
							}
							if (((Component)targetRigidbody).gameObject.layer == LayerMask.NameToLayer("Weapons"))
							{
								Hand handComponent = ((Component)targetRigidbody).GetComponentInParent<Hand>();
								if ((Object)(object)handComponent != (Object)null && handComponent.currentlyGrabbedItem != null)
								{
									List<Hand> grabbingHands = new List<Hand>(handComponent.currentlyGrabbedItem.GetGrabbingHands());
									foreach (Hand handy in grabbingHands)
									{
										if ((Object)(object)handy != (Object)null && handy.currentlyGrabbedItem != null)
										{
											((MonoBehaviour)this).StartCoroutine(dissarm(handy));
											((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
										}
									}
								}
								else
								{
									Debug.Log((object)"No grabbingHands to release (probably already null).");
								}
							}
							Debug.Log((object)$"Balance lost. BallHolderJoint softened for {enemyCharacter.playerName} due to COM angle = {angle2}°");
							globallyModifiedEnemies.Add(enemyCharacter);
							alreadyModified = true;
						}
					}
					int num;
					if (alreadyModified && (Object)(object)leftFoot != (Object)null && (Object)(object)rightFoot != (Object)null && ((Behaviour)enemyCharacter).enabled)
					{
						Vector3 worldCOM = CalculateCenterOfMass(enemyCharacter);
						Vector3 avgFeetPos = (leftFoot.position + rightFoot.position) / 2f;
						val3 = worldCOM - avgFeetPos;
						Vector3 dirToCOM = ((Vector3)(ref val3)).normalized;
						float angle = Vector3.Angle(dirToCOM, Vector3.up);
						if (!(angle < 10f) || !((Object)(object)enemyCharacter.ballHolderjoint != (Object)null))
						{
							if (angle > 10f && (Object)(object)enemyCharacter.ballHolderjoint != (Object)null)
							{
								val = enemyCharacter.ballHolderjoint.angularYZDrive;
								if (((JointDrive)(ref val)).maximumForce != 1E-05f)
								{
									num = ((((Component)targetRigidbody).gameObject.layer != LayerMask.NameToLayer("Weapons")) ? 1 : 0);
									goto IL_1375;
								}
							}
							num = 0;
							goto IL_1375;
						}
						((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
					}
					goto IL_1471;
					IL_1375:
					if (num != 0)
					{
						ConfigurableJoint ballHolderjoint5 = enemyCharacter.ballHolderjoint;
						val = default(JointDrive);
						((JointDrive)(ref val)).positionSpring = MagicHipSpringX * 1E-05f;
						((JointDrive)(ref val)).positionDamper = MagicHipDamperX * 1E-05f;
						((JointDrive)(ref val)).maximumForce = MagicHipStrengthX * 1E-05f;
						ballHolderjoint5.angularXDrive = val;
						ConfigurableJoint ballHolderjoint6 = enemyCharacter.ballHolderjoint;
						val = default(JointDrive);
						((JointDrive)(ref val)).positionSpring = MagicHipSpringYZ * 1E-05f;
						((JointDrive)(ref val)).positionDamper = MagicHipDamperYZ * 1E-05f;
						((JointDrive)(ref val)).maximumForce = MagicHipStrengthYZ * 1E-05f;
						ballHolderjoint6.angularYZDrive = val;
					}
					goto IL_1471;
					IL_1471:
					yield return (object)new WaitForSeconds(0.1f);
				}
				if (currentlyGrabbedEnemyCounts.ContainsKey(enemyCharacter))
				{
					currentlyGrabbedEnemyCounts[enemyCharacter]--;
					if (currentlyGrabbedEnemyCounts[enemyCharacter] <= 0)
					{
						currentlyGrabbedEnemyCounts.Remove(enemyCharacter);
					}
				}
				if ((Object)(object)joint != (Object)null)
				{
					Object.Destroy((Object)(object)joint);
				}
				hand.grabbed = false;
				yield return (object)new WaitForSeconds(0.5f);
				if ((Object)(object)hip != (Object)null && ((Behaviour)enemyCharacter).enabled && !currentlyGrabbedEnemyCounts.ContainsKey(enemyCharacter))
				{
					((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
				}
				ReceiveEnvironmentalDamage[] EnviroDamages = ((Component)enemyCharacter).GetComponentsInChildren<ReceiveEnvironmentalDamage>();
				ReceiveEnvironmentalDamage[] array4 = EnviroDamages;
				foreach (ReceiveEnvironmentalDamage EnviroDamage in array4)
				{
					Object.Destroy((Object)(object)EnviroDamage);
				}
			}
		}
		finally
		{
			activeGrapplingHands.Remove(hand);
		}
	}

	public static ContactInfo MoveToTouch(Transform wrist, Transform handRoot, Collider targetCol, float gap = 0.01f)
	{
		//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_0021: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_00a0: 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_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_00af: 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_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_00bc: 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_00c2: 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_00cd: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		Collider[] componentsInChildren = ((Component)handRoot).GetComponentsInChildren<Collider>();
		ContactInfo result = default(ContactInfo);
		float num = float.MaxValue;
		Vector3 val = Vector3.zero;
		Vector3 val2 = Vector3.zero;
		Collider[] array = componentsInChildren;
		foreach (Collider val3 in array)
		{
			Vector3 val4 = targetCol.ClosestPoint(((Component)val3).transform.position);
			Vector3 val5 = val3.ClosestPoint(val4);
			float num2 = Vector3.Distance(val5, val4);
			if (num2 < num)
			{
				num = num2;
				result.closestCollider = val3;
				val = val5;
				val2 = val4;
			}
		}
		Vector3 val6 = val2 - val;
		Vector3 normalized = ((Vector3)(ref val6)).normalized;
		Vector3 val7 = (result.worldAnchor = val2 - normalized * gap);
		Vector3 val8 = val7 - val;
		wrist.position += val8;
		result.moverLocalAnchor = wrist.InverseTransformPoint(val7);
		result.targetLocalAnchor = ((Component)targetCol).transform.InverseTransformPoint(val7);
		return result;
	}

	private IEnumerator DestroyBluntTransmiters(PlayerHealth enemy)
	{
		PlayerHealth myPlayerHealth = ((Component)this).GetComponentInParent<PlayerHealth>();
		((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(myPlayerHealth, 0.1f));
		yield return (object)new WaitForSeconds(1f);
		BluntTransmitter[] bluntTransmitters = ((Component)enemy).GetComponentsInChildren<BluntTransmitter>();
		BluntTransmitter[] array = bluntTransmitters;
		foreach (BluntTransmitter bluntTransmitter in array)
		{
			Object.Destroy((Object)(object)bluntTransmitter);
		}
	}

	private void OnDestroy()
	{
		isSlowMotionRunning = false;
	}

	public IEnumerator RestoreBallHolderJoint(PlayerHealth enemy, float waitTime)
	{
		yield return (object)new WaitForSeconds(0.01f);
		if (!enemy.alive || !((Object)(object)enemy.ballHolderjoint != (Object)null))
		{
			yield break;
		}
		JointDrive initialX = enemy.ballHolderjoint.angularXDrive;
		JointDrive initialYZ = enemy.ballHolderjoint.angularYZDrive;
		JointDrive val = default(JointDrive);
		((JointDrive)(ref val)).positionSpring = MagicHipSpringX;
		((JointDrive)(ref val)).positionDamper = MagicHipDamperX;
		((JointDrive)(ref val)).maximumForce = MagicHipStrengthX;
		JointDrive targetX = val;
		val = default(JointDrive);
		((JointDrive)(ref val)).positionSpring = MagicHipSpringYZ;
		((JointDrive)(ref val)).positionDamper = MagicHipDamperYZ;
		((JointDrive)(ref val)).maximumForce = MagicHipStrengthYZ;
		JointDrive targetYZ = val;
		float startTime = Time.time;
		if (!currentlyGrabbedEnemyCounts.ContainsKey(enemy))
		{
			while (Time.time - startTime < waitTime && enemy.alive)
			{
				if ((Object)(object)enemy.ballHolderjoint == (Object)null)
				{
					yield break;
				}
				float t = (Time.time - startTime) / waitTime;
				ConfigurableJoint ballHolderjoint = enemy.ballHolderjoint;
				val = default(JointDrive);
				((JointDrive)(ref val)).positionSpring = Mathf.Lerp(((JointDrive)(ref initialX)).positionSpring, ((JointDrive)(ref targetX)).positionSpring, t);
				((JointDrive)(ref val)).positionDamper = Mathf.Lerp(((JointDrive)(ref initialX)).positionDamper, ((JointDrive)(ref targetX)).positionDamper, t);
				((JointDrive)(ref val)).maximumForce = Mathf.Lerp(((JointDrive)(ref initialX)).maximumForce, ((JointDrive)(ref targetX)).maximumForce, t);
				ballHolderjoint.angularXDrive = val;
				ConfigurableJoint ballHolderjoint2 = enemy.ballHolderjoint;
				val = default(JointDrive);
				((JointDrive)(ref val)).positionSpring = Mathf.Lerp(((JointDrive)(ref initialYZ)).positionSpring, ((JointDrive)(ref targetYZ)).positionSpring, t);
				((JointDrive)(ref val)).positionDamper = Mathf.Lerp(((JointDrive)(ref initialYZ)).positionDamper, ((JointDrive)(ref targetYZ)).positionDamper, t);
				((JointDrive)(ref val)).maximumForce = Mathf.Lerp(((JointDrive)(ref initialYZ)).maximumForce, ((JointDrive)(ref targetYZ)).maximumForce, t);
				ballHolderjoint2.angularYZDrive = val;
				yield return null;
			}
			if ((Object)(object)enemy.playerAnimator != (Object)null && enemy.playerAnimator.FighterJoints != null)
			{
				foreach (FighterJoint fighterJoint2 in enemy.playerAnimator.FighterJoints)
				{
					if ((Object)(object)fighterJoint2.jointStrength != (Object)null && fighterJoint2.jointStrength.instancesOfDamage < 1 && fighterJoint2.jointStrength.jointName == "HIP")
					{
						fighterJoint2.jointStrength.SetStrengthPercent(100f);
						Debug.Log((object)("Restored Strength for HIPS, Recovery Succesfull " + fighterJoint2.jointStrength.jointName));
					}
				}
			}
		}
		float startTime2 = Time.time;
		while (Time.time - startTime2 < waitTime && enemy.alive)
		{
			float t2 = (Time.time - startTime2) / waitTime;
			if ((Object)(object)enemy.playerAnimator != (Object)null && enemy.playerAnimator.FighterJoints != null)
			{
				foreach (FighterJoint fighterJoint in enemy.playerAnimator.FighterJoints)
				{
					if ((Object)(object)fighterJoint.jointStrength != (Object)null && fighterJoint.jointStrength.instancesOfDamage < 1 && fighterJoint.jointStrength.jointName != "HIP")
					{
						fighterJoint.jointStrength.SetStrengthPercent(Mathf.Lerp(fighterJoint.jointStrength.currentPercent, 100f, t2));
					}
				}
			}
			yield return null;
		}
		enemy.ballHolderjoint.angularXDrive = targetX;
		enemy.ballHolderjoint.angularYZDrive = targetYZ;
		Debug.Log((object)("BallHolderJoint fully restored for " + enemy.playerName));
		globallyModifiedEnemies.Remove(enemy);
		initialX = default(JointDrive);
		initialYZ = default(JointDrive);
		targetX = default(JointDrive);
		targetYZ = default(JointDrive);
	}

	public Vector3 CalculateCenterOfMass(PlayerHealth character)
	{
		//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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		Rigidbody[] componentsInChildren = ((Component)character).GetComponentsInChildren<Rigidbody>();
		Vector3 val = Vector3.zero;
		float num = 0f;
		Rigidbody[] array = componentsInChildren;
		foreach (Rigidbody val2 in array)
		{
			val += val2.worldCenterOfMass * val2.mass;
			num += val2.mass;
		}
		if (num > 0f)
		{
			return val / num;
		}
		Debug.LogError((object)"Total mass is zero. Check your rigidbodies.");
		return Vector3.zero;
	}

	public IEnumerator dissarm(Hand hand)
	{
		float elapsedTime = 0f;
		float targetTime = 0.5f;
		yield return (object)new WaitForSeconds(0.4f);
		while (elapsedTime < targetTime)
		{
			elapsedTime += Time.deltaTime;
			hand.SetHandState((HandState)0);
			yield return (object)new WaitForFixedUpdate();
		}
	}
}
public class ReceiveEnvironmentalDamage : MonoBehaviour
{
	private const float ImpulseThreshold = 30f;

	private const float DamageDivisor = 75f;

	private const float DamageMax = 0.5f;

	private const float FinalDivisor = 5f;

	private void OnCollisionEnter(Collision collision)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)collision.gameObject.GetComponentInParent<PlayerHealth>() != (Object)null)
		{
			return;
		}
		Vector3 impulse = collision.impulse;
		float magnitude = ((Vector3)(ref impulse)).magnitude;
		if (magnitude <= 30f)
		{
			return;
		}
		float num = magnitude / 75f;
		float num2 = Mathf.Clamp(num, 0f, 0.5f);
		float num3 = num2 / 5f;
		PlayerHealth componentInParent = ((Component)this).GetComponentInParent<PlayerHealth>();
		if ((Object)(object)componentInParent == (Object)null)
		{
			Debug.LogWarning((object)(((Object)this).name + ": PlayerHealth component not found on parent."));
			return;
		}
		if ((magnitude >= 37f && ((Object)((Component)this).gameObject).name.ToLower().Contains("neck")) || (magnitude >= 47f && ((Object)((Component)this).gameObject).name.ToLower().Contains("spine")))
		{
			((MonoBehaviour)this).StartCoroutine(((Component)componentInParent).gameObject.GetComponentInChildren<BluntTransmitter>().KO(componentInParent, magnitude, Vector3.zero, 0f, FeelThePunch.Instance.DisarmOnKO));
		}
		componentInParent.bloodAmount -= (double)num3;
		componentInParent.UpdateBloodVignette();
		Debug.Log((object)$"{((Object)this).name}: Applied {num3:F3} environmental damage. Blood now {componentInParent.bloodAmount:F3}.");
		if (componentInParent.bloodAmount <= 0.0)
		{
			Debug.Log((object)(((Object)this).name + ": Blood depleted. Triggering bleedout death."));
			componentInParent.Die((DeathReason)3);
		}
	}
}