Decompiled source of Spinny v1.0.0

Mods/Spinny.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppSLZ.Marrow;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Spinny;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(SpinnyMod), "Spinny", "1.0.0", "Lakatrazz", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyDescription("Turns you with what you stand on or grab.")]
[assembly: AssemblyTitle("Spinny")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Spinny;

public class SpinnyMod : MelonMod
{
	public const string Name = "Spinny";

	public const string Author = "Lakatrazz";

	public const string Description = "Turns you with what you stand on or grab.";

	public const string Version = "1.0.0";

	private static Grip[] _playerGrips = Array.Empty<Grip>();

	private static bool _preferencesSetup = false;

	private static float _targetSpin = 0f;

	private static float _currentSpin = 0f;

	public static MelonPreferences_Category MelonPrefCategory { get; private set; }

	public static MelonPreferences_Entry<bool> MelonPrefEnabled { get; private set; }

	public static MelonPreferences_Entry<bool> MelonPrefGroundRotation { get; private set; }

	public static MelonPreferences_Entry<bool> MelonPrefGrabRotation { get; private set; }

	public static MelonPreferences_Entry<bool> MelonPrefBeingGrabbedRotation { get; private set; }

	public static bool Enabled { get; private set; }

	public static bool GroundRotation { get; private set; }

	public static bool GrabRotation { get; private set; }

	public static bool BeingGrabbedRotation { get; private set; }

	public static Page MainPage { get; private set; }

	public static BoolElement EnabledElement { get; private set; }

	public static BoolElement GroundRotationElement { get; private set; }

	public static BoolElement GrabRotationElement { get; private set; }

	public static BoolElement BeingGrabbedRotationElement { get; private set; }

	public override void OnInitializeMelon()
	{
		Hooking.OnLevelLoaded += OnLevelLoaded;
		SetupMelonPrefs();
		SetupBoneMenu();
	}

	private void OnLevelLoaded(LevelInfo info)
	{
		PhysicsRig physicsRig = Player.PhysicsRig;
		PhysTorso torso = physicsRig.torso;
		PhysHand physHand = physicsRig.leftHand.physHand;
		PhysHand physHand2 = physicsRig.rightHand.physHand;
		_playerGrips = (Grip[])(object)new Grip[9]
		{
			torso.gChest,
			torso.gHead,
			(Grip)torso.gNeck,
			torso.gPelvis,
			torso.gSpine,
			(Grip)physHand.gShoulder,
			(Grip)physHand.gElbow,
			(Grip)physHand2.gShoulder,
			(Grip)physHand2.gElbow
		};
	}

	public static void SetupMelonPrefs()
	{
		MelonPrefCategory = MelonPreferences.CreateCategory("Spinny");
		MelonPrefEnabled = MelonPrefCategory.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		MelonPrefGroundRotation = MelonPrefCategory.CreateEntry<bool>("Ground Rotation", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		MelonPrefGrabRotation = MelonPrefCategory.CreateEntry<bool>("Grab Rotation", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		MelonPrefBeingGrabbedRotation = MelonPrefCategory.CreateEntry<bool>("Being Grabbed Rotation", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		Enabled = MelonPrefEnabled.Value;
		GroundRotation = MelonPrefGroundRotation.Value;
		GrabRotation = MelonPrefGrabRotation.Value;
		BeingGrabbedRotation = MelonPrefBeingGrabbedRotation.Value;
		_preferencesSetup = true;
	}

	public static void SetupBoneMenu()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_0079: 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)
		MainPage = Page.Root.CreatePage("Spinny", Color.green, 0, true);
		EnabledElement = MainPage.CreateBool("Enabled", Color.yellow, Enabled, (Action<bool>)OnSetEnabled);
		GroundRotationElement = MainPage.CreateBool("Ground Rotation", Color.yellow, GroundRotation, (Action<bool>)OnSetGroundRotation);
		GrabRotationElement = MainPage.CreateBool("Grab Rotation", Color.yellow, GrabRotation, (Action<bool>)OnSetGrabRotation);
		BeingGrabbedRotationElement = MainPage.CreateBool("Being Grabbed Rotation", Color.yellow, BeingGrabbedRotation, (Action<bool>)OnSetBeingGrabbedRotation);
	}

	private static void OnSetEnabled(bool value)
	{
		Enabled = value;
		MelonPrefEnabled.Value = value;
		MelonPrefCategory.SaveToFile(false);
	}

	private static void OnSetGroundRotation(bool value)
	{
		GroundRotation = value;
		MelonPrefGroundRotation.Value = value;
		MelonPrefCategory.SaveToFile(false);
	}

	private static void OnSetGrabRotation(bool value)
	{
		GrabRotation = value;
		MelonPrefGrabRotation.Value = value;
		MelonPrefCategory.SaveToFile(false);
	}

	private static void OnSetBeingGrabbedRotation(bool value)
	{
		BeingGrabbedRotation = value;
		MelonPrefBeingGrabbedRotation.Value = value;
		MelonPrefCategory.SaveToFile(false);
	}

	public override void OnPreferencesLoaded()
	{
		if (_preferencesSetup)
		{
			Enabled = MelonPrefEnabled.Value;
			GroundRotation = MelonPrefGroundRotation.Value;
			GrabRotation = MelonPrefGrabRotation.Value;
			EnabledElement.Value = Enabled;
			GroundRotationElement.Value = GroundRotation;
			GrabRotationElement.Value = GrabRotation;
		}
	}

	public override void OnUpdate()
	{
		if (!Enabled)
		{
			return;
		}
		RigManager rigManager = Player.RigManager;
		if ((Object)(object)rigManager == (Object)null)
		{
			return;
		}
		PhysicsRig physicsRig = rigManager.physicsRig;
		if (!physicsRig.ballLocoEnabled)
		{
			_targetSpin = 0f;
			_currentSpin = 0f;
			return;
		}
		float decay = 12f;
		_targetSpin = 0f;
		if (CheckGrounded(physicsRig))
		{
			if (GroundRotation)
			{
				SolveGroundRotation(physicsRig);
			}
		}
		else if (BeingGrabbedRotation && CheckBeingGrabbed())
		{
			SolveBeingGrabbedRotation();
		}
		else if (GrabRotation && CheckGrabbing(physicsRig))
		{
			SolveGrabRotation(physicsRig);
		}
		else
		{
			decay = 2f;
		}
		_currentSpin = Mathf.Lerp(_currentSpin, _targetSpin, Smoothing.CalculateDecay(decay, Time.deltaTime));
		rigManager.remapHeptaRig.SetTwist(_currentSpin * 57.29578f);
	}

	private static bool CheckGrounded(PhysicsRig physicsRig)
	{
		return physicsRig.physG.isGrounded;
	}

	private static bool CheckGrabbing(PhysicsRig physicsRig)
	{
		if (!Object.op_Implicit((Object)(object)physicsRig.leftHand.m_CurrentAttachedGO))
		{
			return Object.op_Implicit((Object)(object)physicsRig.rightHand.m_CurrentAttachedGO);
		}
		return true;
	}

	private static bool CheckBeingGrabbed()
	{
		Grip[] playerGrips = _playerGrips;
		for (int i = 0; i < playerGrips.Length; i++)
		{
			if (playerGrips[i].HasAttachedHands())
			{
				return true;
			}
		}
		return false;
	}

	private static void SolveGroundRotation(PhysicsRig physicsRig)
	{
		float num = physicsRig.groundAngVelocity * Time.deltaTime;
		Collider groundedCollider = physicsRig.physG._groundedCollider;
		if ((Object)(object)groundedCollider != (Object)null && Object.op_Implicit((Object)(object)groundedCollider.attachedRigidbody))
		{
			num *= CalculateMassSupport(groundedCollider.attachedRigidbody);
		}
		_targetSpin = num;
	}

	private static void SolveBeingGrabbedRotation()
	{
		float num = 0f;
		int num2 = 0;
		Grip[] playerGrips = _playerGrips;
		foreach (Grip val in playerGrips)
		{
			if (val.HasAttachedHands())
			{
				num += GetBeingGrabbedAngularVelocity(val);
				num2++;
			}
		}
		if (num2 > 0)
		{
			num /= (float)num2;
			_targetSpin = num * Time.deltaTime;
		}
	}

	private static float GetBeingGrabbedAngularVelocity(Grip grip)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		float massArm = Player.RigManager.avatar.massArm;
		float num = 0f;
		int num2 = 0;
		Enumerator<Hand> enumerator = grip.attachedHands.GetEnumerator();
		while (enumerator.MoveNext())
		{
			Hand current = enumerator.Current;
			PhysHand physHand = current.physHand;
			float num3 = Mathf.Clamp01((physHand._upperArmRb.mass + physHand._lowerArmRb.mass + physHand._handRb.mass) / (massArm * 2f));
			num += current.physHand._upperArmRb.angularVelocity.y * num3;
			num2++;
		}
		return num / (float)num2;
	}

	private static void SolveGrabRotation(PhysicsRig physicsRig)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_00b2: 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)
		(float, float, Rigidbody) grabContribution = GetGrabContribution(physicsRig.leftHand);
		(float, float, Rigidbody) grabContribution2 = GetGrabContribution(physicsRig.rightHand);
		float num = grabContribution.Item1 + grabContribution2.Item1;
		if (!(num <= 0f))
		{
			float num2 = grabContribution.Item1 / num;
			float num3 = grabContribution2.Item1 / num;
			float num4 = grabContribution.Item2 * num2;
			float num5 = grabContribution2.Item2 * num3;
			_targetSpin = (num4 + num5) * Time.deltaTime;
			if (Object.op_Implicit((Object)(object)grabContribution.Item3))
			{
				grabContribution.Item3.AddTorque(Vector3.up * (0f - num4) * 0.2f, (ForceMode)2);
			}
			if (Object.op_Implicit((Object)(object)grabContribution2.Item3))
			{
				grabContribution2.Item3.AddTorque(Vector3.up * (0f - num5) * 0.2f, (ForceMode)2);
			}
		}
	}

	private static (float supported, float angularVelocity, Rigidbody rigidbody) GetGrabContribution(Hand hand)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hand.m_CurrentAttachedGO == (Object)null)
		{
			return (0f, 0f, null);
		}
		Grip val = Grip.Cache.Get(hand.m_CurrentAttachedGO);
		if ((Object)(object)val == (Object)null)
		{
			return (0f, 0f, null);
		}
		IGrippable host = ((HandReciever)val).Host;
		if (host == null || !host.HasRigidbody)
		{
			return (0f, 0f, null);
		}
		Rigidbody rb = host.Rb;
		float y = rb.angularVelocity.y;
		float num = CalculateMassSupport(rb);
		float item = Mathf.Abs(hand.physHand.handSupported) * num;
		y *= num;
		return (item, y, rb);
	}

	private static float CalculateMassSupport(Rigidbody rigidbody)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		float massPelvis = Player.RigManager.avatar.massPelvis;
		float y = rigidbody.angularVelocity.y;
		float num = Mathf.Pow(rigidbody.mass / massPelvis, 4f);
		float num2 = Mathf.Abs(y) / 10f + 1f;
		num2 *= num2;
		return Mathf.Clamp01(num * num2);
	}
}
public static class Smoothing
{
	public static float CalculateDecay(float decay, float deltaTime)
	{
		return 1f - Mathf.Exp((0f - decay) * deltaTime);
	}
}