Decompiled source of WoogsRagdollMod v1.0.1

Mods/StandaloneRagdoll.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using Microsoft.CodeAnalysis;
using StandaloneRagdoll;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(RagdollMod), "Standalone Ragdoll", "1.1.0", "DOOBER", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("StandaloneRagdoll")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("StandaloneRagdoll")]
[assembly: AssemblyTitle("StandaloneRagdoll")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 StandaloneRagdoll
{
	public enum RagdollMode
	{
		LIMP,
		ARM_CONTROL
	}
	public class RagdollMod : MelonMod
	{
		public override void OnInitializeMelon()
		{
			RagdollController.Initialize();
			((MelonBase)this).LoggerInstance.Msg("Standalone Ragdoll mod loaded");
		}

		public override void OnLateInitializeMelon()
		{
			BuildMenu();
		}

		public override void OnUpdate()
		{
			RagdollController.Update();
		}

		private void BuildMenu()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Ragdoll", Color.red, 0, true);
			obj.CreateBool("Enabled", Color.white, RagdollController.Enabled, (Action<bool>)delegate(bool value)
			{
				RagdollController.Enabled = value;
			});
			obj.CreateBool("Grab Ragdoll", Color.yellow, RagdollController.GrabEnabled, (Action<bool>)delegate(bool value)
			{
				RagdollController.GrabEnabled = value;
			});
			obj.CreateEnum("Mode", Color.cyan, (Enum)RagdollController.Mode, (Action<Enum>)delegate(Enum value)
			{
				RagdollController.Mode = (RagdollMode)(object)value;
			});
			obj.CreateBool("Tantrum Mode", Color.red, RagdollController.TantrumMode, (Action<bool>)delegate(bool value)
			{
				RagdollController.TantrumMode = value;
			});
		}
	}
	public static class RagdollController
	{
		private static bool _enabled = false;

		private static RagdollMode _mode = RagdollMode.LIMP;

		private static bool _tantrumMode = false;

		private static bool _grabEnabled = true;

		private static bool _sceneLoaded = false;

		private static float _nextRagdollTime = 0f;

		private static float _ragdollCooldownUntil = 0f;

		private const float COOLDOWN = 2f;

		private static Grip[] _cachedRigGrips = null;

		private static float _lastGripCacheTime = 0f;

		private const float GRIP_CACHE_INTERVAL = 2f;

		public static bool Enabled
		{
			get
			{
				return _enabled;
			}
			set
			{
				_enabled = value;
				MelonLogger.Msg("Ragdoll Controller " + (value ? "ENABLED" : "DISABLED"));
			}
		}

		public static bool GrabEnabled
		{
			get
			{
				return _grabEnabled;
			}
			set
			{
				_grabEnabled = value;
			}
		}

		public static RagdollMode Mode
		{
			get
			{
				return _mode;
			}
			set
			{
				_mode = value;
				MelonLogger.Msg($"Ragdoll Mode: {value}");
			}
		}

		public static bool TantrumMode
		{
			get
			{
				return _tantrumMode;
			}
			set
			{
				_tantrumMode = value;
				MelonLogger.Msg("Tantrum Mode: " + (value ? "ON (basic ragdoll)" : "OFF (LIMP/ARM_CONTROL)"));
			}
		}

		public static void Initialize()
		{
			Hooking.OnLevelLoaded += delegate
			{
				OnSceneLoaded();
			};
			Hooking.OnPlayerDeath += OnPlayerDeathHook;
			Hooking.OnPlayerResurrected += OnPlayerResurrectedHook;
			MelonLogger.Msg("RagdollController initialized");
		}

		private static void OnSceneLoaded()
		{
			_sceneLoaded = true;
			_cachedRigGrips = null;
			_lastGripCacheTime = 0f;
			_nextRagdollTime = 0f;
		}

		public static void Update()
		{
			if (!_enabled || !_sceneLoaded || Time.time < _ragdollCooldownUntil)
			{
				return;
			}
			try
			{
				PhysicsRig physicsRig = Player.PhysicsRig;
				if (!((Object)(object)physicsRig == (Object)null))
				{
					RigManager rigManager = Player.RigManager;
					if (!((Object)(object)rigManager == (Object)null) && !physicsRig.torso.shutdown && physicsRig.ballLocoEnabled && !(Time.time < _nextRagdollTime) && _grabEnabled)
					{
						CheckGrabRagdoll(rigManager, physicsRig);
					}
				}
			}
			catch
			{
			}
		}

		private static void CheckGrabRagdoll(RigManager rigManager, PhysicsRig physRig)
		{
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PhysTorso torso = physRig.torso;
				if ((Object)(object)torso == (Object)null)
				{
					return;
				}
				float rigMass = GetRigMass(rigManager);
				RigManager externalGrabber = GetExternalGrabber(torso.gHead, rigManager);
				RigManager externalGrabber2 = GetExternalGrabber((Grip)(object)torso.gNeck, rigManager);
				if ((Object)(object)externalGrabber != (Object)null && GetRigMass(externalGrabber) > rigMass * 0.9f)
				{
					TriggerRagdoll(rigManager, "Head Grab", dropItems: false);
					return;
				}
				if ((Object)(object)externalGrabber2 != (Object)null && GetRigMass(externalGrabber2) > rigMass * 0.9f)
				{
					TriggerRagdoll(rigManager, "Neck Grab", dropItems: false);
					return;
				}
				RefreshGripCache(rigManager);
				RigManager val = null;
				RigManager val2 = null;
				Grip[] cachedRigGrips;
				if (_cachedRigGrips != null)
				{
					Transform val3 = (((Object)(object)physRig.leftHand != (Object)null) ? ((Component)physRig.leftHand).transform : null);
					Transform val4 = (((Object)(object)physRig.rightHand != (Object)null) ? ((Component)physRig.rightHand).transform : null);
					Transform transform = ((Component)rigManager).transform;
					GameObject val5 = null;
					GameObject val6 = null;
					try
					{
						Hand leftHand = physRig.leftHand;
						if ((Object)(object)((leftHand != null) ? leftHand.m_CurrentAttachedGO : null) != (Object)null)
						{
							val5 = ((Component)physRig.leftHand.m_CurrentAttachedGO.transform.root).gameObject;
						}
					}
					catch
					{
					}
					try
					{
						Hand rightHand = physRig.rightHand;
						if ((Object)(object)((rightHand != null) ? rightHand.m_CurrentAttachedGO : null) != (Object)null)
						{
							val6 = ((Component)physRig.rightHand.m_CurrentAttachedGO.transform.root).gameObject;
						}
					}
					catch
					{
					}
					cachedRigGrips = _cachedRigGrips;
					foreach (Grip val7 in cachedRigGrips)
					{
						if ((Object)(object)val7 == (Object)null || !val7.HasAttachedHands() || IsTorsoGrip(val7, torso))
						{
							continue;
						}
						Transform root = ((Component)val7).transform.root;
						if (((Object)(object)val5 != (Object)null && (Object)(object)((Component)root).gameObject == (Object)(object)val5) || ((Object)(object)val6 != (Object)null && (Object)(object)((Component)root).gameObject == (Object)(object)val6) || (Object)(object)root != (Object)(object)transform)
						{
							continue;
						}
						RigManager externalGrabberFromGrip = GetExternalGrabberFromGrip(val7, rigManager);
						if ((Object)(object)externalGrabberFromGrip == (Object)null)
						{
							continue;
						}
						Transform transform2 = ((Component)val7).transform;
						if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null)
						{
							float num = Vector3.Distance(transform2.position, val3.position);
							float num2 = Vector3.Distance(transform2.position, val4.position);
							if (transform2.IsChildOf(val3) || num < num2)
							{
								if ((Object)(object)val == (Object)null)
								{
									val = externalGrabberFromGrip;
								}
							}
							else if ((Object)(object)val2 == (Object)null)
							{
								val2 = externalGrabberFromGrip;
							}
						}
						else if (transform.InverseTransformPoint(transform2.position).x < 0f)
						{
							if ((Object)(object)val == (Object)null)
							{
								val = externalGrabberFromGrip;
							}
						}
						else if ((Object)(object)val2 == (Object)null)
						{
							val2 = externalGrabberFromGrip;
						}
					}
				}
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
				{
					float rigMass2 = GetRigMass(val);
					float rigMass3 = GetRigMass(val2);
					if (rigMass2 >= rigMass * 0.9f || rigMass3 >= rigMass * 0.9f)
					{
						TriggerRagdoll(rigManager, "Both Arms Grabbed", dropItems: false);
						return;
					}
				}
				int num3 = 0;
				RigManager val8 = null;
				cachedRigGrips = (Grip[])(object)new Grip[3] { torso.gChest, torso.gSpine, torso.gPelvis };
				foreach (Grip val9 in cachedRigGrips)
				{
					if (!((Object)(object)val9 == (Object)null))
					{
						RigManager externalGrabber3 = GetExternalGrabber(val9, rigManager);
						if ((Object)(object)externalGrabber3 != (Object)null)
						{
							val8 = externalGrabber3;
							num3 += CountExternalHands(val9, rigManager);
						}
					}
				}
				if ((Object)(object)torso.gHead != (Object)null)
				{
					num3 += CountExternalHands(torso.gHead, rigManager);
				}
				if ((Object)(object)torso.gNeck != (Object)null)
				{
					num3 += CountExternalHands((Grip)(object)torso.gNeck, rigManager);
				}
				if ((Object)(object)val8 != (Object)null && num3 >= 1)
				{
					float num4 = GetRigMass(val8) / rigMass;
					if (num4 >= 2f && num3 >= 1)
					{
						TriggerRagdoll(rigManager, "Body Grabbed (Much Bigger)", dropItems: false);
					}
					else if (num4 >= 1.3f && num3 >= 2)
					{
						TriggerRagdoll(rigManager, "Body Grabbed (Both Hands)", dropItems: false);
					}
				}
			}
			catch
			{
			}
		}

		private static RigManager GetExternalGrabber(Grip grip, RigManager myRig)
		{
			if ((Object)(object)grip == (Object)null || !grip.HasAttachedHands())
			{
				return null;
			}
			return GetExternalGrabberFromGrip(grip, myRig);
		}

		private static RigManager GetExternalGrabberFromGrip(Grip grip, RigManager myRig)
		{
			try
			{
				List<Hand> attachedHands = grip.attachedHands;
				if (attachedHands == null)
				{
					return null;
				}
				for (int i = 0; i < attachedHands.Count; i++)
				{
					Hand val = attachedHands[i];
					if ((Object)(object)val != (Object)null && (Object)(object)val.manager != (Object)null && (Object)(object)val.manager != (Object)(object)myRig)
					{
						return val.manager;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static int CountExternalHands(Grip grip, RigManager myRig)
		{
			int num = 0;
			try
			{
				if ((Object)(object)grip == (Object)null || !grip.HasAttachedHands())
				{
					return 0;
				}
				List<Hand> attachedHands = grip.attachedHands;
				if (attachedHands == null)
				{
					return 0;
				}
				for (int i = 0; i < attachedHands.Count; i++)
				{
					Hand val = attachedHands[i];
					if ((Object)(object)val != (Object)null && (Object)(object)val.manager != (Object)null && (Object)(object)val.manager != (Object)(object)myRig)
					{
						num++;
					}
				}
			}
			catch
			{
			}
			return num;
		}

		private static bool IsTorsoGrip(Grip grip, PhysTorso torso)
		{
			if (!((Object)(object)grip == (Object)(object)torso.gHead) && !((Object)(object)grip == (Object)(object)torso.gNeck) && !((Object)(object)grip == (Object)(object)torso.gChest) && !((Object)(object)grip == (Object)(object)torso.gSpine))
			{
				return (Object)(object)grip == (Object)(object)torso.gPelvis;
			}
			return true;
		}

		private static float GetRigMass(RigManager rig)
		{
			try
			{
				if ((Object)(object)rig == (Object)null)
				{
					return 1f;
				}
				PhysicsRig physicsRig = rig.physicsRig;
				if ((Object)(object)physicsRig == (Object)null)
				{
					return 1f;
				}
				float num = 0f;
				PhysTorso torso = physicsRig.torso;
				if ((Object)(object)torso != (Object)null)
				{
					if ((Object)(object)torso.rbHead != (Object)null)
					{
						num += torso.rbHead.mass;
					}
					if ((Object)(object)torso.rbChest != (Object)null)
					{
						num += torso.rbChest.mass;
					}
					if ((Object)(object)torso.rbSpine != (Object)null)
					{
						num += torso.rbSpine.mass;
					}
					if ((Object)(object)torso.rbPelvis != (Object)null)
					{
						num += torso.rbPelvis.mass;
					}
				}
				if ((Object)(object)physicsRig.leftHand != (Object)null && (Object)(object)physicsRig.leftHand.rb != (Object)null)
				{
					num += physicsRig.leftHand.rb.mass;
				}
				if ((Object)(object)physicsRig.rightHand != (Object)null && (Object)(object)physicsRig.rightHand.rb != (Object)null)
				{
					num += physicsRig.rightHand.rb.mass;
				}
				return (num > 0f) ? num : 1f;
			}
			catch
			{
				return 1f;
			}
		}

		private static void RefreshGripCache(RigManager rigManager)
		{
			if (Time.time - _lastGripCacheTime < 2f && _cachedRigGrips != null)
			{
				return;
			}
			try
			{
				_cachedRigGrips = Il2CppArrayBase<Grip>.op_Implicit(((Component)rigManager).GetComponentsInChildren<Grip>());
				_lastGripCacheTime = Time.time;
			}
			catch
			{
				_cachedRigGrips = null;
			}
		}

		private static void TriggerRagdoll(RigManager rig, string reason, bool dropItems)
		{
			try
			{
				PhysicsRig physicsRig = rig.physicsRig;
				if (!((Object)(object)physicsRig == (Object)null))
				{
					ApplyRagdollMode(physicsRig);
					if (dropItems)
					{
						TryDrop(Player.LeftHand);
						TryDrop(Player.RightHand);
					}
					_nextRagdollTime = Time.time + 2f;
					MelonLogger.Msg($"Ragdoll triggered: {reason} ({_mode})");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Ragdoll trigger error: " + ex.Message);
			}
		}

		private static void ApplyRagdollMode(PhysicsRig physRig)
		{
			if (_tantrumMode)
			{
				physRig.RagdollRig();
			}
			else if (_mode == RagdollMode.ARM_CONTROL)
			{
				physRig.legLf.ShutdownLimb();
				physRig.legRt.ShutdownLimb();
			}
			else
			{
				physRig.ShutdownRig();
				physRig.RagdollRig();
			}
		}

		private static void TryDrop(Hand hand)
		{
			try
			{
				if (!((Object)(object)hand == (Object)null) && hand.HasAttachedObject())
				{
					Grip obj = ((Il2CppObjectBase)hand.AttachedReceiver).TryCast<Grip>();
					if (obj != null)
					{
						obj.ForceDetach(true);
					}
				}
			}
			catch
			{
			}
		}

		private static void OnPlayerDeathHook(RigManager rig)
		{
			if (!_enabled)
			{
				return;
			}
			try
			{
				PhysicsRig val = ((rig != null) ? rig.physicsRig : null);
				if ((Object)(object)val != (Object)null)
				{
					val.TurnOnRig();
					val.UnRagdollRig();
				}
				_ragdollCooldownUntil = Time.time + 2f;
			}
			catch
			{
			}
		}

		private static void OnPlayerResurrectedHook(RigManager rig)
		{
		}
	}
}