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 _physicsPref; private static MelonPreferences_Entry _collisionPref; private static MelonPreferences_Entry _bodyPref; private static MelonPreferences_Entry _fingerPref; private static MelonPreferences_Entry _qualityPref; private static bool _defaultsCaptured; private static int _defaultIterations; private static int _defaultVelocityIterations; private static float _defaultMaxAngularSpeed; private static readonly Dictionary Tracked = new Dictionary(); private static readonly HashSet HeldNow = new HashSet(); private static readonly HashSet HeldPrev = new HashSet(); private static readonly HashSet FingerOverrideActive = new HashSet(); 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("BetterPhysics", true, "Better physics enabled", (string)null, false, false, (ValueValidator)null, (string)null); _collisionPref = _prefs.CreateEntry("BetterCollision", true, "Better collision enabled", (string)null, false, false, (ValueValidator)null, (string)null); _bodyPref = _prefs.CreateEntry("BodyCollision", false, "Body collision enabled", (string)null, false, false, (ValueValidator)null, (string)null); _fingerPref = _prefs.CreateEntry("FingerFix", true, "Finger anti-clip enabled", (string)null, false, false, (ValueValidator)null, (string)null); _qualityPref = _prefs.CreateEntry("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)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)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)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)delegate(bool value) { FingerFixEnabled = value; _fingerPref.Value = value; MelonPreferences.Save(); }); obj.CreateEnum("Quality", Color.yellow, (Enum)Quality, (Action)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 val = Object.FindObjectsOfType(); 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() != (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() != (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 list = new List(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 list = new List(); foreach (KeyValuePair 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 componentsInChildren = ((Component)physicsRig).GetComponentsInChildren(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(); 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 val2 = Physics.RaycastAll(position - val * 0.005f, val, num); float num2 = float.MaxValue; for (int i = 0; i < ((Il2CppArrayBase)(object)val2).Length; i++) { RaycastHit val3 = ((Il2CppArrayBase)(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)(object)val2)[i]; if (((RaycastHit)(ref val3)).distance < num2) { val3 = ((Il2CppArrayBase)(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; } } } }