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.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.4.4")]
public class FeelThePunch : BaseUnityPlugin
{
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 OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("SCENE LOADED: " + ((Scene)(ref scene)).name));
((MonoBehaviour)this).StartCoroutine(DelayedSetup());
}
public IEnumerator DelayedSetup()
{
yield return (object)new WaitForSecondsRealtime(1f);
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>();
}
}
}
}
public class BluntTransmitter : MonoBehaviour
{
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 bool isSlowMotionRunning = false;
private const float requiredDuration = 10f;
private Coroutine watchdogCoroutine;
private void Start()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
objectRigidbody = ((Component)this).GetComponent<Rigidbody>();
if ((Object)(object)objectRigidbody == (Object)null)
{
Debug.LogError((object)"BluntTransmitter script requires a Rigidbody on the object!");
}
PlayerHealth componentInParent = ((Component)this).GetComponentInParent<PlayerHealth>();
JointDrive val = componentInParent.ballHolderjoint.angularXDrive;
MagicHipSpringX = ((JointDrive)(ref val)).positionSpring;
val = componentInParent.ballHolderjoint.angularXDrive;
MagicHipDamperX = ((JointDrive)(ref val)).positionDamper;
val = componentInParent.ballHolderjoint.angularXDrive;
MagicHipStrengthX = ((JointDrive)(ref val)).maximumForce;
val = componentInParent.ballHolderjoint.angularYZDrive;
MagicHipSpringYZ = ((JointDrive)(ref val)).positionSpring;
val = componentInParent.ballHolderjoint.angularYZDrive;
MagicHipDamperYZ = ((JointDrive)(ref val)).positionDamper;
val = componentInParent.ballHolderjoint.angularYZDrive;
MagicHipStrengthYZ = ((JointDrive)(ref val)).maximumForce;
}
private void OnEnable()
{
watchdogCoroutine = ((MonoBehaviour)this).StartCoroutine(KOWatchdog());
}
private void OnDisable()
{
if (watchdogCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(watchdogCoroutine);
}
}
private IEnumerator KOWatchdog()
{
PlayerHealth health = ((Component)this).GetComponentInParent<PlayerHealth>();
float timer = 0f;
do
{
yield return (object)new WaitForSeconds(1f);
if (health.playerAnimator.FighterJoints[1].jointStrength.currentPercent <= 1f)
{
timer += 1f;
if (timer >= 10f)
{
((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));
}
}
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_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0440: Unknown result type (might be due to invalid IL or missing references)
//IL_0444: Unknown result type (might be due to invalid IL or missing references)
//IL_0450: Unknown result type (might be due to invalid IL or missing references)
//IL_0458: Unknown result type (might be due to invalid IL or missing references)
//IL_045d: Unknown result type (might be due to invalid IL or missing references)
//IL_0461: Unknown result type (might be due to invalid IL or missing references)
//IL_0466: Unknown result type (might be due to invalid IL or missing references)
//IL_0474: Unknown result type (might be due to invalid IL or missing references)
//IL_0479: Unknown result type (might be due to invalid IL or missing references)
//IL_047c: Unknown result type (might be due to invalid IL or missing references)
//IL_049e: Unknown result type (might be due to invalid IL or missing references)
//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
//IL_0510: 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 < 30f || (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}");
PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>();
PlayerHealth[] array2 = array;
foreach (PlayerHealth val6 in array2)
{
Rigidbody[] componentsInChildren = ((Component)val6).GetComponentsInChildren<Rigidbody>();
Rigidbody[] array3 = componentsInChildren;
foreach (Rigidbody val7 in array3)
{
if (!((Object)(object)val7 == (Object)(object)rigidbody) || ((Component)val7).gameObject.layer == LayerMask.NameToLayer("Weapons"))
{
continue;
}
string text = ((Object)val7).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 (val6.bloodAmount - (double)num3 <= 0.0)
{
num3 = 0f;
JointStrength[] components = ((Component)((Component)val7).transform.parent).GetComponents<JointStrength>();
JointStrength[] array4 = components;
foreach (JointStrength val8 in array4)
{
bool flag = val8.jointName == ((Object)((Component)val7).gameObject).name;
string text2 = ((Object)((Component)val7).gameObject).name.ToLower();
if (flag)
{
val8.DealMuscleDamage();
val8.DealMuscleDamage();
val8.DealMuscleDamage();
val8.DealMuscleDamage();
}
}
}
}
else
{
num2 = 0.8f;
num3 = Mathf.Clamp(magnitude / 75f, 0f, 0.5f) * num2;
}
val6.bloodAmount -= (double)num3;
val6.UpdateBloodVignette();
Debug.Log((object)$"{val6.playerName} blood amount is {val6.bloodAmount}");
if (val6.bloodAmount <= 0.0 && val6.alive)
{
val6.Die((DeathReason)3);
num *= 5f;
((MonoBehaviour)this).StartCoroutine(DestroyBluntTransmiters(val6));
}
if (!text.Contains("left") && !text.Contains("right"))
{
rigidbody.AddForce(val5 * num, (ForceMode)1);
val = objectRigidbody.velocity;
Vector3 val9 = Vector3.Cross(val5, ((Vector3)(ref val)).normalized) * (num * torqueMultiplier);
rigidbody.AddTorque(val9, (ForceMode)1);
if ((Object)(object)objectRigidbody != (Object)null)
{
Vector3 val10 = -objectRigidbody.velocity * objectRigidbody.mass;
objectRigidbody.AddForce(val10, (ForceMode)1);
}
}
if (((num2 >= 0.8f && magnitude >= 47f) || (text.Contains("neck") && magnitude >= 37f)) && !recoveringPlayers.Contains(val6))
{
((MonoBehaviour)this).StartCoroutine(KO(val6, magnitude, val5, num));
}
else
{
if (!Object.op_Implicit((Object)(object)((Component)((Component)val7).transform.parent).GetComponent<JointStrength>()) || !(magnitude < 47f) || !(magnitude > 32f))
{
continue;
}
JointStrength[] components2 = ((Component)((Component)val7).transform.parent).GetComponents<JointStrength>();
JointStrength[] array5 = components2;
foreach (JointStrength val11 in array5)
{
bool flag2 = val11.jointName == ((Object)((Component)val7).gameObject).name;
string text3 = ((Object)((Component)val7).gameObject).name.ToLower();
if (flag2 && !text3.Contains("elbow") && !text3.Contains("shoulder"))
{
((MonoBehaviour)this).StartCoroutine(React(val11, magnitude, val6));
}
else if (flag2 && (text3.Contains("elbow") || text3.Contains("shoulder")))
{
((MonoBehaviour)this).StartCoroutine(React(val11, 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 / 10f);
joint.SetStrengthPercent(100f);
}
public IEnumerator KO(PlayerHealth playerCharacter, float impulseMagnitude, Vector3 impactDirection, float impactForce)
{
//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));
}
((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 / 4f), (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 / 20f / Mathf.Max((float)playerCharacter.bloodAmount, 0.2f), 0.5f, 10f);
yield return (object)new WaitForSeconds(koDuration);
((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(playerCharacter, koDuration / 10f));
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;
wrist.transform.position = (wrist.transform.position + initialCollider.ClosestPoint(((Component)hand).transform.position)) / 2f;
yield return (object)new WaitForFixedUpdate();
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 = Vector3.zero;
((Joint)joint).connectedAnchor = ((Component)targetRigidbody).transform.InverseTransformPoint(wrist.transform.position);
((Joint)joint).breakForce = 20000f;
((Joint)joint).breakTorque = float.PositiveInfinity;
Rigidbody[] enemyLimbs = ((Component)enemyCharacter).GetComponentsInChildren<Rigidbody>();
Rigidbody[] array = enemyLimbs;
foreach (Rigidbody enemyLimb in array)
{
if ((Object)(object)((Component)enemyLimb).GetComponent<ReceiveEnvironmentalDamage>() == (Object)null)
{
((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 fighterJoint in enemyCharacter.playerAnimator.FighterJoints)
{
if ((Object)(object)fighterJoint.jointStrength != (Object)null && !((Object)fighterJoint.joint).name.ToLower().Contains("wrist") && !((Object)fighterJoint.joint).name.ToLower().Contains("elbow") && !((Object)fighterJoint.joint).name.ToLower().Contains("shoulder") && !((Object)fighterJoint.joint).name.ToLower().Contains("scapula") && !((Object)fighterJoint.joint).name.ToLower().Contains("spine2"))
{
fighterJoint.jointStrength.SetStrengthPercent(fighterJoint.jointStrength.currentPercent * 0.5f);
}
}
}
}
while (ReleaseElapsed < ReleaseMaxDuration && (int)hand.handState == 1 && (Object)(object)joint != (Object)null)
{
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 (((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_1116;
}
}
num = 0;
goto IL_1116;
}
((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
}
goto IL_1212;
IL_1116:
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_1212;
IL_1212:
yield return (object)new WaitForSeconds(0.1f);
}
if ((Object)(object)hip != (Object)null && ((Behaviour)enemyCharacter).enabled)
{
((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
}
if ((Object)(object)joint != (Object)null)
{
Object.Destroy((Object)(object)joint);
}
hand.grabbed = false;
yield return (object)new WaitForSeconds(0.5f);
ReceiveEnvironmentalDamage[] EnviroDamages = ((Component)enemyCharacter).GetComponentsInChildren<ReceiveEnvironmentalDamage>();
ReceiveEnvironmentalDamage[] array4 = EnviroDamages;
foreach (ReceiveEnvironmentalDamage EnviroDamage in array4)
{
Object.Destroy((Object)(object)EnviroDamage);
}
}
}
finally
{
activeGrapplingHands.Remove(hand);
}
}
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;
}
private 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;
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;
}
float startTime2 = Time.time;
while (Time.time - startTime2 < waitTime && enemy.alive)
{
float t2 = (Time.time - startTime) / 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.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));
}
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);
}
}
}