using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using MoveClasses;
using UnityEngine;
using UnityEngine.Events;
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", "2.0.9")]
[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 float GrabDurationInSeconds = 5f;
public float AngleToloseBalanceDuringGrab = 25f;
public float ForceNeededToBreakFromGrab = 20000f;
private ConfigEntry<bool> cfgEnableBerserkersDeath;
private ConfigEntry<bool> cfgBerserkerDisarm;
private ConfigEntry<bool> cfgDisarmOnKO;
private ConfigEntry<float> cfgKOKnockbackMultiplier;
private ConfigEntry<float> cfgKODurationMultiplier;
private ConfigEntry<float> cfgGrabDurationInSeconds;
private ConfigEntry<float> cfgAngleToloseBalanceDuringGrab;
private ConfigEntry<float> cfgForceNeededToBreakFromGrab;
public static FeelThePunch Instance { get; private set; }
private void Awake()
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Expected O, but got Unknown
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Expected O, but got Unknown
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Expected O, but got Unknown
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Expected O, but got Unknown
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Expected O, but got Unknown
((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
Instance = this;
Harmony.CreateAndPatchAll(typeof(FeelThePunch), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
cfgEnableBerserkersDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableBerserkersDeath", true, new ConfigDescription("Enable Berserker's Death Buff", (AcceptableValueBase)null, Array.Empty<object>()));
cfgBerserkerDisarm = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BerserkerDisarm", true, new ConfigDescription("Disarm enemies when berserker dies", (AcceptableValueBase)null, Array.Empty<object>()));
cfgDisarmOnKO = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisarmOnKO", true, new ConfigDescription("Disarm a target when they are KO'd", (AcceptableValueBase)null, Array.Empty<object>()));
cfgKOKnockbackMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "KOKnockbackMultiplier", 10f, new ConfigDescription("KO knockback multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
cfgKODurationMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "KODurationMultiplier", 10f, new ConfigDescription("KO duration multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
cfgGrabDurationInSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GrabDurationInSeconds", 5f, new ConfigDescription("Grab duration in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
cfgAngleToloseBalanceDuringGrab = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AngleToloseBalanceDuringGrab", 25f, new ConfigDescription("Angle to lose balance during grab", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 45f), Array.Empty<object>()));
cfgForceNeededToBreakFromGrab = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ForceNeededToBreakFromGrab", 20000f, new ConfigDescription("Force needed to break from grab", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5000f, 30000f), Array.Empty<object>()));
LoadConfig();
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 += OnToggleMenuPerformed;
toggleMenuAction.Enable();
}
private void OnDisable()
{
if (toggleMenuAction != null)
{
toggleMenuAction.performed -= OnToggleMenuPerformed;
toggleMenuAction.Disable();
toggleMenuAction.Dispose();
toggleMenuAction = null;
}
SaveConfig();
}
private void OnToggleMenuPerformed(CallbackContext ctx)
{
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);
LoadConfig();
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>();
}
if (((((Object)bodypart).name.ToLower().Contains("shoulder") && Object.op_Implicit((Object)(object)bodypart.GetComponent<Rigidbody>())) || (((Object)bodypart).name.ToLower().Contains("hip_joint") && Object.op_Implicit((Object)(object)bodypart.GetComponent<Rigidbody>()))) && (Object)(object)bodypart.gameObject.GetComponent<JointBreaker>() == (Object)null)
{
bodypart.gameObject.AddComponent<JointBreaker>();
}
if ((Object)(object)bodypart.GetComponent<CarotidChoke>() == (Object)null && ((Object)bodypart).name.ToLower() == "neck")
{
bodypart.AddComponent<CarotidChoke>();
}
}
}
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_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
//IL_036d: Unknown result type (might be due to invalid IL or missing references)
//IL_039a: Unknown result type (might be due to invalid IL or missing references)
if (showMenu)
{
GUI.Box(new Rect(10f, 10f, 420f, 470f), "UnarmedCombat Mod Menu");
int num = 40;
EnableBerserkersDeath = GUI.Toggle(new Rect(20f, (float)num, 380f, 20f), EnableBerserkersDeath, "Enable Berserker's Death Buff");
num += 25;
BerserkerDisarm = GUI.Toggle(new Rect(20f, (float)num, 380f, 20f), BerserkerDisarm, "Disarm Enemies on Berserker Death");
num += 25;
DisarmOnKO = GUI.Toggle(new Rect(20f, (float)num, 380f, 20f), DisarmOnKO, "Disarm on KO");
num += 35;
GUI.Label(new Rect(20f, (float)num, 400f, 20f), "KO Knockback Multiplier: " + Mathf.RoundToInt(KOKnockbackMultiplier));
KOKnockbackMultiplier = GUI.HorizontalSlider(new Rect(20f, (float)(num + 20), 380f, 20f), KOKnockbackMultiplier, 0f, 200f);
KOKnockbackMultiplier = Mathf.Round(KOKnockbackMultiplier);
num += 50;
GUI.Label(new Rect(20f, (float)num, 400f, 20f), "KO Duration Multiplier: " + Mathf.RoundToInt(KODurationMultiplier));
KODurationMultiplier = GUI.HorizontalSlider(new Rect(20f, (float)(num + 20), 380f, 20f), KODurationMultiplier, 0f, 60f);
KODurationMultiplier = Mathf.Round(KODurationMultiplier);
num += 50;
GUI.Label(new Rect(20f, (float)num, 400f, 20f), "Grab Duration in Seconds: " + Mathf.RoundToInt(GrabDurationInSeconds));
GrabDurationInSeconds = GUI.HorizontalSlider(new Rect(20f, (float)(num + 20), 380f, 20f), GrabDurationInSeconds, 0f, 60f);
GrabDurationInSeconds = Mathf.Round(GrabDurationInSeconds);
num += 50;
GUI.Label(new Rect(20f, (float)num, 400f, 20f), "Angle to Lose Balance During Grab: " + Mathf.RoundToInt(AngleToloseBalanceDuringGrab));
AngleToloseBalanceDuringGrab = GUI.HorizontalSlider(new Rect(20f, (float)(num + 20), 380f, 20f), AngleToloseBalanceDuringGrab, 20f, 45f);
AngleToloseBalanceDuringGrab = Mathf.Round(AngleToloseBalanceDuringGrab);
num += 50;
GUI.Label(new Rect(20f, (float)num, 400f, 20f), "Force Needed to Break Grab: " + Mathf.RoundToInt(ForceNeededToBreakFromGrab));
ForceNeededToBreakFromGrab = GUI.HorizontalSlider(new Rect(20f, (float)(num + 20), 380f, 20f), ForceNeededToBreakFromGrab, 5000f, 30000f);
ForceNeededToBreakFromGrab = Mathf.Round(ForceNeededToBreakFromGrab);
num += 50;
if (GUI.Button(new Rect(20f, (float)num, 200f, 30f), "Apply Settings"))
{
SaveConfig();
}
if (GUI.Button(new Rect(240f, (float)num, 160f, 30f), "Reset to Default"))
{
EnableBerserkersDeath = true;
BerserkerDisarm = true;
DisarmOnKO = true;
KOKnockbackMultiplier = 10f;
KODurationMultiplier = 10f;
GrabDurationInSeconds = 5f;
AngleToloseBalanceDuringGrab = 25f;
ForceNeededToBreakFromGrab = 20000f;
SaveConfig();
}
}
}
private void LoadConfig()
{
try
{
EnableBerserkersDeath = cfgEnableBerserkersDeath.Value;
BerserkerDisarm = cfgBerserkerDisarm.Value;
DisarmOnKO = cfgDisarmOnKO.Value;
KOKnockbackMultiplier = cfgKOKnockbackMultiplier.Value;
KODurationMultiplier = cfgKODurationMultiplier.Value;
GrabDurationInSeconds = cfgGrabDurationInSeconds.Value;
AngleToloseBalanceDuringGrab = cfgAngleToloseBalanceDuringGrab.Value;
ForceNeededToBreakFromGrab = cfgForceNeededToBreakFromGrab.Value;
((BaseUnityPlugin)this).Logger.LogInfo((object)"FeelThePunch: Config loaded");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load FeelThePunch config: " + ex.Message));
}
}
private void SaveConfig()
{
try
{
cfgEnableBerserkersDeath.Value = EnableBerserkersDeath;
cfgBerserkerDisarm.Value = BerserkerDisarm;
cfgDisarmOnKO.Value = DisarmOnKO;
cfgKOKnockbackMultiplier.Value = KOKnockbackMultiplier;
cfgKODurationMultiplier.Value = KODurationMultiplier;
cfgGrabDurationInSeconds.Value = GrabDurationInSeconds;
cfgAngleToloseBalanceDuringGrab.Value = AngleToloseBalanceDuringGrab;
cfgForceNeededToBreakFromGrab.Value = ForceNeededToBreakFromGrab;
((BaseUnityPlugin)this).Config.Save();
((BaseUnityPlugin)this).Logger.LogInfo((object)"FeelThePunch: Config saved");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to save FeelThePunch config: " + ex.Message));
}
}
}
public class JointBreaker : MonoBehaviour
{
public ConfigurableJoint joint;
private float breakThreshold;
[Header("Spring tuning")]
public float JointLimitSpring = 2000f;
public float JointLimitDamper = 1f;
private Rigidbody rb;
private Rigidbody connectedRb;
private float lowAngularXLimitDeg;
private float highAngularXLimitDeg;
private float springX;
public bool isBroken = false;
private void Start()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
joint = ((Component)this).GetComponent<ConfigurableJoint>();
JointDrive angularXDrive = joint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce < 10000f)
{
rb = ((Component)this).GetComponent<Rigidbody>();
connectedRb = ((Joint)joint).connectedBody;
angularXDrive = joint.angularXDrive;
breakThreshold = ((JointDrive)(ref angularXDrive)).maximumForce * 2.25f;
SoftJointLimitSpring angularXLimitSpring = joint.angularXLimitSpring;
((SoftJointLimitSpring)(ref angularXLimitSpring)).spring = JointLimitSpring;
((SoftJointLimitSpring)(ref angularXLimitSpring)).damper = JointLimitDamper;
joint.angularXLimitSpring = angularXLimitSpring;
RefreshCachedLimitsAndSpring();
}
}
private void FixedUpdate()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)joint != (Object)null && !isBroken)
{
JointDrive angularXDrive = joint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce < 10000f)
{
ComputeLimitSpringTorqueLocal();
}
}
}
public void RefreshCachedLimitsAndSpring()
{
//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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
SoftJointLimitSpring angularXLimitSpring = joint.angularXLimitSpring;
springX = ((SoftJointLimitSpring)(ref angularXLimitSpring)).spring;
SoftJointLimit val = joint.lowAngularXLimit;
lowAngularXLimitDeg = ((SoftJointLimit)(ref val)).limit;
val = joint.highAngularXLimit;
highAngularXLimitDeg = ((SoftJointLimit)(ref val)).limit;
connectedRb = ((Joint)joint).connectedBody;
}
private float ComputeTwistAngleDeg(Transform connectedT)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: 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_008b: 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_00e0: 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_0108: 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_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)
Transform transform = ((Component)this).transform;
Vector3 axis = ((Joint)joint).axis;
Vector3 val = transform.TransformDirection(((Vector3)(ref axis)).normalized);
Vector3 val2 = ((Component)this).transform.forward;
if (Mathf.Abs(Vector3.Dot(((Vector3)(ref val2)).normalized, ((Vector3)(ref val)).normalized)) > 0.99f)
{
val2 = ((Component)this).transform.up;
}
Vector3 val3 = connectedT.forward;
if (Mathf.Abs(Vector3.Dot(((Vector3)(ref val3)).normalized, ((Vector3)(ref val)).normalized)) > 0.99f)
{
val3 = connectedT.up;
}
Vector3 val4 = Vector3.ProjectOnPlane(val2, val);
Vector3 val5 = Vector3.ProjectOnPlane(val3, val);
if (((Vector3)(ref val4)).sqrMagnitude < 1E-08f || ((Vector3)(ref val5)).sqrMagnitude < 1E-08f)
{
return 0f;
}
((Vector3)(ref val4)).Normalize();
((Vector3)(ref val5)).Normalize();
float num = Mathf.Clamp(Vector3.Dot(val4, val5), -1f, 1f);
float num2 = Mathf.Acos(num) * 57.29578f;
float num3 = Mathf.Sign(Vector3.Dot(val, Vector3.Cross(val4, val5)));
return num2 * num3;
}
public float ComputeLimitSpringTorqueLocal()
{
Transform val = (Object.op_Implicit((Object)(object)connectedRb) ? ((Component)connectedRb).transform : (Object.op_Implicit((Object)(object)((Component)this).transform.parent) ? ((Component)this).transform.parent : null));
if ((Object)(object)val == (Object)null)
{
return 0f;
}
float num = ComputeTwistAngleDeg(val);
float num2 = 0f;
if (num < lowAngularXLimitDeg)
{
float num3 = (num - lowAngularXLimitDeg) * ((float)Math.PI / 180f);
num2 = (0f - springX) * num3;
}
else if (num > highAngularXLimitDeg)
{
float num4 = (num - highAngularXLimitDeg) * ((float)Math.PI / 180f);
num2 = (0f - springX) * num4;
}
num2 = Mathf.Abs(num2);
if (num2 > breakThreshold)
{
Debug.Log((object)("torque exceeded threshold. Breaking joint: " + num2));
JointStrength component = ((Component)this).GetComponent<JointStrength>();
if ((Object)(object)component != (Object)null)
{
component.DealMuscleDamage();
component.DealMuscleDamage();
component.DealMuscleDamage();
component.DealMuscleDamage();
}
joint.angularXMotion = (ConfigurableJointMotion)2;
joint.angularYMotion = (ConfigurableJointMotion)2;
joint.angularZMotion = (ConfigurableJointMotion)2;
isBroken = true;
}
return num2;
}
private static float NormalizeDeg(float a)
{
a = (a + 180f) % 360f;
if (a < 0f)
{
a += 360f;
}
return a - 180f;
}
}
[DisallowMultipleComponent]
public class BluntTransmitter : MonoBehaviour
{
public struct ContactInfo
{
public Collider closestCollider;
public Vector3 worldAnchor;
public Vector3 moverLocalAnchor;
public Vector3 targetLocalAnchor;
}
public static float baseDeltaTime;
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;
public static HashSet<PlayerHealth> recoveringPlayers = new HashSet<PlayerHealth>();
private static Dictionary<string, float> lastGrabTimes = new Dictionary<string, float>();
public 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 List<HandState> stateHistory = new List<HandState>();
private void Start()
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: 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_012e: Unknown result type (might be due to invalid IL or missing references)
baseDeltaTime = Time.fixedDeltaTime;
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;
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()
{
}
public PlayerHealth GetNeckPlayerHealth()
{
return ((Component)((Component)this).transform.root).GetComponentInChildren<PlayerHealth>();
}
private void OnCollisionEnter(Collision collision)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
((MonoBehaviour)this).StartCoroutine(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, 25f));
List<PlayerHealth> enemies = new List<PlayerHealth>();
float explosionRadius = 4f;
float explosionForce = 16f;
((MonoBehaviour)this).StartCoroutine(GradualSlowMotion(0.3f, 0.5f, 1f));
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 IEnumerator HandleCollision(Collision collision)
{
yield return (object)new WaitForEndOfFrame();
yield return (object)new WaitForFixedUpdate();
yield return (object)new WaitForEndOfFrame();
Rigidbody targetRigidbody = collision.rigidbody;
Vector3 val = collision.impulse;
float impulseMagnitude = ((Vector3)(ref val)).magnitude;
if (impulseMagnitude < 20f || (Object)(object)targetRigidbody == (Object)null || (((Object)targetRigidbody).name.ToLower().Contains("left") && ((Object)((Component)this).gameObject).name.ToLower().Contains("neck")) || (((Object)targetRigidbody).name.ToLower().Contains("right") && ((Object)((Component)this).gameObject).name.ToLower().Contains("neck")))
{
yield break;
}
val = collision.impulse;
Vector3 rawDir = ((Vector3)(ref val)).normalized;
Vector3 totalNormal = Vector3.zero;
int contactCount = collision.contactCount;
for (int i = 0; i < contactCount; i++)
{
Vector3 val2 = totalNormal;
ContactPoint contact = collision.GetContact(i);
totalNormal = val2 + ((ContactPoint)(ref contact)).normal;
}
Vector3 averagedContactNormal = ((Vector3)(ref totalNormal)).normalized;
if (Vector3.Dot(rawDir, averagedContactNormal) > 0f)
{
rawDir = -rawDir;
}
Vector3 ImpactDirection = rawDir;
float impactForce = impulseMagnitude * forceMultiplier;
PlayerHealth[] attackerPHs = ((Component)objectRigidbody).GetComponentsInParent<PlayerHealth>();
PlayerHealth[] targetPHs = ((Component)targetRigidbody).GetComponentsInParent<PlayerHealth>();
if (attackerPHs.Intersect(targetPHs).Any())
{
yield break;
}
Debug.Log((object)$"{((Object)((Component)objectRigidbody).gameObject).name} collided with {((Object)targetRigidbody).name} with an impulse magnitude of {impulseMagnitude}. Impact Force: {impactForce}");
if (((Object)targetRigidbody).name.ToLower().Contains("cuttable") || (((Object)targetRigidbody).name.ToLower().Contains("neck") && ((Object)((Component)targetRigidbody).transform.parent).name.ToLower().Contains("cuttable")))
{
Debug.Log((object)"FOOOOOOOOOTBALL");
targetRigidbody.AddForce(ImpactDirection * impactForce * 4f, (ForceMode)1);
val = objectRigidbody.velocity;
Vector3 torque = Vector3.Cross(ImpactDirection, ((Vector3)(ref val)).normalized) * (impactForce * torqueMultiplier);
targetRigidbody.AddTorque(torque, (ForceMode)1);
if ((Object)(object)objectRigidbody != (Object)null)
{
Vector3 recoilForce = -objectRigidbody.velocity * objectRigidbody.mass;
objectRigidbody.AddForce(recoilForce, (ForceMode)1);
}
SphereCollider existingCollider = ((Component)targetRigidbody).GetComponent<SphereCollider>();
if ((Object)(object)existingCollider == (Object)null)
{
Debug.Log((object)"Neck found! Adding sphere collider...");
SphereCollider sphereCollider = ((Component)targetRigidbody).gameObject.AddComponent<SphereCollider>();
sphereCollider.radius = 0.16f;
((Collider)sphereCollider).isTrigger = false;
Vector3 localCOM = ((Component)targetRigidbody).transform.InverseTransformPoint(targetRigidbody.worldCenterOfMass);
sphereCollider.center = localCOM;
}
}
PlayerHealth[] characters = Object.FindObjectsOfType<PlayerHealth>();
PlayerHealth[] array = characters;
foreach (PlayerHealth character in array)
{
Rigidbody[] bodyparts = ((Component)character).GetComponentsInChildren<Rigidbody>();
Rigidbody[] array2 = bodyparts;
foreach (Rigidbody bodypart in array2)
{
if (!((Object)(object)bodypart == (Object)(object)targetRigidbody) || ((Component)bodypart).gameObject.layer == LayerMask.NameToLayer("Weapons") || ((Object)bodypart).name.ToLower().Contains("right") || ((Object)bodypart).name.ToLower().Contains("left"))
{
continue;
}
((Object)bodypart).name.ToLower();
if (!character.alive && character.bloodAmount >= 0.10000000149011612)
{
impactForce *= 3f;
targetRigidbody.AddForce(ImpactDirection * (impactForce / 8f) * (FeelThePunch.Instance.KOKnockbackMultiplier / 10f) / 10f, (ForceMode)2);
((MonoBehaviour)this).StartCoroutine(GradualSlowMotion(0.3f, 0.5f, 1f));
((MonoBehaviour)this).StartCoroutine(KO(character, impulseMagnitude, ImpactDirection, impactForce, FeelThePunch.Instance.DisarmOnKO));
character.bloodAmount = 0.0;
}
if (impulseMagnitude >= 100f)
{
targetRigidbody.AddForce(ImpactDirection * (impactForce / 8f) * (FeelThePunch.Instance.KOKnockbackMultiplier / 10f) / 10f, (ForceMode)2);
((MonoBehaviour)this).StartCoroutine(GradualSlowMotion(0.3f, 0.5f, 1f));
if (impulseMagnitude >= 120f && !((Object)targetRigidbody).name.ToLower().Contains("left") && !((Object)targetRigidbody).name.ToLower().Contains("right"))
{
((MonoBehaviour)this).StartCoroutine(KO(character, impulseMagnitude, ImpactDirection, impactForce, FeelThePunch.Instance.DisarmOnKO));
}
}
}
}
}
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)
if (recoveringPlayers.Contains(playerCharacter))
{
yield break;
}
recoveringPlayers.Add(playerCharacter);
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) / 10f, (ForceMode)2);
}
if ((Object)(object)playerCharacter.ballHolderjoint != (Object)null)
{
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);
}
}
}
playerCharacter.bloodAmount -= 0.5;
float bloodAmount = (float)playerCharacter.bloodAmount;
float koDuration = Mathf.Clamp(impulseMagnitude / 30f / bloodAmount, 1f, 8f);
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 static IEnumerator GradualSlowMotion(float slowMultiplier, float transitionDuration, float holdTime)
{
if (isSlowMotionRunning)
{
yield break;
}
isSlowMotionRunning = true;
try
{
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);
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;
}
finally
{
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 = FeelThePunch.Instance.ForceNeededToBreakFromGrab;
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"))
{
((Component)enemyLimb).gameObject.AddComponent<ReceiveEnvironmentalDamage>();
}
}
float ReleaseElapsed = 0f;
float ReleaseMaxDuration = FeelThePunch.Instance.GrabDurationInSeconds;
if (((Behaviour)enemyCharacter).enabled && !enemyCharacter.alive)
{
ReleaseMaxDuration *= 2f;
}
if (!((Behaviour)enemyCharacter).enabled)
{
ReleaseMaxDuration *= 2f;
}
bool alreadyModified = globallyModifiedEnemies.Contains(enemyCharacter);
Rigidbody leftFoot = null;
Rigidbody rightFoot = null;
if ((Object)(object)leftFoot == (Object)null || (Object)(object)rightFoot == (Object)null)
{
Rigidbody[] allChildren = ((Component)enemyCharacter).GetComponentsInChildren<Rigidbody>();
Rigidbody[] array2 = allChildren;
foreach (Rigidbody child in array2)
{
if (((Object)child).name == "KNEE_LEFT")
{
leftFoot = child;
}
if (((Object)child).name == "KNEE_RIGHT")
{
rightFoot = child;
}
}
}
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 && 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.worldCenterOfMass + rightFoot.worldCenterOfMass) / 2f;
val3 = worldCOM2 - avgFeetPos2;
Vector3 dirToCOM2 = ((Vector3)(ref val3)).normalized;
float angle2 = Vector3.Angle(dirToCOM2, Vector3.up);
if (angle2 > FeelThePunch.Instance.AngleToloseBalanceDuringGrab && (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 fighterJoint2 in enemyCharacter.playerAnimator.FighterJoints)
{
if ((Object)(object)fighterJoint2.jointStrength != (Object)null && fighterJoint2.jointStrength.instancesOfDamage < 1 && fighterJoint2.jointStrength.jointName == "HIP")
{
fighterJoint2.jointStrength.SetStrengthPercent(1f);
Debug.Log((object)("DECREASED Strength for HIPS, Takedown Succesfull " + fighterJoint2.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.worldCenterOfMass + rightFoot.worldCenterOfMass) / 2f;
val3 = worldCOM - avgFeetPos;
Vector3 dirToCOM = ((Vector3)(ref val3)).normalized;
float angle = Vector3.Angle(dirToCOM, Vector3.up);
if (!(angle < 15f) || !((Object)(object)enemyCharacter.ballHolderjoint != (Object)null))
{
if (angle > 15f && (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_126f;
}
}
num = 0;
goto IL_126f;
}
((MonoBehaviour)this).StartCoroutine(RestoreBallHolderJoint(enemyCharacter, 1f));
alreadyModified = false;
}
goto IL_136b;
IL_126f:
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_136b;
IL_136b:
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[] array3 = EnviroDamages;
foreach (ReceiveEnvironmentalDamage EnviroDamage in array3)
{
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 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: 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)
{
if (!val2.isKinematic)
{
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);
}
}
}
public class CarotidChoke : MonoBehaviour
{
private class CarotidSensor : MonoBehaviour
{
internal CarotidChoke owner;
internal bool isLeft;
private void OnTriggerEnter(Collider other)
{
owner?.HandleTrigger(isLeft, other, entering: true);
}
private void OnTriggerExit(Collider other)
{
owner?.HandleTrigger(isLeft, other, entering: false);
}
}
[Header("Trigger Geometry")]
[Tooltip("Side offset from neck center in local X (meters).")]
public float sideOffset = 0.1f;
[Tooltip("Trigger radius (meters).")]
public float triggerRadius = 0.1f;
[Header("Timing (seconds)")]
[Tooltip("Time required with both triggers occupied to fire the first effect.")]
public float firstThresholdSeconds = 5f;
[Tooltip("Time required with both triggers occupied to kill.")]
public float killThresholdSeconds = 10f;
[Header("Filtering")]
[Tooltip("Only count colliders on these layers. Set to Everything to accept all.")]
public LayerMask contactLayers = LayerMask.op_Implicit(-1);
[Header("Rigidbody Setup")]
[Tooltip("If no Rigidbody found in this transform or its parents, add a kinematic one so triggers work.")]
public bool addKinematicRigidbodyIfMissing = true;
[Header("Events (optional hooks)")]
public UnityEvent TenSecondsReached;
public UnityEvent TwentySecondsReached_Kill;
private HashSet<Collider> _leftContacts = new HashSet<Collider>();
private HashSet<Collider> _rightContacts = new HashSet<Collider>();
private Coroutine _chokeCo;
private float _timer;
private bool _fired10;
private bool _fired20;
private Transform _leftTriggerT;
private Transform _rightTriggerT;
private Rigidbody _anyRigid;
private Transform _selfRoot;
private void Awake()
{
_selfRoot = ((Component)this).transform.root;
EnsureRigidbodyPresence();
CreateOrFetchTriggers();
}
private void OnDisable()
{
ResetChoke(stopRoutine: true);
}
internal void HandleTrigger(bool isLeft, Collider other, bool entering)
{
if (PassesFilter(other))
{
HashSet<Collider> hashSet = (isLeft ? _leftContacts : _rightContacts);
if (entering)
{
hashSet.Add(other);
}
else
{
hashSet.Remove(other);
}
UpdateChokeState();
Debug.Log((object)("Collider detected: " + ((Object)((Component)other.attachedRigidbody).gameObject).name));
}
}
private bool PassesFilter(Collider other)
{
if ((Object)(object)other == (Object)null)
{
Debug.Log((object)"Didnt Pass filter because Other is Null...");
return false;
}
if ((Object)(object)other.attachedRigidbody == (Object)null)
{
Debug.Log((object)"Didnt Pass filter because Other.Rigidbody is Null...");
return false;
}
PlayerHealth componentInParent = ((Component)this).GetComponentInParent<PlayerHealth>();
if ((Object)(object)componentInParent != (Object)null && !componentInParent.alive)
{
return false;
}
PlayerHealth componentInParent2 = ((Component)other).GetComponentInParent<PlayerHealth>();
if ((Object)(object)componentInParent2 == (Object)null)
{
return false;
}
string text = ((Object)((Component)other.attachedRigidbody).gameObject).name.ToLower();
if (text.ToLower().Contains("trigger"))
{
return false;
}
if ((Object)(object)componentInParent == (Object)(object)componentInParent2)
{
return false;
}
return true;
}
private void UpdateChokeState()
{
bool flag = BothActive();
if (flag && _chokeCo == null)
{
_chokeCo = ((MonoBehaviour)this).StartCoroutine(ChokeRoutine());
Debug.Log((object)"CHOKIIIIING");
Debug.Log((object)"CHOKIIIIING");
Debug.Log((object)"CHOKIIIIING");
Debug.Log((object)"CHOKIIIIING");
Debug.Log((object)"CHOKIIIIING");
Debug.Log((object)"CHOKIIIIING");
}
else if (!flag && _chokeCo != null)
{
ResetChoke(stopRoutine: true);
}
}
private bool BothActive()
{
return _leftContacts.Count > 0 && _rightContacts.Count > 0;
}
private IEnumerator ChokeRoutine()
{
_timer = 0f;
_fired10 = false;
_fired20 = false;
while (BothActive())
{
_timer += Time.deltaTime;
if (!_fired10 && _timer >= firstThresholdSeconds)
{
_fired10 = true;
OnTenSecondsReached();
}
if (!_fired20 && _timer >= killThresholdSeconds)
{
_fired20 = true;
OnTwentySecondsReached_Kill();
break;
}
yield return null;
}
if (!_fired20)
{
ResetChoke(stopRoutine: true);
}
}
private void ResetChoke(bool stopRoutine)
{
_timer = 0f;
_fired10 = false;
_fired20 = false;
if (stopRoutine && _chokeCo != null)
{
((MonoBehaviour)this).StopCoroutine(_chokeCo);
_chokeCo = null;
}
}
private void OnTenSecondsReached()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
PlayerHealth componentInParent = ((Component)this).GetComponentInParent<PlayerHealth>();
if (!((Object)(object)componentInParent == (Object)null))
{
BluntTransmitter componentInChildren = ((Component)componentInParent).GetComponentInChildren<BluntTransmitter>();
if ((Object)(object)componentInChildren != (Object)null)
{
((MonoBehaviour)componentInChildren).StartCoroutine(componentInChildren.KO(componentInParent, 50000f, Vector3.zero, 50000f, FeelThePunch.Instance.DisarmOnKO));
}
}
}
private void OnTwentySecondsReached_Kill()
{
PlayerHealth componentInParent = ((Component)this).GetComponentInParent<PlayerHealth>();
if (!((Object)(object)componentInParent == (Object)null))
{
componentInParent.Die((DeathReason)6);
}
}
private void EnsureRigidbodyPresence()
{
_anyRigid = ((Component)this).GetComponentInParent<Rigidbody>();
if ((Object)(object)_anyRigid == (Object)null && addKinematicRigidbodyIfMissing)
{
_anyRigid = ((Component)this).gameObject.AddComponent<Rigidbody>();
_anyRigid.isKinematic = true;
_anyRigid.useGravity = false;
}
}
private void CreateOrFetchTriggers()
{
_leftTriggerT = FindOrCreateTrigger("LeftCarotidTrigger", 1f);
_rightTriggerT = FindOrCreateTrigger("RightCarotidTrigger", -1f);
}
private Transform FindOrCreateTrigger(string name, float sideSign)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: 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)
Transform val = ((Component)this).transform.Find(name);
if ((Object)(object)val == (Object)null)
{
GameObject val2 = new GameObject(name);
val2.layer = ((Component)this).gameObject.layer;
val = val2.transform;
val.SetParent(((Component)this).transform, false);
}
val.localPosition = Vector3.right * (sideOffset * sideSign);
val.localRotation = Quaternion.identity;
val.localScale = Vector3.one;
Transform val3 = val.Find("trigger");
GameObject val4;
if ((Object)(object)val3 == (Object)null)
{
val4 = new GameObject("trigger");
val4.layer = ((Component)val).gameObject.layer;
val3 = val4.transform;
val3.SetParent(val, false);
val3.localPosition = Vector3.zero;
val3.localRotation = Quaternion.identity;
val3.localScale = Vector3.one;
}
else
{
val4 = ((Component)val3).gameObject;
}
SphereCollider val5 = val4.GetComponent<SphereCollider>();
if ((Object)(object)val5 == (Object)null)
{
val5 = val4.AddComponent<SphereCollider>();
}
((Collider)val5).isTrigger = true;
val5.radius = triggerRadius;
val5.center = Vector3.zero;
CarotidSensor carotidSensor = val4.GetComponent<CarotidSensor>();
if ((Object)(object)carotidSensor == (Object)null)
{
carotidSensor = val4.AddComponent<CarotidSensor>();
}
carotidSensor.owner = this;
carotidSensor.isLeft = sideSign > 0f;
Rigidbody val6 = val4.GetComponent<Rigidbody>();
if ((Object)(object)val6 == (Object)null)
{
val6 = val4.AddComponent<Rigidbody>();
val6.isKinematic = true;
val6.useGravity = false;
}
val6.collisionDetectionMode = (CollisionDetectionMode)3;
return val;
}
}