Decompiled source of Better Physics v1.2.0

Mods/BetterPhysics.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BetterPhysics;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Better Physics", "1.2.0", "imebruhh", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BetterPhysics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterPhysics")]
[assembly: AssemblyTitle("BetterPhysics")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetterPhysics
{
	public enum PhysicsQuality
	{
		High,
		Ultra,
		Insane
	}
	public class Core : MelonMod
	{
		private struct Entry
		{
			public Rigidbody rb;

			public int origSolver;

			public int origVelocity;

			public float origMaxAngular;

			public CollisionDetectionMode origMode;

			public bool physicsApplied;

			public bool modeApplied;
		}

		public static volatile bool PhysicsEnabled;

		public static volatile bool CollisionEnabled;

		public static volatile bool BodyCollisionEnabled;

		public static volatile bool FingerFixEnabled;

		public static PhysicsQuality Quality = PhysicsQuality.Ultra;

		private const float MaxAngularSpeed = 40f;

		private const float SweepInterval = 2f;

		private static float _nextSweep;

		private static MelonPreferences_Category _prefs;

		private static MelonPreferences_Entry<bool> _physicsPref;

		private static MelonPreferences_Entry<bool> _collisionPref;

		private static MelonPreferences_Entry<bool> _bodyPref;

		private static MelonPreferences_Entry<bool> _fingerPref;

		private static MelonPreferences_Entry<int> _qualityPref;

		private static bool _defaultsCaptured;

		private static int _defaultIterations;

		private static int _defaultVelocityIterations;

		private static float _defaultMaxAngularSpeed;

		private static readonly Dictionary<int, Entry> Tracked = new Dictionary<int, Entry>();

		private static readonly HashSet<int> HeldNow = new HashSet<int>();

		private static readonly HashSet<int> HeldPrev = new HashSet<int>();

		private static readonly HashSet<int> FingerOverrideActive = new HashSet<int>();

		private static int SolverIterations => Quality switch
		{
			PhysicsQuality.High => 12, 
			PhysicsQuality.Ultra => 16, 
			_ => 24, 
		};

		private static int SolverVelocityIterations => Quality switch
		{
			PhysicsQuality.High => 4, 
			PhysicsQuality.Ultra => 6, 
			_ => 10, 
		};

		public override void OnInitializeMelon()
		{
			//IL_0130: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			_prefs = MelonPreferences.CreateCategory("BetterPhysics");
			_physicsPref = _prefs.CreateEntry<bool>("BetterPhysics", true, "Better physics enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			_collisionPref = _prefs.CreateEntry<bool>("BetterCollision", true, "Better collision enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			_bodyPref = _prefs.CreateEntry<bool>("BodyCollision", false, "Body collision enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			_fingerPref = _prefs.CreateEntry<bool>("FingerFix", true, "Finger anti-clip enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			_qualityPref = _prefs.CreateEntry<int>("Quality", 1, "Physics quality level", (string)null, false, false, (ValueValidator)null, (string)null);
			PhysicsEnabled = _physicsPref.Value;
			CollisionEnabled = _collisionPref.Value;
			BodyCollisionEnabled = _bodyPref.Value;
			FingerFixEnabled = _fingerPref.Value;
			if (_qualityPref.Value >= 0 && _qualityPref.Value <= 2)
			{
				Quality = (PhysicsQuality)_qualityPref.Value;
			}
			Page obj = Page.Root.CreatePage("Better Physics", new Color(0.4f, 0.8f, 1f), 0, true);
			obj.CreateBool("Better Physics", Color.green, PhysicsEnabled, (Action<bool>)delegate(bool value)
			{
				PhysicsEnabled = value;
				_physicsPref.Value = value;
				MelonPreferences.Save();
				ApplyGlobals();
				if (value)
				{
					_nextSweep = 0f;
				}
				else
				{
					RestoreAll(restorePhysics: true, restoreModes: false);
				}
			});
			obj.CreateBool("Better Collision", Color.cyan, CollisionEnabled, (Action<bool>)delegate(bool value)
			{
				CollisionEnabled = value;
				_collisionPref.Value = value;
				MelonPreferences.Save();
				if (value)
				{
					_nextSweep = 0f;
				}
				else
				{
					RestoreAll(restorePhysics: false, restoreModes: true);
				}
			});
			obj.CreateBool("Better Body Collision", Color.magenta, BodyCollisionEnabled, (Action<bool>)delegate(bool value)
			{
				BodyCollisionEnabled = value;
				_bodyPref.Value = value;
				MelonPreferences.Save();
				if (value)
				{
					_nextSweep = 0f;
				}
				else
				{
					RestoreAll(restorePhysics: false, restoreModes: true);
				}
			});
			obj.CreateBool("Finger Fix", Color.white, FingerFixEnabled, (Action<bool>)delegate(bool value)
			{
				FingerFixEnabled = value;
				_fingerPref.Value = value;
				MelonPreferences.Save();
			});
			obj.CreateEnum("Quality", Color.yellow, (Enum)Quality, (Action<Enum>)delegate(Enum value)
			{
				if (value is PhysicsQuality physicsQuality)
				{
					Quality = physicsQuality;
					_qualityPref.Value = (int)physicsQuality;
					MelonPreferences.Save();
					ApplyGlobals();
					if (PhysicsEnabled)
					{
						_nextSweep = 0f;
					}
				}
			});
			Hooking.OnLevelLoaded += OnLevelLoaded;
			Hooking.OnLevelUnloaded += OnLevelUnloaded;
			((MelonBase)this).LoggerInstance.Msg($"Better Physics v1.2 loaded. Physics {(PhysicsEnabled ? "ON" : "OFF")}, collision {(CollisionEnabled ? "ON" : "OFF")}, body {(BodyCollisionEnabled ? "ON" : "OFF")}, fingers {(FingerFixEnabled ? "ON" : "OFF")}, quality {Quality}.");
		}

		private static void OnLevelLoaded(LevelInfo info)
		{
			Tracked.Clear();
			HeldPrev.Clear();
			HeldNow.Clear();
			FingerOverrideActive.Clear();
			ApplyGlobals();
			_nextSweep = Time.unscaledTime + 1f;
		}

		private static void OnLevelUnloaded()
		{
			Tracked.Clear();
			HeldPrev.Clear();
			HeldNow.Clear();
			FingerOverrideActive.Clear();
		}

		public override void OnUpdate()
		{
			if (CollisionEnabled)
			{
				UpdateHeldObjects();
			}
			UpdateFingerFix();
			if ((PhysicsEnabled || CollisionEnabled) && Time.unscaledTime >= _nextSweep)
			{
				_nextSweep = Time.unscaledTime + 2f;
				Sweep();
			}
		}

		private static void ApplyGlobals()
		{
			try
			{
				if (!_defaultsCaptured)
				{
					_defaultIterations = Physics.defaultSolverIterations;
					_defaultVelocityIterations = Physics.defaultSolverVelocityIterations;
					_defaultMaxAngularSpeed = Physics.defaultMaxAngularSpeed;
					_defaultsCaptured = true;
				}
				if (PhysicsEnabled)
				{
					Physics.defaultSolverIterations = SolverIterations;
					Physics.defaultSolverVelocityIterations = SolverVelocityIterations;
					Physics.defaultMaxAngularSpeed = 40f;
				}
				else
				{
					Physics.defaultSolverIterations = _defaultIterations;
					Physics.defaultSolverVelocityIterations = _defaultVelocityIterations;
					Physics.defaultMaxAngularSpeed = _defaultMaxAngularSpeed;
				}
			}
			catch
			{
			}
		}

		private static void Sweep()
		{
			try
			{
				Il2CppArrayBase<Rigidbody> val = Object.FindObjectsOfType<Rigidbody>();
				for (int i = 0; i < val.Length; i++)
				{
					Rigidbody val2 = val[i];
					if (!((Object)(object)val2 == (Object)null))
					{
						ApplyToBody(val2, HeldPrev.Contains(((Object)val2).GetInstanceID()));
					}
				}
				if (Tracked.Count > 1024)
				{
					PruneDead();
				}
			}
			catch
			{
			}
			ApplyToHands();
			if (BodyCollisionEnabled)
			{
				ApplyToPlayerBody();
			}
		}

		private static void ApplyToBody(Rigidbody rb, bool held)
		{
			//IL_0063: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((Component)rb).GetComponentInParent<RigManager>() != (Object)null)
				{
					return;
				}
				int instanceID = ((Object)rb).GetInstanceID();
				if (!Tracked.TryGetValue(instanceID, out var value))
				{
					value = new Entry
					{
						rb = rb,
						origSolver = rb.solverIterations,
						origVelocity = rb.solverVelocityIterations,
						origMaxAngular = rb.maxAngularVelocity,
						origMode = rb.collisionDetectionMode
					};
				}
				if (PhysicsEnabled)
				{
					rb.solverIterations = SolverIterations;
					rb.solverVelocityIterations = SolverVelocityIterations;
					if (rb.maxAngularVelocity < 40f)
					{
						rb.maxAngularVelocity = 40f;
					}
					value.physicsApplied = true;
					if (!held && !rb.isKinematic && !rb.useGravity && (Object)(object)((Component)rb).GetComponent<InteractableHost>() != (Object)null)
					{
						rb.useGravity = true;
					}
				}
				if (CollisionEnabled && !rb.isKinematic)
				{
					CollisionDetectionMode val = (held ? ((CollisionDetectionMode)2) : (((int)value.origMode != 0) ? value.origMode : ((CollisionDetectionMode)3)));
					if (rb.collisionDetectionMode != val)
					{
						rb.collisionDetectionMode = val;
					}
					value.modeApplied = true;
				}
				Tracked[instanceID] = value;
			}
			catch
			{
			}
		}

		private static void RestoreAll(bool restorePhysics, bool restoreModes)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			List<int> list = new List<int>(Tracked.Keys);
			for (int i = 0; i < list.Count; i++)
			{
				Entry value = Tracked[list[i]];
				try
				{
					if ((Object)(object)value.rb == (Object)null)
					{
						Tracked.Remove(list[i]);
						continue;
					}
					if (restorePhysics && value.physicsApplied)
					{
						value.rb.solverIterations = value.origSolver;
						value.rb.solverVelocityIterations = value.origVelocity;
						value.rb.maxAngularVelocity = value.origMaxAngular;
						value.physicsApplied = false;
					}
					if (restoreModes && value.modeApplied)
					{
						if (!value.rb.isKinematic)
						{
							value.rb.collisionDetectionMode = value.origMode;
						}
						value.modeApplied = false;
					}
					if (!value.physicsApplied && !value.modeApplied)
					{
						Tracked.Remove(list[i]);
					}
					else
					{
						Tracked[list[i]] = value;
					}
				}
				catch
				{
					Tracked.Remove(list[i]);
				}
			}
		}

		private static void PruneDead()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, Entry> item in Tracked)
			{
				try
				{
					if ((Object)(object)item.Value.rb == (Object)null)
					{
						list.Add(item.Key);
					}
				}
				catch
				{
					list.Add(item.Key);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				Tracked.Remove(list[i]);
			}
		}

		private static void ApplyToHands()
		{
			ApplyToRigBody(((Object)(object)Player.LeftHand != (Object)null) ? Player.LeftHand.rb : null, capSpin: false);
			ApplyToRigBody(((Object)(object)Player.RightHand != (Object)null) ? Player.RightHand.rb : null, capSpin: false);
		}

		private static void ApplyToPlayerBody()
		{
			try
			{
				PhysicsRig physicsRig = Player.PhysicsRig;
				if (!((Object)(object)physicsRig == (Object)null))
				{
					Il2CppArrayBase<Rigidbody> componentsInChildren = ((Component)physicsRig).GetComponentsInChildren<Rigidbody>(false);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						ApplyToRigBody(componentsInChildren[i], capSpin: false);
					}
				}
			}
			catch
			{
			}
		}

		private static void ApplyToRigBody(Rigidbody rb, bool capSpin)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			try
			{
				if ((Object)(object)rb == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)rb).GetInstanceID();
				if (!Tracked.TryGetValue(instanceID, out var value))
				{
					value = new Entry
					{
						rb = rb,
						origSolver = rb.solverIterations,
						origVelocity = rb.solverVelocityIterations,
						origMaxAngular = rb.maxAngularVelocity,
						origMode = rb.collisionDetectionMode
					};
				}
				if (PhysicsEnabled)
				{
					rb.solverIterations = SolverIterations;
					rb.solverVelocityIterations = SolverVelocityIterations;
					value.physicsApplied = true;
				}
				if (CollisionEnabled && !rb.isKinematic)
				{
					if ((int)rb.collisionDetectionMode != 2)
					{
						rb.collisionDetectionMode = (CollisionDetectionMode)2;
					}
					value.modeApplied = true;
				}
				Tracked[instanceID] = value;
			}
			catch
			{
			}
		}

		private static void UpdateHeldObjects()
		{
			HeldNow.Clear();
			CollectHeld(Player.LeftHand);
			CollectHeld(Player.RightHand);
			foreach (int item in HeldPrev)
			{
				if (HeldNow.Contains(item) || !Tracked.TryGetValue(item, out var value))
				{
					continue;
				}
				try
				{
					if ((Object)(object)value.rb != (Object)null)
					{
						ApplyToBody(value.rb, held: false);
					}
				}
				catch
				{
				}
			}
			HeldPrev.Clear();
			foreach (int item2 in HeldNow)
			{
				HeldPrev.Add(item2);
			}
		}

		private static void CollectHeld(Hand hand)
		{
			try
			{
				if ((Object)(object)hand == (Object)null)
				{
					return;
				}
				ConfigurableJoint joint = hand.joint;
				if ((Object)(object)joint != (Object)null)
				{
					MarkHeld(((Joint)joint).connectedBody);
				}
				GameObject currentAttachedGO = hand.m_CurrentAttachedGO;
				if ((Object)(object)currentAttachedGO != (Object)null)
				{
					InteractableHost componentInParent = currentAttachedGO.GetComponentInParent<InteractableHost>();
					if ((Object)(object)componentInParent != (Object)null && componentInParent.HasRigidbody)
					{
						MarkHeld(componentInParent.Rb);
					}
				}
			}
			catch
			{
			}
		}

		private static void MarkHeld(Rigidbody rb)
		{
			try
			{
				if ((Object)(object)rb == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)rb).GetInstanceID();
				if (!HeldNow.Contains(instanceID))
				{
					HeldNow.Add(instanceID);
					if (!HeldPrev.Contains(instanceID))
					{
						ApplyToBody(rb, held: true);
					}
				}
			}
			catch
			{
			}
		}

		private static void UpdateFingerFix()
		{
			ApplyFingerFix(Player.LeftHand);
			ApplyFingerFix(Player.RightHand);
		}

		private static void ApplyFingerFix(Hand hand)
		{
			try
			{
				if ((Object)(object)hand == (Object)null)
				{
					return;
				}
				HandPoseAnimator animator = hand.Animator;
				if ((Object)(object)animator == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)hand).GetInstanceID();
				if (!FingerFixEnabled || hand.HasAttachedObject())
				{
					if (FingerOverrideActive.Remove(instanceID))
					{
						animator.CurlOverride(-1f, -1f, -1f, -1f, -1f);
					}
					return;
				}
				BaseController controller = hand.Controller;
				float inputCurl = 0f;
				float inputCurl2 = 0f;
				float inputCurl3 = 0f;
				float inputCurl4 = 0f;
				if ((Object)(object)controller != (Object)null)
				{
					inputCurl = controller._processedIndex;
					inputCurl2 = controller._processedMiddle;
					inputCurl3 = controller._processedRing;
					inputCurl4 = controller._processedPinky;
				}
				Transform myRig = null;
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager != (Object)null)
				{
					myRig = ((Component)rigManager).transform;
				}
				float num = FingerCurl(animator.index1, animator.index2, animator.index3, inputCurl, myRig);
				float num2 = FingerCurl(animator.middle1, animator.middle2, animator.middle3, inputCurl2, myRig);
				float num3 = FingerCurl(animator.ring1, animator.ring2, animator.ring3, inputCurl3, myRig);
				float num4 = FingerCurl(animator.pinky1, animator.pinky2, animator.pinky3, inputCurl4, myRig);
				if (num >= 0f || num2 >= 0f || num3 >= 0f || num4 >= 0f)
				{
					animator.CurlOverride(-1f, num, num2, num3, num4);
					FingerOverrideActive.Add(instanceID);
				}
				else if (FingerOverrideActive.Remove(instanceID))
				{
					animator.CurlOverride(-1f, -1f, -1f, -1f, -1f);
				}
			}
			catch
			{
			}
		}

		private static float FingerCurl(Transform proximal, Transform mid, Transform tip, float inputCurl, Transform myRig)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)proximal == (Object)null || (Object)(object)mid == (Object)null || (Object)(object)tip == (Object)null)
				{
					return -1f;
				}
				Vector3 position = proximal.position;
				Vector3 val = mid.position - position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (magnitude < 1E-05f)
				{
					return -1f;
				}
				val /= magnitude;
				float num = magnitude + Vector3.Distance(tip.position, mid.position) * 1.8f;
				Il2CppStructArray<RaycastHit> val2 = Physics.RaycastAll(position - val * 0.005f, val, num);
				float num2 = float.MaxValue;
				for (int i = 0; i < ((Il2CppArrayBase<RaycastHit>)(object)val2).Length; i++)
				{
					RaycastHit val3 = ((Il2CppArrayBase<RaycastHit>)(object)val2)[i];
					Collider collider = ((RaycastHit)(ref val3)).collider;
					if (!((Object)(object)collider == (Object)null) && !collider.isTrigger && (!((Object)(object)myRig != (Object)null) || !((Component)collider).transform.IsChildOf(myRig)))
					{
						val3 = ((Il2CppArrayBase<RaycastHit>)(object)val2)[i];
						if (((RaycastHit)(ref val3)).distance < num2)
						{
							val3 = ((Il2CppArrayBase<RaycastHit>)(object)val2)[i];
							num2 = ((RaycastHit)(ref val3)).distance;
						}
					}
				}
				if (num2 >= num)
				{
					return -1f;
				}
				float num3 = Mathf.Clamp01(1f - num2 / num) * 0.85f;
				if (num3 <= inputCurl)
				{
					return -1f;
				}
				return Mathf.Clamp01(num3);
			}
			catch
			{
				return -1f;
			}
		}
	}
}