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 UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ImprovedCharacterPhysics")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImprovedCharacterPhysics")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8f40caaf-d3bb-483d-8cda-37a323a87a4a")]
[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")]
namespace ImprovedCharacterPhysics;
[BepInPlugin("com.m4gmar.ImprovedCharacterPhysics", "Improved Character Physics Mod", "1.9.7")]
public class ImprovedCharacterPhysics : BaseUnityPlugin
{
public PhysicMaterial floorPhyMaterial;
private ConfigurableJoint HipStabilizer;
private List<ConfigurableJoint> shoulderJoints = new List<ConfigurableJoint>();
private List<ConfigurableJoint> elbowJoints = new List<ConfigurableJoint>();
private List<ConfigurableJoint> hipJoints = new List<ConfigurableJoint>();
private List<ConfigurableJoint> kneeJoints = new List<ConfigurableJoint>();
private List<ConfigurableJoint> spineJoints = new List<ConfigurableJoint>();
private List<ConfigurableJoint> hipStabilizerJoints = new List<ConfigurableJoint>();
private float[] shoulderStamina;
private float[] elbowStamina;
private float[] hipStamina;
private float[] kneeStamina;
private float[] spineStamina;
private Quaternion[] prevShoulderRotations;
private Quaternion[] prevElbowRotations;
private Quaternion[] prevHipRotations;
private Quaternion[] prevKneeRotations;
private Quaternion[] prevSpineRotations;
private Quaternion[] StartingHipStabilizerRotations;
private Dictionary<string, PlayerHealth> playerHealths = new Dictionary<string, PlayerHealth>();
private Dictionary<string, float> playerCardioStamina = new Dictionary<string, float>();
private Dictionary<string, int> jointFrameCount = new Dictionary<string, int>();
private Dictionary<ConfigurableJoint, float> originalPositionSprings = new Dictionary<ConfigurableJoint, float>();
private Dictionary<ConfigurableJoint, float> originalPositionDampers = new Dictionary<ConfigurableJoint, float>();
private Dictionary<ConfigurableJoint, float> originalMaximumForces = new Dictionary<ConfigurableJoint, float>();
private float updateInterval = 0.1f;
private bool showMenu = false;
private InputAction toggleMenuAction;
public bool useMod = true;
public bool useCustomHipStabilizer = true;
public float hipStabilizerStrengthMultiplier = 100f;
public float hipStabilizerDamperMultiplier = 100f;
public float armStrenghtMultiplier = 100f;
public float legStrengthMultiplier = 100f;
public float spineStrenghtMultiplier = 100f;
public float minMovementSpeedToDrainStamina = 110f;
public float armsStaminaDrainMultiplier = 50f;
public float armsStaminaRegenMultiplier = 100f;
public float legsStaminaDrainMultiplier = 120f;
public float legsStaminaRegenMultiplier = 100f;
public float cardioVascularStaminaDrainMultiplier = 80f;
public float cardioVascularStaminaRegenMultiplier = 40f;
public float floorFriction = 60f;
public void Awake()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
((Object)Chainloader.ManagerObject).hideFlags = (HideFlags)61;
((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
Harmony val = new Harmony("com.m4gmar.ImprovedCharacterPhysics");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches applied.");
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnEnable()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
toggleMenuAction = new InputAction("ToggleMenu", (InputActionType)1, "<Keyboard>/f8", (string)null, (string)null, (string)null);
toggleMenuAction.performed += delegate
{
ToggleMenu();
};
toggleMenuAction.Enable();
}
private void OnDisable()
{
toggleMenuAction.Disable();
toggleMenuAction.performed -= delegate
{
ToggleMenu();
};
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("SCENE LOADED: " + ((Scene)(ref scene)).name));
((MonoBehaviour)this).StopAllCoroutines();
if (((Scene)(ref scene)).name.ToLower().Contains("map") || ((Scene)(ref scene)).name.ToLower().Contains("test"))
{
shoulderJoints.Clear();
elbowJoints.Clear();
hipJoints.Clear();
kneeJoints.Clear();
spineJoints.Clear();
hipStabilizerJoints.Clear();
playerHealths.Clear();
playerCardioStamina.Clear();
jointFrameCount.Clear();
originalPositionSprings.Clear();
originalPositionDampers.Clear();
originalMaximumForces.Clear();
shoulderStamina = null;
elbowStamina = null;
hipStamina = null;
kneeStamina = null;
spineStamina = null;
prevShoulderRotations = null;
prevElbowRotations = null;
prevHipRotations = null;
prevKneeRotations = null;
prevSpineRotations = null;
updateInterval = 0.1f;
if (useMod)
{
((MonoBehaviour)this).StartCoroutine(WaitForPlayerObjects());
}
}
}
private IEnumerator WaitForPlayerObjects()
{
yield return (object)new WaitForSeconds(0.5f);
((BaseUnityPlugin)this).Logger.LogInfo((object)"ObjectsLoaded, running Mod");
ChangeFloorPhysicsMaterial();
PlayerHealth[] playersHealth = Object.FindObjectsOfType<PlayerHealth>();
PlayerHealth[] array = playersHealth;
foreach (PlayerHealth playerHealth in array)
{
List<Transform> parentHierarchy = new List<Transform>();
Transform current = ((Component)playerHealth).transform;
while ((Object)(object)current.parent != (Object)null)
{
parentHierarchy.Add(current.parent);
current = current.parent;
}
GameObject character;
if (parentHierarchy.Count >= 3)
{
character = ((Component)parentHierarchy[parentHierarchy.Count - 3]).gameObject;
Debug.Log((object)("Found Character: " + ((Object)character).name));
}
else
{
character = ((Component)playerHealth).gameObject;
Debug.Log((object)("Found Character " + ((Object)((Component)playerHealth).gameObject).name));
}
if (!playerHealths.ContainsKey(((Object)character).name))
{
playerHealths.Add(((Object)character).name, playerHealth);
playerCardioStamina.Add(((Object)character).name, 100f);
((BaseUnityPlugin)this).Logger.LogInfo((object)("Added player " + ((Object)character).name + " with 100 cardio stamina."));
}
}
foreach (ConfigurableJoint item in Object.FindObjectsOfType<ConfigurableJoint>().ToList())
{
if (!((Object)(object)item == (Object)null) && !((Object)(object)((Joint)item).connectedBody == (Object)null) && !((Object)(object)((Component)((Joint)item).connectedBody).gameObject == (Object)null))
{
JointDrive val;
if (((Object)((Component)((Joint)item).connectedBody).gameObject).name == "HipSphere" && useCustomHipStabilizer)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"HipStabilizer FOUND!!!, Switching to CustomStabilizer");
val = default(JointDrive);
((JointDrive)(ref val)).positionSpring = 10000f;
((JointDrive)(ref val)).positionDamper = 2700f * (hipStabilizerDamperMultiplier / 100f);
((JointDrive)(ref val)).maximumForce = float.MaxValue;
item.angularXDrive = val;
val = default(JointDrive);
((JointDrive)(ref val)).positionSpring = 10000f;
((JointDrive)(ref val)).positionDamper = 2700f * (hipStabilizerDamperMultiplier / 100f);
((JointDrive)(ref val)).maximumForce = 2500f * (hipStabilizerStrengthMultiplier / 100f);
item.angularYZDrive = val;
HipStabilizer = item;
Dictionary<ConfigurableJoint, float> dictionary = originalPositionSprings;
val = item.angularXDrive;
dictionary[item] = ((JointDrive)(ref val)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary2 = originalPositionDampers;
val = item.angularXDrive;
dictionary2[item] = ((JointDrive)(ref val)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary3 = originalMaximumForces;
val = item.angularXDrive;
dictionary3[item] = ((JointDrive)(ref val)).maximumForce;
}
_ = ((Object)((Component)((Component)((Joint)item).connectedBody).gameObject.transform.root).gameObject).name;
switch (((Object)((Component)((Joint)item).connectedBody).gameObject).name.ToLower())
{
case "shoulder_left":
((BaseUnityPlugin)this).Logger.LogInfo((object)"ShoulderLeft Joint Found!!!");
shoulderJoints.Add(item);
originalPositionSprings[item] = 1700f;
originalPositionDampers[item] = 150f;
originalMaximumForces[item] = 650f * (armStrenghtMultiplier / 100f);
break;
case "shoulder_right":
((BaseUnityPlugin)this).Logger.LogInfo((object)"ShoulderRight Joint Found!!!");
shoulderJoints.Add(item);
originalPositionSprings[item] = 1700f;
originalPositionDampers[item] = 150f;
originalMaximumForces[item] = 650f * (armStrenghtMultiplier / 100f);
break;
case "elbow_left":
((BaseUnityPlugin)this).Logger.LogInfo((object)"ElbowLeft Joint Found!!!");
elbowJoints.Add(item);
originalPositionSprings[item] = 1700f;
originalPositionDampers[item] = 150f;
originalMaximumForces[item] = 475f * (armStrenghtMultiplier / 100f);
break;
case "elbow_right":
((BaseUnityPlugin)this).Logger.LogInfo((object)"ElbowRight Joint Found!!!");
elbowJoints.Add(item);
originalPositionSprings[item] = 1700f;
originalPositionDampers[item] = 150f;
originalMaximumForces[item] = 475f * (armStrenghtMultiplier / 100f);
break;
case "hip_joint_left":
((BaseUnityPlugin)this).Logger.LogInfo((object)"HipJointLeft Joint Found!!!");
hipJoints.Add(item);
originalPositionSprings[item] = 10000f;
originalPositionDampers[item] = 900f;
originalMaximumForces[item] = 1500f * (legStrengthMultiplier / 100f);
break;
case "hip_joint_right":
((BaseUnityPlugin)this).Logger.LogInfo((object)"HipJointRight Joint Found!!!");
hipJoints.Add(item);
originalPositionSprings[item] = 10000f;
originalPositionDampers[item] = 900f;
originalMaximumForces[item] = 1500f * (legStrengthMultiplier / 100f);
break;
case "knee_left":
((BaseUnityPlugin)this).Logger.LogInfo((object)"KneeLeft Joint Found!!!");
kneeJoints.Add(item);
originalPositionSprings[item] = 10000f;
originalPositionDampers[item] = 900f;
originalMaximumForces[item] = 1500f * (legStrengthMultiplier / 100f);
break;
case "knee_right":
((BaseUnityPlugin)this).Logger.LogInfo((object)"KneeRight Joint Found!!!");
kneeJoints.Add(item);
originalPositionSprings[item] = 10000f;
originalPositionDampers[item] = 900f;
originalMaximumForces[item] = 1500f * (legStrengthMultiplier / 100f);
break;
case "spine1":
((BaseUnityPlugin)this).Logger.LogInfo((object)"Spine1 Joint Found!!! Skipping stamina system.");
spineJoints.Add(item);
val = default(JointDrive);
((JointDrive)(ref val)).positionDamper = 650f;
((JointDrive)(ref val)).positionSpring = 7000f;
((JointDrive)(ref val)).maximumForce = 1500f * (spineStrenghtMultiplier / 100f);
item.angularXDrive = val;
val = default(JointDrive);
((JointDrive)(ref val)).positionDamper = 650f;
((JointDrive)(ref val)).positionSpring = 7000f;
((JointDrive)(ref val)).maximumForce = 1500f * (spineStrenghtMultiplier / 100f);
item.angularYZDrive = val;
break;
case "spine2":
((BaseUnityPlugin)this).Logger.LogInfo((object)"Spine2 Joint Found!!! Skipping stamina system.");
spineJoints.Add(item);
val = default(JointDrive);
((JointDrive)(ref val)).positionDamper = 650f;
((JointDrive)(ref val)).positionSpring = 7000f;
((JointDrive)(ref val)).maximumForce = 1500f * (spineStrenghtMultiplier / 100f);
item.angularXDrive = val;
val = default(JointDrive);
((JointDrive)(ref val)).positionDamper = 650f;
((JointDrive)(ref val)).positionSpring = 7000f;
((JointDrive)(ref val)).maximumForce = 1500f * (spineStrenghtMultiplier / 100f);
item.angularYZDrive = val;
break;
case "hipsphere":
((BaseUnityPlugin)this).Logger.LogInfo((object)"HipStabilizer Joint Found!!! Skipping stamina system.");
hipStabilizerJoints.Add(item);
break;
}
}
}
shoulderStamina = new float[shoulderJoints.Count];
elbowStamina = new float[elbowJoints.Count];
hipStamina = new float[hipJoints.Count];
kneeStamina = new float[kneeJoints.Count];
spineStamina = new float[spineJoints.Count];
prevShoulderRotations = (Quaternion[])(object)new Quaternion[shoulderJoints.Count];
prevElbowRotations = (Quaternion[])(object)new Quaternion[elbowJoints.Count];
prevHipRotations = (Quaternion[])(object)new Quaternion[hipJoints.Count];
prevKneeRotations = (Quaternion[])(object)new Quaternion[kneeJoints.Count];
prevSpineRotations = (Quaternion[])(object)new Quaternion[spineJoints.Count];
StartingHipStabilizerRotations = (Quaternion[])(object)new Quaternion[hipStabilizerJoints.Count];
for (int i = 0; i < hipStabilizerJoints.Count; i++)
{
StartingHipStabilizerRotations[i] = ((Component)((Joint)hipStabilizerJoints[i]).connectedBody).transform.rotation;
}
for (int j = 0; j < shoulderJoints.Count; j++)
{
shoulderStamina[j] = 100f;
prevShoulderRotations[j] = ((Component)shoulderJoints[j]).transform.localRotation * Quaternion.Inverse(shoulderJoints[j].targetRotation);
}
for (int l = 0; l < elbowJoints.Count; l++)
{
elbowStamina[l] = 100f;
prevElbowRotations[l] = ((Component)elbowJoints[l]).transform.localRotation * Quaternion.Inverse(elbowJoints[l].targetRotation);
}
for (int m = 0; m < hipJoints.Count; m++)
{
hipStamina[m] = 100f;
prevHipRotations[m] = ((Component)hipJoints[m]).transform.localRotation * Quaternion.Inverse(hipJoints[m].targetRotation);
}
for (int n = 0; n < kneeJoints.Count; n++)
{
kneeStamina[n] = 100f;
prevKneeRotations[n] = ((Component)kneeJoints[n]).transform.localRotation * Quaternion.Inverse(kneeJoints[n].targetRotation);
}
for (int k = 0; k < spineJoints.Count; k++)
{
spineStamina[k] = 100f;
prevSpineRotations[k] = ((Component)spineJoints[k]).transform.localRotation * Quaternion.Inverse(spineJoints[k].targetRotation);
}
updateInterval = (updateInterval * (float)(elbowJoints.Count / 2) + updateInterval) / 2f;
((BaseUnityPlugin)this).Logger.LogError((object)$"update interval is {updateInterval}");
((MonoBehaviour)this).StartCoroutine(UpdateStaminaCoroutine());
}
private IEnumerator UpdateStaminaCoroutine()
{
while (true)
{
for (int m = 0; m < shoulderJoints.Count; m++)
{
if ((Object)(object)shoulderJoints[m] != (Object)null)
{
CheckAndUpdateStamina(shoulderJoints[m], ref shoulderStamina[m], ref prevShoulderRotations[m]);
}
}
for (int l = 0; l < elbowJoints.Count; l++)
{
if ((Object)(object)elbowJoints[l] != (Object)null)
{
CheckAndUpdateStamina(elbowJoints[l], ref elbowStamina[l], ref prevElbowRotations[l]);
}
}
for (int k = 0; k < hipJoints.Count; k++)
{
if ((Object)(object)hipJoints[k] != (Object)null)
{
CheckAndUpdateStamina(hipJoints[k], ref hipStamina[k], ref prevHipRotations[k]);
}
}
for (int j = 0; j < kneeJoints.Count; j++)
{
if ((Object)(object)kneeJoints[j] != (Object)null)
{
CheckAndUpdateStamina(kneeJoints[j], ref kneeStamina[j], ref prevKneeRotations[j]);
}
}
for (int i = 0; i < hipStabilizerJoints.Count; i++)
{
if ((Object)(object)kneeJoints[i] != (Object)null)
{
HipStabilizerCalculator(hipStabilizerJoints[i], ref StartingHipStabilizerRotations[i]);
}
}
yield return (object)new WaitForSeconds(updateInterval);
}
}
private void CheckAndUpdateStamina(ConfigurableJoint joint, ref float stamina, ref Quaternion prevRotation)
{
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: 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_07d1: Unknown result type (might be due to invalid IL or missing references)
//IL_0842: Unknown result type (might be due to invalid IL or missing references)
//IL_084d: Unknown result type (might be due to invalid IL or missing references)
//IL_08be: Unknown result type (might be due to invalid IL or missing references)
//IL_06de: Unknown result type (might be due to invalid IL or missing references)
//IL_0749: Unknown result type (might be due to invalid IL or missing references)
//IL_0754: Unknown result type (might be due to invalid IL or missing references)
//IL_07bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0931: Unknown result type (might be due to invalid IL or missing references)
//IL_095e: Unknown result type (might be due to invalid IL or missing references)
//IL_0969: Unknown result type (might be due to invalid IL or missing references)
//IL_0996: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)joint == (Object)null || (Object)(object)((Joint)joint).connectedBody == (Object)null || (Object)(object)((Component)((Joint)joint).connectedBody).gameObject == (Object)null)
{
return;
}
string name = ((Object)((Component)((Component)((Joint)joint).connectedBody).gameObject.transform.root).gameObject).name;
Transform val = null;
List<Transform> list = new List<Transform>();
Transform val2 = ((Component)joint).transform;
while (!((Object)val2).name.ToLower().Contains("character"))
{
list.Add(val2.parent);
if (((Object)val2).name.ToLower() == "hip")
{
val = val2;
}
val2 = val2.parent;
}
name = ((Object)val2).name;
if (!playerCardioStamina.ContainsKey(name))
{
((BaseUnityPlugin)this).Logger.LogError((object)("Player " + name + " not found in playerCardioStamina dictionary."));
}
else
{
if (!((Object)(object)joint != (Object)null))
{
return;
}
Vector3 val3 = val.InverseTransformDirection(((Joint)joint).connectedBody.angularVelocity);
float num = ((Vector3)(ref val3)).magnitude * 57.29578f;
float num2 = num * updateInterval;
if (num2 > minMovementSpeedToDrainStamina * updateInterval)
{
if (playerCardioStamina.ContainsKey(name))
{
if (((Object)((Joint)joint).connectedBody).name.ToLower().Contains("knee") || ((Object)((Joint)joint).connectedBody).name.ToLower().Contains("hip"))
{
float num3 = num2 / (20f * Mathf.Max(Mathf.Abs(playerCardioStamina[name] - 50f) / 50f, 0.1f)) * (cardioVascularStaminaDrainMultiplier / 500f) * (legsStaminaDrainMultiplier / 100f);
playerCardioStamina[name] -= num3;
playerCardioStamina[name] = Mathf.Clamp(playerCardioStamina[name], 0.01f, 100f);
}
else
{
float num4 = num2 / (20f * Mathf.Max(Mathf.Abs(playerCardioStamina[name] - 50f) / 50f, 0.1f)) * (cardioVascularStaminaDrainMultiplier / 500f) * (armsStaminaDrainMultiplier / 100f);
playerCardioStamina[name] -= num4;
playerCardioStamina[name] = Mathf.Clamp(playerCardioStamina[name], 0.01f, 100f);
}
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("CardioVascularStamina for " + name + " wasn't found because " + name + " is not part of the PlayerList"));
}
if (((Object)((Joint)joint).connectedBody).name.ToLower().Contains("knee") || ((Object)((Joint)joint).connectedBody).name.ToLower().Contains("hip"))
{
stamina -= num2 / (20f * Mathf.Max(Mathf.Abs(stamina - 50f) / 50f, 0.1f)) * (legsStaminaDrainMultiplier / 100f);
stamina = Mathf.Clamp(stamina, 0.01f, 100f);
}
else
{
stamina -= num2 / (20f * Mathf.Max(Mathf.Abs(stamina - 50f) / 50f, 0.1f)) * (armsStaminaDrainMultiplier / 100f);
stamina = Mathf.Clamp(stamina, 0.01f, 100f);
}
if (jointFrameCount.ContainsKey(((Object)((Component)((Joint)joint).connectedBody).gameObject).name.ToLower()))
{
jointFrameCount[((Object)((Component)((Joint)joint).connectedBody).gameObject).name.ToLower()] = 0;
}
}
if (num2 < minMovementSpeedToDrainStamina * updateInterval)
{
if (((Object)((Joint)joint).connectedBody).name.ToLower().Contains("knee") || ((Object)((Joint)joint).connectedBody).name.ToLower().Contains("hip"))
{
stamina += 20f * updateInterval * (legsStaminaRegenMultiplier / 100f);
stamina = Mathf.Clamp(stamina, 0.01f, 100f);
playerCardioStamina[name] += 5f * (cardioVascularStaminaRegenMultiplier / 100f) * updateInterval;
playerCardioStamina[name] = Mathf.Clamp(playerCardioStamina[name], 0.01f, 100f);
}
else
{
stamina += 20f * updateInterval * (armsStaminaRegenMultiplier / 100f);
stamina = Mathf.Clamp(stamina, 0.01f, 100f);
playerCardioStamina[name] += 5f * (cardioVascularStaminaRegenMultiplier / 100f) * updateInterval;
playerCardioStamina[name] = Mathf.Clamp(playerCardioStamina[name], 0.01f, 100f);
}
string key = ((Object)((Component)((Joint)joint).connectedBody).gameObject).name.ToLower();
if (!jointFrameCount.ContainsKey(key))
{
jointFrameCount[key] = 0;
}
jointFrameCount[key]++;
if ((float)jointFrameCount[key] >= 2f / updateInterval)
{
stamina = 100f;
jointFrameCount[key] = 0;
}
}
float num5 = (float)((Component)val2).GetComponent<PlayerHealth>().bloodAmount / 2f;
num5 = Mathf.Clamp(num5, 0.0001f, 1f);
JointDrive val4;
if (originalPositionSprings.TryGetValue(joint, out var value) && originalPositionDampers.TryGetValue(joint, out var value2) && originalMaximumForces.TryGetValue(joint, out var value3))
{
if (num5 <= 0.4f)
{
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = value * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f) * num5;
((JointDrive)(ref val4)).positionDamper = value2 * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f) * num5;
((JointDrive)(ref val4)).maximumForce = float.MaxValue;
joint.angularXDrive = val4;
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = value * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f) * num5;
((JointDrive)(ref val4)).positionDamper = value2 * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f) * num5;
((JointDrive)(ref val4)).maximumForce = float.MaxValue;
joint.angularYZDrive = val4;
}
else
{
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = value * Mathf.Clamp((stamina + stamina + playerCardioStamina[name]) / 3f / 100f, 0.75f, 1f);
((JointDrive)(ref val4)).positionDamper = value2;
((JointDrive)(ref val4)).maximumForce = value3 * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f);
joint.angularXDrive = val4;
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = value * Mathf.Clamp((stamina + stamina + playerCardioStamina[name]) / 3f / 100f, 0.75f, 1f);
((JointDrive)(ref val4)).positionDamper = value2;
((JointDrive)(ref val4)).maximumForce = value3 * ((stamina + stamina + playerCardioStamina[name]) / 3f / 100f);
joint.angularYZDrive = val4;
}
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)("Original position spring or damper not found for joint " + ((Object)((Component)((Joint)joint).connectedBody).gameObject).name));
}
if (num5 <= 0.3f && ((Object)((Component)((Joint)joint).connectedBody).gameObject).name.ToLower().Contains("knee"))
{
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = 0.1f;
((JointDrive)(ref val4)).positionDamper = 0.1f;
((JointDrive)(ref val4)).maximumForce = 0.1f;
joint.angularXDrive = val4;
val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = 0.1f;
((JointDrive)(ref val4)).positionDamper = 0.1f;
((JointDrive)(ref val4)).maximumForce = 0.1f;
joint.angularYZDrive = val4;
}
}
}
public void UpdateJointValues()
{
//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)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0103: 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_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_025a: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Unknown result type (might be due to invalid IL or missing references)
//IL_029a: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
//IL_0317: Unknown result type (might be due to invalid IL or missing references)
//IL_033a: Unknown result type (might be due to invalid IL or missing references)
//IL_033f: Unknown result type (might be due to invalid IL or missing references)
//IL_0357: Unknown result type (might be due to invalid IL or missing references)
//IL_035c: Unknown result type (might be due to invalid IL or missing references)
//IL_0374: Unknown result type (might be due to invalid IL or missing references)
//IL_0379: Unknown result type (might be due to invalid IL or missing references)
JointDrive angularXDrive;
foreach (ConfigurableJoint shoulderJoint in shoulderJoints)
{
if ((Object)(object)shoulderJoint != (Object)null)
{
angularXDrive = shoulderJoint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce == float.MaxValue)
{
Dictionary<ConfigurableJoint, float> dictionary = originalPositionSprings;
angularXDrive = shoulderJoint.angularXDrive;
dictionary[shoulderJoint] = ((JointDrive)(ref angularXDrive)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary2 = originalPositionDampers;
angularXDrive = shoulderJoint.angularXDrive;
dictionary2[shoulderJoint] = ((JointDrive)(ref angularXDrive)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary3 = originalMaximumForces;
angularXDrive = shoulderJoint.angularXDrive;
dictionary3[shoulderJoint] = ((JointDrive)(ref angularXDrive)).maximumForce;
}
}
}
foreach (ConfigurableJoint elbowJoint in elbowJoints)
{
if ((Object)(object)elbowJoint != (Object)null)
{
angularXDrive = elbowJoint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce == float.MaxValue)
{
Dictionary<ConfigurableJoint, float> dictionary4 = originalPositionSprings;
angularXDrive = elbowJoint.angularXDrive;
dictionary4[elbowJoint] = ((JointDrive)(ref angularXDrive)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary5 = originalPositionDampers;
angularXDrive = elbowJoint.angularXDrive;
dictionary5[elbowJoint] = ((JointDrive)(ref angularXDrive)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary6 = originalMaximumForces;
angularXDrive = elbowJoint.angularXDrive;
dictionary6[elbowJoint] = ((JointDrive)(ref angularXDrive)).maximumForce;
}
}
}
foreach (ConfigurableJoint hipJoint in hipJoints)
{
if ((Object)(object)hipJoint != (Object)null)
{
angularXDrive = hipJoint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce == float.MaxValue)
{
Dictionary<ConfigurableJoint, float> dictionary7 = originalPositionSprings;
angularXDrive = hipJoint.angularXDrive;
dictionary7[hipJoint] = ((JointDrive)(ref angularXDrive)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary8 = originalPositionDampers;
angularXDrive = hipJoint.angularXDrive;
dictionary8[hipJoint] = ((JointDrive)(ref angularXDrive)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary9 = originalMaximumForces;
angularXDrive = hipJoint.angularXDrive;
dictionary9[hipJoint] = ((JointDrive)(ref angularXDrive)).maximumForce;
}
}
}
foreach (ConfigurableJoint kneeJoint in kneeJoints)
{
if ((Object)(object)kneeJoint != (Object)null)
{
angularXDrive = kneeJoint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce == float.MaxValue)
{
Dictionary<ConfigurableJoint, float> dictionary10 = originalPositionSprings;
angularXDrive = kneeJoint.angularXDrive;
dictionary10[kneeJoint] = ((JointDrive)(ref angularXDrive)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary11 = originalPositionDampers;
angularXDrive = kneeJoint.angularXDrive;
dictionary11[kneeJoint] = ((JointDrive)(ref angularXDrive)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary12 = originalMaximumForces;
angularXDrive = kneeJoint.angularXDrive;
dictionary12[kneeJoint] = ((JointDrive)(ref angularXDrive)).maximumForce;
}
}
}
foreach (ConfigurableJoint spineJoint in spineJoints)
{
if ((Object)(object)spineJoint != (Object)null)
{
angularXDrive = spineJoint.angularXDrive;
if (((JointDrive)(ref angularXDrive)).maximumForce == float.MaxValue)
{
Dictionary<ConfigurableJoint, float> dictionary13 = originalPositionSprings;
angularXDrive = spineJoint.angularXDrive;
dictionary13[spineJoint] = ((JointDrive)(ref angularXDrive)).positionSpring;
Dictionary<ConfigurableJoint, float> dictionary14 = originalPositionDampers;
angularXDrive = spineJoint.angularXDrive;
dictionary14[spineJoint] = ((JointDrive)(ref angularXDrive)).positionDamper;
Dictionary<ConfigurableJoint, float> dictionary15 = originalMaximumForces;
angularXDrive = spineJoint.angularXDrive;
dictionary15[spineJoint] = ((JointDrive)(ref angularXDrive)).maximumForce;
}
}
}
}
private void HipStabilizerCalculator(ConfigurableJoint joint, ref Quaternion startingRotation)
{
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: 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_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)joint == (Object)null) && !((Object)(object)((Joint)joint).connectedBody == (Object)null) && !((Object)(object)((Component)((Joint)joint).connectedBody).gameObject == (Object)null))
{
string name = ((Object)((Component)((Component)((Joint)joint).connectedBody).gameObject.transform.root).gameObject).name;
List<Transform> list = new List<Transform>();
Transform val = ((Component)joint).transform;
while (!((Object)val).name.ToLower().Contains("character"))
{
list.Add(val.parent);
val = val.parent;
}
name = ((Object)val).name;
float num = (float)((Component)val).GetComponent<PlayerHealth>().bloodAmount / 2f;
num = Mathf.Clamp(num, 0.0001f, 1f);
if (num <= 0.5f)
{
JointDrive val2 = default(JointDrive);
((JointDrive)(ref val2)).positionSpring = 10000f * hipStabilizerStrengthMultiplier;
((JointDrive)(ref val2)).positionDamper = 2700f * hipStabilizerDamperMultiplier;
((JointDrive)(ref val2)).maximumForce = 2500f * (num / 1.2f);
joint.angularXDrive = val2;
val2 = default(JointDrive);
((JointDrive)(ref val2)).positionSpring = 10000f * hipStabilizerStrengthMultiplier;
((JointDrive)(ref val2)).positionDamper = 2700f * hipStabilizerDamperMultiplier;
((JointDrive)(ref val2)).maximumForce = 2500f * (num / 1.2f);
joint.angularYZDrive = val2;
}
Vector3 currentTorque = ((Joint)joint).currentTorque;
float magnitude = ((Vector3)(ref currentTorque)).magnitude;
}
}
private void ChangeFloorPhysicsMaterial()
{
GameObject[] array = Object.FindObjectsOfType<GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (!(((Object)val).name.ToLower() == "arenaofblades"))
{
continue;
}
Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>();
foreach (Collider val2 in componentsInChildren)
{
if (((Object)val2).name.ToLower() == "arenaground.001")
{
((BaseUnityPlugin)this).Logger.LogError((object)(((Object)val2).name ?? ""));
val2.material = floorPhyMaterial;
val2.material.staticFriction = floorFriction / 100f;
val2.material.dynamicFriction = floorFriction / 100f;
if (floorFriction > 60f)
{
val2.material.frictionCombine = (PhysicMaterialCombine)3;
}
if (floorFriction < 60f)
{
val2.material.frictionCombine = (PhysicMaterialCombine)2;
}
}
}
}
}
private void ToggleMenu()
{
showMenu = !showMenu;
}
private void OnGUI()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
//IL_032f: Unknown result type (might be due to invalid IL or missing references)
//IL_0367: Unknown result type (might be due to invalid IL or missing references)
//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0419: Unknown result type (might be due to invalid IL or missing references)
//IL_0451: Unknown result type (might be due to invalid IL or missing references)
//IL_048e: Unknown result type (might be due to invalid IL or missing references)
//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
//IL_0503: Unknown result type (might be due to invalid IL or missing references)
//IL_053b: Unknown result type (might be due to invalid IL or missing references)
//IL_0578: Unknown result type (might be due to invalid IL or missing references)
//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0625: Unknown result type (might be due to invalid IL or missing references)
//IL_0662: Unknown result type (might be due to invalid IL or missing references)
if (showMenu)
{
GUI.Box(new Rect(10f, 10f, 420f, 620f), "ImprovedCharacterPhysics Menu");
useMod = GUI.Toggle(new Rect(20f, 40f, 230f, 20f), useMod, "Use Mod");
useCustomHipStabilizer = GUI.Toggle(new Rect(20f, 70f, 230f, 20f), useCustomHipStabilizer, "Use Custom Hip Stabilizer");
GUI.Label(new Rect(20f, 100f, 400f, 20f), "Hip Stabilizer Strength (Anti-Torque Exploit): " + Mathf.RoundToInt(hipStabilizerStrengthMultiplier));
hipStabilizerStrengthMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 120f, 400f, 20f), hipStabilizerStrengthMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 140f, 400f, 20f), "Hip Stabilizer Damper: " + Mathf.RoundToInt(hipStabilizerDamperMultiplier));
hipStabilizerDamperMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 160f, 400f, 20f), hipStabilizerDamperMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 180f, 400f, 20f), "Arm Strength: " + Mathf.RoundToInt(armStrenghtMultiplier));
armStrenghtMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 200f, 400f, 20f), armStrenghtMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 220f, 400f, 20f), "Leg Strength: " + Mathf.RoundToInt(legStrengthMultiplier));
legStrengthMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 240f, 400f, 20f), legStrengthMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 260f, 400f, 20f), "Spine Strength: " + Mathf.RoundToInt(spineStrenghtMultiplier));
spineStrenghtMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 280f, 400f, 20f), spineStrenghtMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 300f, 400f, 20f), "min Movement Speed to Drain Stamina (Degrees per second): " + Mathf.RoundToInt(minMovementSpeedToDrainStamina));
minMovementSpeedToDrainStamina = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 320f, 400f, 20f), minMovementSpeedToDrainStamina, 0f, 200f));
GUI.Label(new Rect(20f, 340f, 400f, 20f), "Arms Stamina Drain: " + Mathf.RoundToInt(armsStaminaDrainMultiplier));
armsStaminaDrainMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 360f, 400f, 20f), armsStaminaDrainMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 380f, 400f, 20f), "Arms Stamina Regen: " + Mathf.RoundToInt(armsStaminaRegenMultiplier));
armsStaminaRegenMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 400f, 400f, 20f), armsStaminaRegenMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 420f, 400f, 20f), "Legs Stamina Drain: " + Mathf.RoundToInt(legsStaminaDrainMultiplier));
legsStaminaDrainMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 440f, 400f, 20f), legsStaminaDrainMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 460f, 400f, 20f), "Legs Stamina Regen: " + Mathf.RoundToInt(legsStaminaRegenMultiplier));
legsStaminaRegenMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 480f, 400f, 20f), legsStaminaRegenMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 500f, 400f, 20f), "Cardiovascular/Shared Stamina Drain: " + Mathf.RoundToInt(cardioVascularStaminaDrainMultiplier));
cardioVascularStaminaDrainMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 520f, 400f, 20f), cardioVascularStaminaDrainMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 540f, 400f, 20f), "Cardiovascular/Shared Stamina Regen: " + Mathf.RoundToInt(cardioVascularStaminaRegenMultiplier));
cardioVascularStaminaRegenMultiplier = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 560f, 400f, 20f), cardioVascularStaminaRegenMultiplier, 0f, 200f));
GUI.Label(new Rect(20f, 580f, 400f, 20f), "Floor Friction: " + Mathf.RoundToInt(floorFriction));
floorFriction = Mathf.Round(GUI.HorizontalSlider(new Rect(20f, 600f, 400f, 20f), floorFriction, 1f, 100f));
}
}
}
[HarmonyPatch(typeof(JointStrength), "DealMuscleDamage")]
public class JointStrengthPatch
{
private static void Postfix(JointStrength __instance)
{
ImprovedCharacterPhysics component = Chainloader.ManagerObject.GetComponent<ImprovedCharacterPhysics>();
if ((Object)(object)component != (Object)null)
{
component.UpdateJointValues();
}
else
{
Debug.LogError((object)"ImprovedCharacterPhysics instance not found!");
}
}
}