Decompiled source of Ragdoll Reload v1.0.0

Mods/RagdollReload.dll

Decompiled 2 days 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 Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using RagdollReload;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "Ragdoll Reload", "1.0.0", "DFort2", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DFort2")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Manual magazine insertion while ragdolled in BONELAB.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RagdollReload")]
[assembly: AssemblyTitle("RagdollReload")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace RagdollReload
{
	internal sealed class HeldItem
	{
		private IntPtr _host;

		internal Gun? Gun { get; private set; }

		internal Magazine? Magazine { get; private set; }

		internal void Update(Hand? hand, RigManager rig)
		{
			if (hand == null || !Object.op_Implicit((Object)(object)hand) || !Object.op_Implicit((Object)(object)hand.manager) || ((Il2CppObjectBase)hand.manager).Pointer != ((Il2CppObjectBase)rig).Pointer)
			{
				Clear();
				return;
			}
			HandReciever attachedReceiver = hand.AttachedReceiver;
			object obj;
			if (!Object.op_Implicit((Object)(object)attachedReceiver))
			{
				obj = null;
			}
			else
			{
				IGrippable host = attachedReceiver.Host;
				obj = ((host != null) ? ((Il2CppObjectBase)host).TryCast<InteractableHost>() : null);
			}
			InteractableHost val = (InteractableHost)obj;
			if (val == null || !Object.op_Implicit((Object)(object)val))
			{
				Clear();
			}
			else if (!(_host == ((Il2CppObjectBase)val).Pointer))
			{
				_host = ((Il2CppObjectBase)val).Pointer;
				Gun = ((Component)val).GetComponent<Gun>() ?? ((Component)val).GetComponentInChildren<Gun>();
				Magazine = ((Component)val).GetComponent<Magazine>() ?? ((Component)val).GetComponentInChildren<Magazine>();
				if (Object.op_Implicit((Object)(object)Gun) && (!Object.op_Implicit((Object)(object)Gun.host) || ((Il2CppObjectBase)Gun.host).Pointer != _host))
				{
					Gun = null;
				}
				if (Object.op_Implicit((Object)(object)Magazine) && (!Object.op_Implicit((Object)(object)Magazine.interactableHost) || ((Il2CppObjectBase)Magazine.interactableHost).Pointer != _host))
				{
					Magazine = null;
				}
			}
		}

		internal void Clear()
		{
			_host = IntPtr.Zero;
			Gun = null;
			Magazine = null;
		}
	}
	public sealed class Mod : MelonMod
	{
		private readonly HeldItem _left = new HeldItem();

		private readonly HeldItem _right = new HeldItem();

		private MelonPreferences_Category _category;

		private MelonPreferences_Entry<bool> _enabled;

		private BoolElement? _toggle;

		private IntPtr _socket;

		private IntPtr _plug;

		private float _nearSince;

		private float _nextAttempt;

		private float _nextWarning;

		public override void OnInitializeMelon()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			_category = MelonPreferences.CreateCategory("RagdollReload");
			_enabled = _category.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Page val = Page.Root.CreatePage("Ragdoll Reload", Color.cyan, 0, true);
			_toggle = val.CreateBool("Enabled", Color.white, _enabled.Value, (Action<bool>)delegate(bool value)
			{
				_enabled.Value = value;
				_category.SaveToFile(false);
				Reset();
			});
			((MelonBase)this).LoggerInstance.Msg("Ragdoll Reload loaded.");
		}

		public override void OnPreferencesLoaded()
		{
			if (_toggle != null)
			{
				_toggle.Value = _enabled.Value;
			}
			Reset();
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			Reset();
		}

		public override void OnFixedUpdate()
		{
			try
			{
				Tick();
			}
			catch (Exception ex)
			{
				Reset();
				if (!(Time.realtimeSinceStartup < _nextWarning))
				{
					_nextWarning = Time.realtimeSinceStartup + 10f;
					((MelonBase)this).LoggerInstance.Warning("Magazine insertion failed: " + ex.GetType().Name + ": " + ex.Message);
				}
			}
		}

		private void Tick()
		{
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			RigManager rigManager = Player.RigManager;
			PhysicsRig val = (Object.op_Implicit((Object)(object)rigManager) ? rigManager.physicsRig : null);
			if (_enabled == null || !_enabled.Value || Time.timeScale <= 0f || rigManager == null || !Object.op_Implicit((Object)(object)rigManager) || Object.op_Implicit((Object)(object)rigManager.activeSeat) || val == null || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.torso) || (!val.torso.shutdown && val.ballLocoEnabled) || (Object.op_Implicit((Object)(object)rigManager.health) && rigManager.health.curr_Health <= 0f))
			{
				Reset();
				return;
			}
			_left.Update(val.leftHand, rigManager);
			_right.Update(val.rightHand, rigManager);
			Gun gun = _left.Gun;
			Magazine magazine = _right.Magazine;
			if (!Object.op_Implicit((Object)(object)gun) || !Object.op_Implicit((Object)(object)magazine))
			{
				gun = _right.Gun;
				magazine = _left.Magazine;
			}
			if (gun == null || magazine == null || !Object.op_Implicit((Object)(object)gun) || !Object.op_Implicit((Object)(object)magazine) || !((Behaviour)gun).isActiveAndEnabled || !((Behaviour)magazine).isActiveAndEnabled)
			{
				ClearCandidate();
				return;
			}
			AmmoSocket ammoSocket = gun.ammoSocket;
			AmmoPlug magazinePlug = magazine.magazinePlug;
			MagazineState magazineState = magazine.magazineState;
			MagazineData val2 = ((magazineState != null) ? magazineState.magazineData : null);
			if (!Object.op_Implicit((Object)(object)ammoSocket) || !Object.op_Implicit((Object)(object)magazinePlug) || (Object)(object)val2 == (Object)null || !((Behaviour)ammoSocket).isActiveAndEnabled || !((Behaviour)magazinePlug).isActiveAndEnabled || ammoSocket.HasMagazine || ((Socket)ammoSocket).IsLocked || Object.op_Implicit((Object)(object)((Socket)ammoSocket).LockedPlug) || magazine.isMagazineInserted || ((AlignPlug)magazinePlug)._isLocked || ((AlignPlug)magazinePlug)._isExitTransition || (((AlignPlug)magazinePlug)._isEnterTransition && (!Object.op_Implicit((Object)(object)((AlignPlug)magazinePlug)._lastSocket) || ((Il2CppObjectBase)((AlignPlug)magazinePlug)._lastSocket).Pointer != ((Il2CppObjectBase)ammoSocket).Pointer)))
			{
				ClearCandidate();
				return;
			}
			Transform transform = ((Component)ammoSocket).transform;
			Transform transform2 = ((Component)magazinePlug).transform;
			string platform = ammoSocket.platform;
			string platform2 = val2.platform;
			Vector3 val3 = transform.position - transform2.position;
			if (!ReloadRules.CanInsert(platform, platform2, ((Vector3)(ref val3)).sqrMagnitude, Quaternion.Angle(transform.rotation, transform2.rotation)))
			{
				ClearCandidate();
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (_socket != ((Il2CppObjectBase)ammoSocket).Pointer || _plug != ((Il2CppObjectBase)magazinePlug).Pointer)
			{
				_socket = ((Il2CppObjectBase)ammoSocket).Pointer;
				_plug = ((Il2CppObjectBase)magazinePlug).Pointer;
				_nearSince = realtimeSinceStartup;
			}
			if (!(realtimeSinceStartup - _nearSince < 0.08f) && !(realtimeSinceStartup < _nextAttempt))
			{
				_nextAttempt = realtimeSinceStartup + 0.5f;
				((AlignPlug)magazinePlug).ForceInSocket((Socket)(object)ammoSocket);
				ClearCandidate();
			}
		}

		private void ClearCandidate()
		{
			_socket = IntPtr.Zero;
			_plug = IntPtr.Zero;
			_nearSince = 0f;
		}

		private void Reset()
		{
			_left.Clear();
			_right.Clear();
			ClearCandidate();
			_nextAttempt = 0f;
		}
	}
	internal static class ReloadRules
	{
		internal const float Reach = 0.12f;

		internal const float MaxAngle = 65f;

		internal const float HoldTime = 0.08f;

		internal static bool CanInsert(string? socketPlatform, string? magazinePlatform, float distanceSquared, float angle)
		{
			if (!string.IsNullOrEmpty(socketPlatform) && string.Equals(socketPlatform, magazinePlatform, StringComparison.Ordinal) && float.IsFinite(distanceSquared) && distanceSquared >= 0f && distanceSquared <= 0.0144f && float.IsFinite(angle) && angle >= 0f)
			{
				return angle <= 65f;
			}
			return false;
		}
	}
}