Decompiled source of BlackHole v1.0.0

Mods/BlackHole.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BlackHole;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "Black Hole", "1.0.0", "marrowbyte", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("marrowbyte")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A BONELAB black hole effect with gravity.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BlackHole")]
[assembly: AssemblyTitle("BlackHole")]
[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.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;
		}
	}
	[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 BlackHole
{
	internal static class Dimensions
	{
		internal const float DefaultDiameter = 0.24f;

		internal const float DiskRadius = 6.7f;

		internal const float VolumeRadius = 8f;

		internal static float ClampDiameter(float value)
		{
			if (!float.IsFinite(value))
			{
				return 0.24f;
			}
			return Math.Clamp(value, 0.1f, 10f);
		}

		internal static float Horizon(float diameter)
		{
			return ClampDiameter(diameter) / 13.4f;
		}

		internal static float Volume(float diameter)
		{
			return Horizon(diameter) * 16.2f;
		}

		internal static float Scale(float diameter)
		{
			return ClampDiameter(diameter) / 0.24f;
		}

		internal static float SpawnDistance(float diameter)
		{
			return Math.Max(2.5f, ClampDiameter(diameter) * 1.25f);
		}
	}
	internal sealed class DragState
	{
		private bool pressed = true;

		private Vector3 offset;

		private Vector3 anchor;

		internal bool Active { get; private set; }

		internal bool UpdateTrigger(float axis)
		{
			if (!float.IsFinite(axis))
			{
				Reset();
				return false;
			}
			if (axis <= 0.2f)
			{
				pressed = false;
				Active = false;
				return false;
			}
			if (axis < 0.75f || pressed)
			{
				return false;
			}
			pressed = true;
			return true;
		}

		internal void Begin(Vector3 origin, Quaternion rotation, Vector3 center, Vector3 hit)
		{
			Quaternion rotation2 = Quaternion.Inverse(rotation);
			offset = Vector3.Transform(center - origin, rotation2);
			anchor = Vector3.Transform(hit - origin, rotation2);
			Active = true;
		}

		internal Vector3 Position(Vector3 origin, Quaternion rotation)
		{
			return origin + Vector3.Transform(offset, rotation);
		}

		internal Vector3 Anchor(Vector3 origin, Quaternion rotation)
		{
			return origin + Vector3.Transform(anchor, rotation);
		}

		internal void Reset()
		{
			Active = false;
			pressed = true;
		}

		internal static bool Hit(Vector3 origin, Vector3 direction, Vector3 center, float radius, float maxDistance, out float distance)
		{
			distance = 0f;
			float num = direction.Length();
			if (!float.IsFinite(num) || num < 0.0001f || !float.IsFinite(radius) || radius <= 0f)
			{
				return false;
			}
			direction /= num;
			Vector3 vector = center - origin;
			float num2 = Vector3.Dot(vector, direction);
			float num3 = radius * radius - (vector.LengthSquared() - num2 * num2);
			if (!float.IsFinite(num3) || num3 < 0f)
			{
				return false;
			}
			float num4 = MathF.Sqrt(num3);
			if (num2 + num4 < 0f)
			{
				return false;
			}
			distance = Math.Max(0f, num2 - num4);
			return distance <= maxDistance;
		}
	}
	internal static class Gravity
	{
		internal static float Acceleration(float distance, float range, float strength)
		{
			if (!float.IsFinite(distance) || !float.IsFinite(range) || !float.IsFinite(strength) || distance < 0f || range <= 0f || strength <= 0f || distance >= range)
			{
				return 0f;
			}
			float num = Math.Clamp((range - distance) / Math.Min(range, 1.5f), 0f, 1f);
			num *= num * (3f - 2f * num);
			return Math.Min(45f, strength * 5f / (1f + distance * distance)) * num;
		}

		internal static float Damping(float distance)
		{
			return Math.Clamp(1f - distance / 0.8f, 0f, 1f) * 5f;
		}

		internal static float ScaledAcceleration(float distance, float range, float strength, float scale)
		{
			if (!float.IsFinite(scale) || scale <= 0f)
			{
				return 0f;
			}
			return Math.Min(180f, Acceleration(distance / scale, range, strength) * scale);
		}
	}
	public sealed class Mod : MelonMod
	{
		private sealed record CameraState(UniversalAdditionalCameraData Data, CameraOverrideOption Color, CameraOverrideOption Depth)
		{
			[CompilerGenerated]
			public void Deconstruct(out UniversalAdditionalCameraData Data, out CameraOverrideOption Color, out CameraOverrideOption Depth)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Expected I4, but got Unknown
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected I4, but got Unknown
				Data = this.Data;
				Color = (CameraOverrideOption)(int)this.Color;
				Depth = (CameraOverrideOption)(int)this.Depth;
			}
		}

		private readonly Il2CppReferenceArray<Collider> colliders = new Il2CppReferenceArray<Collider>(8192L);

		private readonly HashSet<int> bodies = new HashSet<int>(8192);

		private readonly List<CameraState> cameras = new List<CameraState>();

		private Settings settings;

		private AssetBundle? bundle;

		private Material? material;

		private GameObject? volume;

		private PointerDrag? drag;

		private float cameraCheck;

		private bool loading;

		private bool warnedCapacity;

		public override void OnInitializeMelon()
		{
			settings = new Settings(Spawn, Remove);
			Hooking.OnLevelLoading += OnLoading;
			Hooking.OnLevelLoaded += OnLoaded;
			Hooking.OnLevelUnloaded += OnUnloaded;
			((MelonBase)this).LoggerInstance.Msg("Controls: BoneMenu > Black Hole. F8 spawns, F9 removes.");
		}

		public override void OnUpdate()
		{
			if (Input.GetKeyDown((KeyCode)290))
			{
				Remove();
			}
			if (Input.GetKeyDown((KeyCode)289))
			{
				Spawn();
			}
			if (!Object.op_Implicit((Object)(object)volume) || !Object.op_Implicit((Object)(object)material))
			{
				return;
			}
			try
			{
				if (Time.unscaledTime >= cameraCheck)
				{
					ConfigureCameras();
					cameraCheck = Time.unscaledTime + 1f;
				}
				drag?.Tick(settings.PointerDrag, settings.Diameter);
				ApplyAppearance();
			}
			catch (Exception error)
			{
				Fail(error);
			}
		}

		public override void OnFixedUpdate()
		{
			//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_0041: 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_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)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			if (loading || !Object.op_Implicit((Object)(object)volume) || !settings.Pull)
			{
				return;
			}
			try
			{
				Vector3 position = volume.transform.position;
				float gravityScale = settings.GravityScale;
				int num = Physics.OverlapSphereNonAlloc(position, settings.PullRange, colliders);
				bodies.Clear();
				if (num == ((Il2CppArrayBase<Collider>)(object)colliders).Length && !warnedCapacity)
				{
					warnedCapacity = true;
					((MelonBase)this).LoggerInstance.Warning("Gravity reached its collider limit. Some objects may not be affected in this scene.");
				}
				for (int i = 0; i < num; i++)
				{
					Collider val = ((Il2CppArrayBase<Collider>)(object)colliders)[i];
					((Il2CppArrayBase<Collider>)(object)colliders)[i] = null;
					if (!Object.op_Implicit((Object)(object)val))
					{
						continue;
					}
					Rigidbody attachedRigidbody = val.attachedRigidbody;
					if (Object.op_Implicit((Object)(object)attachedRigidbody) && !attachedRigidbody.isKinematic && bodies.Add(((Object)attachedRigidbody).GetInstanceID()))
					{
						Vector3 val2 = position - attachedRigidbody.worldCenterOfMass;
						float magnitude = ((Vector3)(ref val2)).magnitude;
						if (float.IsFinite(magnitude))
						{
							float num2 = Gravity.ScaledAcceleration(magnitude, settings.Range, settings.Strength, gravityScale);
							Vector3 val3 = ((magnitude > 0.001f) ? (val2 * (num2 / magnitude)) : Vector3.zero);
							val3 -= attachedRigidbody.velocity * Gravity.Damping(magnitude / gravityScale);
							attachedRigidbody.AddForce(Vector3.ClampMagnitude(val3, 200f), (ForceMode)5);
						}
					}
				}
			}
			catch (Exception error)
			{
				Fail(error);
			}
		}

		private void Spawn()
		{
			//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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			if (loading)
			{
				return;
			}
			try
			{
				RigManager rigManager = Player.RigManager;
				if (!Object.op_Implicit((Object)(object)rigManager) || !Object.op_Implicit((Object)(object)rigManager.ControllerRig) || !Object.op_Implicit((Object)(object)((Rig)rigManager.ControllerRig).m_head))
				{
					((MelonBase)this).LoggerInstance.Warning("Load a level before spawning the black hole.");
					return;
				}
				Transform head = ((Rig)rigManager.ControllerRig).m_head;
				Vector3 forward = head.forward;
				float num = Dimensions.SpawnDistance(settings.Diameter);
				float num2 = Dimensions.Volume(settings.Diameter) * 0.5f + 0.15f;
				Vector3 position = head.position + forward * num;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(head.position, forward, ref val, num + num2, -1, (QueryTriggerInteraction)1))
				{
					position = head.position + forward * Math.Max(num2, ((RaycastHit)(ref val)).distance - num2);
				}
				EnsureMaterial();
				drag?.Cancel();
				if (!Object.op_Implicit((Object)(object)volume))
				{
					volume = GameObject.CreatePrimitive((PrimitiveType)3);
					((Object)volume).name = "BlackHole";
					Collider component = volume.GetComponent<Collider>();
					component.enabled = false;
					Object.Destroy((Object)(object)component);
					MeshRenderer component2 = volume.GetComponent<MeshRenderer>();
					((Renderer)component2).sharedMaterial = material;
					((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)component2).receiveShadows = false;
					((Renderer)component2).lightProbeUsage = (LightProbeUsage)0;
					((Renderer)component2).reflectionProbeUsage = (ReflectionProbeUsage)0;
					Shader val2 = bundle.LoadAsset<Shader>("assets/shaders/pointer.shader");
					if (!Object.op_Implicit((Object)(object)val2) || !val2.isSupported)
					{
						throw new InvalidOperationException("The pointer shader could not be loaded.");
					}
					drag = new PointerDrag(volume, val2);
				}
				volume.transform.position = position;
				Vector3 val3 = Quaternion.AngleAxis(12f, head.right) * Vector3.up;
				material.SetVector("_DiskNormal", new Vector4(val3.x, val3.y, val3.z, 0f));
				ApplyAppearance();
				ConfigureCameras();
				warnedCapacity = false;
			}
			catch (Exception error)
			{
				Fail(error);
			}
		}

		private void ApplyAppearance()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			float num = Dimensions.Horizon(settings.Diameter);
			volume.transform.localScale = Vector3.one * Dimensions.Volume(settings.Diameter);
			Vector3 position = volume.transform.position;
			material.SetVector("_CenterRadius", new Vector4(position.x, position.y, position.z, num));
			material.SetFloat("_Exposure", settings.Brightness);
			material.SetFloat("_Steps", (float)settings.Steps);
			material.SetFloat("_AnimationTime", Time.time);
		}

		private void EnsureMaterial()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)material))
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)bundle))
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BlackHole.assets") ?? throw new InvalidOperationException("The shader bundle is missing.");
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				bundle = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray()));
				if (!Object.op_Implicit((Object)(object)bundle))
				{
					throw new InvalidOperationException("The shader bundle could not be loaded.");
				}
			}
			Material val = bundle.LoadAsset<Material>("assets/generated/blackhole.mat");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.shader) || !val.shader.isSupported)
			{
				throw new InvalidOperationException("The black hole shader is unsupported by this renderer.");
			}
			material = new Material(val)
			{
				enableInstancing = true
			};
		}

		private void ConfigureCameras()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras)
			{
				if (!Object.op_Implicit((Object)(object)item) || (int)item.cameraType != 1)
				{
					continue;
				}
				UniversalAdditionalCameraData component = ((Component)item).GetComponent<UniversalAdditionalCameraData>();
				if (!Object.op_Implicit((Object)(object)component) || (int)component.renderType != 0)
				{
					continue;
				}
				bool flag = false;
				foreach (CameraState camera in cameras)
				{
					if ((Object)(object)camera.Data == (Object)(object)component)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					cameras.Add(new CameraState(component, component.requiresColorOption, component.requiresDepthOption));
					component.requiresColorOption = (CameraOverrideOption)1;
					component.requiresDepthOption = (CameraOverrideOption)1;
				}
			}
			material.SetFloat("_SceneTextures", (float)(cameras.Exists((CameraState state) => Object.op_Implicit((Object)(object)state.Data)) ? 1 : 0));
			material.SetFloat("_Distortion", (float)(settings.Distortion ? 1 : 0));
		}

		private void Remove()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			drag?.Dispose();
			drag = null;
			if (Object.op_Implicit((Object)(object)volume))
			{
				Object.Destroy((Object)(object)volume);
			}
			volume = null;
			foreach (CameraState camera in cameras)
			{
				if (Object.op_Implicit((Object)(object)camera.Data))
				{
					if ((int)camera.Data.requiresColorOption == 1)
					{
						camera.Data.requiresColorOption = camera.Color;
					}
					if ((int)camera.Data.requiresDepthOption == 1)
					{
						camera.Data.requiresDepthOption = camera.Depth;
					}
				}
			}
			cameras.Clear();
			bodies.Clear();
			for (int i = 0; i < ((Il2CppArrayBase<Collider>)(object)colliders).Length; i++)
			{
				((Il2CppArrayBase<Collider>)(object)colliders)[i] = null;
			}
			if (Object.op_Implicit((Object)(object)material))
			{
				Object.Destroy((Object)(object)material);
			}
			material = null;
		}

		private void OnLoading(LevelInfo level)
		{
			loading = true;
			Remove();
		}

		private void OnLoaded(LevelInfo level)
		{
			loading = false;
		}

		private void OnUnloaded()
		{
			loading = true;
			Remove();
		}

		private void Fail(Exception error)
		{
			Remove();
			((MelonBase)this).LoggerInstance.Error("Black hole stopped: " + error.Message);
		}

		public override void OnDeinitializeMelon()
		{
			Hooking.OnLevelLoading -= OnLoading;
			Hooking.OnLevelLoaded -= OnLoaded;
			Hooking.OnLevelUnloaded -= OnUnloaded;
			Remove();
			if (Object.op_Implicit((Object)(object)bundle))
			{
				bundle.Unload(true);
			}
			bundle = null;
		}
	}
	internal sealed class PointerDrag : IDisposable
	{
		private const float Reach = 50f;

		private readonly DragState state = new DragState();

		private readonly Il2CppStructArray<RaycastHit> hits = new Il2CppStructArray<RaycastHit>(64L);

		private readonly GameObject target;

		private readonly GameObject pointer;

		private readonly LineRenderer line;

		private readonly Material material;

		private RigManager? rig;

		private BaseController? controller;

		internal PointerDrag(GameObject target, Shader shader)
		{
			//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_0039: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			this.target = target;
			material = new Material(shader)
			{
				enableInstancing = true
			};
			pointer = new GameObject("BlackHolePointer");
			line = pointer.AddComponent<LineRenderer>();
			((Renderer)line).sharedMaterial = material;
			line.useWorldSpace = true;
			line.positionCount = 2;
			line.startWidth = 0.003f;
			line.endWidth = 0.0015f;
			line.numCapVertices = 4;
			((Renderer)line).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)line).receiveShadows = false;
			((Renderer)line).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)line).reflectionProbeUsage = (ReflectionProbeUsage)0;
			((Renderer)line).enabled = false;
		}

		internal void Tick(bool enabled, float diameter)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			RigManager rigManager = Player.RigManager;
			if (!enabled || !Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)rigManager) || !Object.op_Implicit((Object)(object)rigManager.ControllerRig) || rigManager.ControllerRig.IsPaused || !Object.op_Implicit((Object)(object)rigManager.physicsRig) || !Object.op_Implicit((Object)(object)rigManager.physicsRig.rightHand) || Object.op_Implicit((Object)(object)rigManager.physicsRig.rightHand.m_CurrentAttachedGO))
			{
				Cancel();
				return;
			}
			BaseController rightController = rigManager.ControllerRig.rightController;
			if (!Object.op_Implicit((Object)(object)rightController) || !((Behaviour)rightController).isActiveAndEnabled)
			{
				Cancel();
				return;
			}
			OpenControllerRig val = ((Il2CppObjectBase)rigManager.ControllerRig).TryCast<OpenControllerRig>();
			if (Object.op_Implicit((Object)(object)val) && (int)val._contRtState == 0)
			{
				Cancel();
				return;
			}
			if ((Object)(object)rig != (Object)(object)rigManager || (Object)(object)controller != (Object)(object)rightController)
			{
				Cancel();
				rig = rigManager;
				controller = rightController;
			}
			Transform transform = ((Component)rightController).transform;
			Vector3 position = transform.position;
			Vector3 forward = transform.forward;
			Quaternion rotation = transform.rotation;
			bool flag = state.UpdateTrigger(rightController.GetPrimaryInteractionButtonAxis());
			if (state.Active)
			{
				target.transform.position = From(state.Position(To(position), To(rotation)));
				Draw(position, From(state.Anchor(To(position), To(rotation))), highlighted: true);
				return;
			}
			float val2 = Obstruction(position, forward, rigManager);
			float distance;
			bool flag2 = DragState.Hit(To(position), To(forward), To(target.transform.position), Math.Max(diameter * 0.5f, 0.06f), Math.Min(50f, val2), out distance);
			if (flag2 && flag)
			{
				state.Begin(To(position), To(rotation), To(target.transform.position), To(position + forward * distance));
			}
			Draw(position, position + forward * (flag2 ? distance : Math.Min(5f, val2)), flag2);
		}

		private float Obstruction(Vector3 origin, Vector3 direction, RigManager player)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.RaycastNonAlloc(origin, direction, hits, 50f, -1, (QueryTriggerInteraction)1);
			float num2 = 50f;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)hits)[i];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<RigManager>() == (Object)(object)player))
				{
					num2 = Math.Min(num2, ((RaycastHit)(ref val)).distance);
				}
			}
			if (num != ((Il2CppArrayBase<RaycastHit>)(object)hits).Length)
			{
				return num2;
			}
			return 0f;
		}

		private void Draw(Vector3 start, Vector3 end, bool highlighted)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			Color val = (highlighted ? new Color(1f, 0.65f, 0.15f, 0.95f) : new Color(0.3f, 0.75f, 1f, 0.3f));
			line.startColor = val;
			line.endColor = val;
			line.SetPosition(0, start);
			line.SetPosition(1, end);
			((Renderer)line).enabled = true;
		}

		internal void Cancel()
		{
			state.Reset();
			if (Object.op_Implicit((Object)(object)line))
			{
				((Renderer)line).enabled = false;
			}
		}

		public void Dispose()
		{
			Cancel();
			if (Object.op_Implicit((Object)(object)pointer))
			{
				Object.Destroy((Object)(object)pointer);
			}
			if (Object.op_Implicit((Object)(object)material))
			{
				Object.Destroy((Object)(object)material);
			}
		}

		private static Vector3 To(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(value.x, value.y, value.z);
		}

		private static Quaternion To(Quaternion value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(value.x, value.y, value.z, value.w);
		}

		private static Vector3 From(Vector3 value)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(value.X, value.Y, value.Z);
		}
	}
	internal sealed class Settings
	{
		private readonly MelonPreferences_Category category = MelonPreferences.CreateCategory("BlackHole");

		private readonly MelonPreferences_Entry<float> strength;

		private readonly MelonPreferences_Entry<float> range;

		private readonly MelonPreferences_Entry<float> brightness;

		private readonly MelonPreferences_Entry<bool> pull;

		private readonly MelonPreferences_Entry<float> diameter;

		private readonly MelonPreferences_Entry<bool> scaleGravity;

		private readonly MelonPreferences_Entry<int> quality;

		private readonly MelonPreferences_Entry<bool> distortion;

		private readonly FloatElement sizeElement;

		private readonly MelonPreferences_Entry<bool> pointerDrag;

		internal float Strength => Bounded(strength.Value, 12f, 1f, 30f);

		internal float Range => Bounded(range.Value, 8f, 1f, 20f);

		internal float Brightness => Bounded(brightness.Value, 2f, 0.5f, 5f);

		internal bool Pull => pull.Value;

		internal float Diameter => Dimensions.ClampDiameter(diameter.Value);

		internal float GravityScale
		{
			get
			{
				if (!scaleGravity.Value)
				{
					return 1f;
				}
				return Dimensions.Scale(Diameter);
			}
		}

		internal float PullRange => Range * GravityScale;

		internal Detail Quality => (Detail)Math.Clamp(quality.Value, 0, 2);

		internal int Steps => Quality switch
		{
			Detail.Balanced => 160, 
			Detail.High => 320, 
			_ => 640, 
		};

		internal bool Distortion => distortion.Value;

		internal bool PointerDrag => pointerDrag.Value;

		internal Settings(Action spawn, Action remove)
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			strength = category.CreateEntry<float>("Strength", 12f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			range = category.CreateEntry<float>("Range", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			brightness = category.CreateEntry<float>("Brightness", 2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			pull = category.CreateEntry<bool>("Gravity", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			diameter = category.CreateEntry<float>("Diameter", 0.24f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			scaleGravity = category.CreateEntry<bool>("ScaleGravity", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			quality = category.CreateEntry<int>("Quality", 2, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			distortion = category.CreateEntry<bool>("Distortion", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			pointerDrag = category.CreateEntry<bool>("PointerDrag", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Page val = Page.Root.CreatePage("Black Hole", new Color(1f, 0.55f, 0.15f), 0, true);
			val.CreateFunction("Spawn / move here", Color.white, spawn);
			val.CreateFunction("Remove", Color.red, remove);
			val.CreateBool("Right-hand dragging", Color.white, PointerDrag, (Action<bool>)delegate(bool value)
			{
				Save(pointerDrag, value);
			});
			sizeElement = val.CreateFloat("Disk diameter (m)", Color.white, Diameter, 0.1f, 0.1f, 10f, (Action<float>)SetDiameter);
			Page obj = val.CreatePage("Size presets", Color.white, 0, true);
			obj.CreateFunction("Basketball (0.24 m)", Color.white, (Action)delegate
			{
				SetDiameter(0.24f);
			});
			obj.CreateFunction("1 metre", Color.white, (Action)delegate
			{
				SetDiameter(1f);
			});
			obj.CreateFunction("5 metres", Color.white, (Action)delegate
			{
				SetDiameter(5f);
			});
			obj.CreateFunction("10 metres", Color.white, (Action)delegate
			{
				SetDiameter(10f);
			});
			val.CreateBool("Gravity", Color.white, Pull, (Action<bool>)delegate(bool value)
			{
				Save(pull, value);
			});
			val.CreateBool("Scale gravity with size", Color.white, scaleGravity.Value, (Action<bool>)delegate(bool value)
			{
				Save(scaleGravity, value);
			});
			val.CreateFloat("Pull strength", Color.white, Strength, 1f, 1f, 30f, (Action<float>)delegate(float value)
			{
				Save(strength, value);
			});
			val.CreateFloat("Base pull range (m)", Color.white, Range, 1f, 1f, 20f, (Action<float>)delegate(float value)
			{
				Save(range, value);
			});
			val.CreateFloat("Brightness", Color.white, Brightness, 0.25f, 0.5f, 5f, (Action<float>)delegate(float value)
			{
				Save(brightness, value);
			});
			val.CreateEnum("Quality", Color.white, (Enum)Quality, (Action<Enum>)delegate(Enum value)
			{
				Save(quality, (int)(Detail)(object)value);
			});
			val.CreateBool("Background distortion", Color.white, Distortion, (Action<bool>)delegate(bool value)
			{
				Save(distortion, value);
			});
		}

		private void SetDiameter(float value)
		{
			value = Dimensions.ClampDiameter(value);
			sizeElement.Value = value;
			Save(diameter, value);
		}

		private void Save<T>(MelonPreferences_Entry<T> entry, T value)
		{
			entry.Value = value;
			category.SaveToFile(false);
		}

		private static float Bounded(float value, float fallback, float min, float max)
		{
			if (!float.IsFinite(value))
			{
				return fallback;
			}
			return Math.Clamp(value, min, max);
		}
	}
	internal enum Detail
	{
		Balanced,
		High,
		Ultra
	}
}