Decompiled source of BubbleLevelSet v2.0.4

BubbleLevelSet.dll

Decompiled 2 weeks ago
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HLin_Mods.SharedBubble;
using HarmonyLib;
using OtherLoader;
using UnityEngine;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace HLin_Mods.BubbleLevelSet
{
	[BepInPlugin("HLin_Mods.BubbleLevelSet", "BubbleLevelSet", "2.0.4")]
	[BepInProcess("h3vr.exe")]
	[Description("Built with MeatKit")]
	[BepInDependency("h3vr.otherloader", "1.3.0")]
	public class BubbleLevelSetPlugin : BaseUnityPlugin
	{
		private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static ManualLogSource Logger;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			LoadAssets();
		}

		private void LoadAssets()
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "HLin_Mods.BubbleLevelSet");
			OtherLoader.RegisterDirectLoad(BasePath, "HLin_Mods.BubbleLevelSet", "", "", "hlin-bubblelevel", "");
		}
	}
	public class BubbleLevel : GravityBubbleLevelController
	{
		[Header("BaseObject")]
		public GameObject baseObject = null;

		[Header("FVRAttachment")]
		public FVRFireArmAttachment attachment = null;

		[Header("LevelBubble")]
		public GameObject level_bubble = null;

		[Header("Bubble Travel")]
		[Tooltip("The level position when the bubble is centered.")]
		public float centerLocalX = -0.0084f;

		[Tooltip("The hard left travel stop in the bubble parent's local X space.")]
		public float minimumLocalX = -0.33f;

		[Tooltip("The hard right travel stop in the bubble parent's local X space.")]
		public float maximumLocalX = 0.33f;

		[Tooltip("Cant angle at which the rail bubble reaches a travel stop.")]
		[Range(1f, 45f)]
		public float fullScaleAngleDegrees = 3.25f;

		[Header("Fluid Motion")]
		[Tooltip("Spring acceleration that pulls the bubble toward its gravity-derived equilibrium.")]
		public float restoringAcceleration = 60f;

		[Tooltip("Linear viscous drag that represents liquid resistance.")]
		public float fluidDrag = 15f;

		[Tooltip("Small displacement at which the bubble settles instead of jittering.")]
		public float staticFrictionDistance = 5E-05f;

		[Tooltip("Velocity below which the bubble settles instead of jittering.")]
		public float settleVelocity = 0.0005f;

		[Tooltip("Safety cap for extreme attachment motion.")]
		public float maximumVelocity = 1.2f;

		protected override GameObject BaseObject => baseObject;

		protected override GameObject LevelBubble => level_bubble;

		protected override float CenterLocalX => centerLocalX;

		protected override float MinimumLocalX => minimumLocalX;

		protected override float MaximumLocalX => maximumLocalX;

		protected override float FullScaleAngleDegrees => fullScaleAngleDegrees;

		protected override float RestoringAcceleration => restoringAcceleration;

		protected override float FluidDrag => fluidDrag;

		protected override float StaticFrictionDistance => staticFrictionDistance;

		protected override float SettleVelocity => settleVelocity;

		protected override float MaximumVelocity => maximumVelocity;

		private void Awake()
		{
			if (!InitializeRuntimeState())
			{
				Debug.LogWarning((object)"BubbleLevel disabled because its base object or bubble reference is missing.", (Object)(object)this);
				((Behaviour)this).enabled = false;
			}
		}

		private void FixedUpdate()
		{
			StepController();
		}
	}
	public class BubbleLevelMount : MonoBehaviour
	{
		[Header("BaseObject")]
		public GameObject baseObject = null;

		[Header("FVRAttachment")]
		public FVRFireArmAttachment attachment = null;

		[Header("LevelBubble")]
		public GameObject level_bubble = null;

		[Header("BubblePivot")]
		public Transform customPivot;

		private void Awake()
		{
			if ((Object)(object)attachment == (Object)null || (Object)(object)level_bubble == (Object)null || (Object)(object)customPivot == (Object)null)
			{
				Debug.LogWarning((object)"BubbleLevelMount disabled because an attachment, bubble, or pivot reference is missing.", (Object)(object)this);
				((Behaviour)this).enabled = false;
			}
		}

		private float GetRoll()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attachment.curMount != (Object)null)
			{
				FVRFireArmAttachmentMount rootMount = attachment.curMount.GetRootMount();
				if ((Object)(object)rootMount != (Object)null)
				{
					return 0f - Mathf.DeltaAngle(0f, ((Component)rootMount).transform.eulerAngles.z);
				}
			}
			return Mathf.DeltaAngle(0f, ((Component)attachment).transform.eulerAngles.z);
		}

		private void FixedUpdate()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			float roll = GetRoll();
			float num = 0f - Mathf.DeltaAngle(0f, level_bubble.transform.localEulerAngles.y);
			float num2 = Mathf.Clamp(3f * roll - num, -25f, 25f);
			if (num < 6.301f && num > -6.301f)
			{
				if (num < 6.3f && num > 5.8f)
				{
					num2 *= (7f - num) * 0.3f;
				}
				else if (num > -6.3f && num < -5.8f)
				{
					num2 *= (7f + num) * 0.3f;
				}
				level_bubble.transform.RotateAround(customPivot.position, Vector3.forward, num2 * Time.fixedDeltaTime);
			}
			else if (num >= 6.3f)
			{
				level_bubble.transform.RotateAround(customPivot.position, Vector3.forward, -0.02f * Mathf.Abs(num2) * Time.fixedDeltaTime);
			}
			else if (num <= -6.3f)
			{
				level_bubble.transform.RotateAround(customPivot.position, Vector3.forward, 0.02f * Mathf.Abs(num2) * Time.fixedDeltaTime);
			}
		}
	}
	public class BubbleLevelMountTest : MonoBehaviour
	{
		[Header("BaseObject")]
		public GameObject baseObject = null;

		[Header("FVRAttachment")]
		public FVRFireArmAttachment attachment = null;

		[Header("LevelBubble")]
		public GameObject level_bubble = null;

		[Header("BubblePivot")]
		public Transform customPivot;

		[Header("Angular Travel")]
		public float minimumAngle = -6.3f;

		public float maximumAngle = 6.3f;

		[Header("Gravity Reference")]
		public Vector3 gravityAtLevelLocal = Vector3.back;

		[Header("Fluid Motion")]
		public float restoringAcceleration = 70f;

		public float fluidDrag = 16f;

		public float staticFrictionAngle = 0.01f;

		public float settleVelocity = 0.01f;

		public float maximumAngularVelocity = 120f;

		private Vector3 initialBubbleOffsetLocal;

		private Quaternion initialBubbleRotationLocal;

		private Vector3 levelDirectionLocal;

		private Vector3 trackAxisLocal;

		private float bubbleAngle;

		private float bubbleAngularVelocity;

		private void Awake()
		{
			//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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0089: 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)
			//IL_0093: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attachment == (Object)null || (Object)(object)level_bubble == (Object)null || (Object)(object)customPivot == (Object)null)
			{
				Debug.LogWarning((object)"BubbleLevelMountTest disabled because an attachment, bubble, or pivot reference is missing.", (Object)(object)this);
				((Behaviour)this).enabled = false;
				return;
			}
			initialBubbleOffsetLocal = customPivot.InverseTransformPoint(level_bubble.transform.position);
			initialBubbleRotationLocal = Quaternion.Inverse(customPivot.rotation) * level_bubble.transform.rotation;
			Vector3 val = customPivot.InverseTransformDirection(-level_bubble.transform.forward);
			trackAxisLocal = ((Vector3)(ref val)).normalized;
			Vector3 val2 = Vector3.ProjectOnPlane(gravityAtLevelLocal, trackAxisLocal);
			levelDirectionLocal = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref trackAxisLocal)).sqrMagnitude < 1E-06f || ((Vector3)(ref initialBubbleOffsetLocal)).sqrMagnitude < 1E-12f || ((Vector3)(ref levelDirectionLocal)).sqrMagnitude < 1E-06f)
			{
				Debug.LogWarning((object)"BubbleLevelMountTest disabled because its pivot geometry cannot define a gravity track.", (Object)(object)this);
				((Behaviour)this).enabled = false;
			}
		}

		private void FixedUpdate()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Behaviour)this).enabled || (Object)(object)level_bubble == (Object)null || (Object)(object)customPivot == (Object)null)
			{
				return;
			}
			Vector3 projectedGravityDirection = GetProjectedGravityDirection();
			float num = 0f;
			if (((Vector3)(ref projectedGravityDirection)).sqrMagnitude >= 1E-06f)
			{
				float num2 = SignedAngle(levelDirectionLocal, projectedGravityDirection, trackAxisLocal);
				num = Mathf.Clamp(0f - num2, minimumAngle, maximumAngle);
			}
			float num3 = num - bubbleAngle;
			if (Mathf.Abs(num3) <= staticFrictionAngle && Mathf.Abs(bubbleAngularVelocity) <= settleVelocity)
			{
				bubbleAngle = num;
				bubbleAngularVelocity = 0f;
			}
			else
			{
				float num4 = restoringAcceleration * num3 - fluidDrag * bubbleAngularVelocity;
				bubbleAngularVelocity = Mathf.Clamp(bubbleAngularVelocity + num4 * Time.fixedDeltaTime, 0f - maximumAngularVelocity, maximumAngularVelocity);
				float num5 = bubbleAngle + bubbleAngularVelocity * Time.fixedDeltaTime;
				if (num5 <= minimumAngle)
				{
					bubbleAngle = minimumAngle;
					if (bubbleAngularVelocity < 0f)
					{
						bubbleAngularVelocity = 0f;
					}
				}
				else if (num5 >= maximumAngle)
				{
					bubbleAngle = maximumAngle;
					if (bubbleAngularVelocity > 0f)
					{
						bubbleAngularVelocity = 0f;
					}
				}
				else
				{
					bubbleAngle = num5;
				}
			}
			ApplyBubblePose();
		}

		private Vector3 GetProjectedGravityDirection()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0054: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)customPivot == (Object)null) && !(((Vector3)(ref trackAxisLocal)).sqrMagnitude < 1E-06f))
			{
				Vector3 gravity = Physics.gravity;
				if (!(((Vector3)(ref gravity)).sqrMagnitude < 1E-06f))
				{
					Vector3 val = customPivot.InverseTransformDirection(Physics.gravity);
					Vector3 val2 = Vector3.ProjectOnPlane(val, trackAxisLocal);
					return (!(((Vector3)(ref val2)).sqrMagnitude < 1E-06f)) ? ((Vector3)(ref val2)).normalized : Vector3.zero;
				}
			}
			return Vector3.zero;
		}

		private void ApplyBubblePose()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_0024: 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)
			//IL_0030: 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_0050: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.AngleAxis(bubbleAngle, trackAxisLocal);
			level_bubble.transform.position = customPivot.TransformPoint(val * initialBubbleOffsetLocal);
			level_bubble.transform.rotation = customPivot.rotation * val * initialBubbleRotationLocal;
		}

		private static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Atan2(Vector3.Dot(axis, Vector3.Cross(from, to)), Vector3.Dot(from, to)) * 57.29578f;
		}
	}
	public class CosineMount : MonoBehaviour
	{
		[Header("Wheel")]
		public GameObject wheel = null;

		private void Start()
		{
		}

		private void FixedUpdate()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Vector3 eulerAngles = wheel.transform.eulerAngles;
			eulerAngles.x = -90f;
			wheel.transform.eulerAngles = eulerAngles;
		}
	}
}
namespace HLin_Mods.SharedBubble
{
	public static class GravityBubbleLevelMotion
	{
		public struct State
		{
			public float BubbleVelocity;

			public Transform BubbleTransform;

			public Transform MovementSpace;

			public Vector3 CachedGravity;

			public Vector3 CachedGravityDirection;

			public float CachedFullScaleAngle;

			public float CachedFullScaleGravity;

			public bool HasCachedGravityDirection;

			public bool HasCachedFullScaleGravity;

			public bool Initialized;
		}

		public static bool Initialize(GameObject baseObject, GameObject levelBubble, ref State state)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)baseObject == (Object)null || (Object)(object)levelBubble == (Object)null)
			{
				return false;
			}
			state.BubbleTransform = levelBubble.transform;
			state.MovementSpace = ((!((Object)(object)state.BubbleTransform.parent != (Object)null)) ? baseObject.transform : state.BubbleTransform.parent);
			RefreshGravityDirection(Physics.gravity, ref state);
			state.Initialized = (Object)(object)state.MovementSpace != (Object)null;
			return state.Initialized;
		}

		public static bool Step(GameObject baseObject, GameObject levelBubble, float centerLocalX, float minimumLocalX, float maximumLocalX, float fullScaleAngleDegrees, float restoringAcceleration, float fluidDrag, float staticFrictionDistance, float settleVelocity, float maximumVelocity, ref State state)
		{
			//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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_008b: 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_00b7: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if ((!state.Initialized || (Object)(object)state.BubbleTransform == (Object)null || (Object)(object)state.MovementSpace == (Object)null) && !Initialize(baseObject, levelBubble, ref state))
			{
				return false;
			}
			Vector3 gravity = Physics.gravity;
			if (state.HasCachedGravityDirection)
			{
				Vector3 val = gravity - state.CachedGravity;
				if (!(((Vector3)(ref val)).sqrMagnitude > 1E-06f))
				{
					goto IL_007f;
				}
			}
			RefreshGravityDirection(gravity, ref state);
			goto IL_007f;
			IL_007f:
			Vector3 right = state.MovementSpace.right;
			if (!state.HasCachedGravityDirection || ((Vector3)(ref right)).sqrMagnitude < 1E-06f)
			{
				return true;
			}
			float gravityAlongTravel = Mathf.Clamp(Vector3.Dot(state.CachedGravityDirection, right), -1f, 1f);
			float gravityTarget = GetGravityTarget(GetFullScaleTravel(gravityAlongTravel, fullScaleAngleDegrees, ref state), centerLocalX, minimumLocalX, maximumLocalX);
			Vector3 localPosition = state.BubbleTransform.localPosition;
			float num = gravityTarget - localPosition.x;
			if (Mathf.Abs(num) <= staticFrictionDistance && Mathf.Abs(state.BubbleVelocity) <= settleVelocity)
			{
				localPosition.x = gravityTarget;
				state.BubbleVelocity = 0f;
			}
			else
			{
				float num2 = restoringAcceleration * num - fluidDrag * state.BubbleVelocity;
				state.BubbleVelocity = Mathf.Clamp(state.BubbleVelocity + num2 * Time.fixedDeltaTime, 0f - maximumVelocity, maximumVelocity);
				float num3 = localPosition.x + state.BubbleVelocity * Time.fixedDeltaTime;
				if (num3 <= minimumLocalX)
				{
					localPosition.x = minimumLocalX;
					if (state.BubbleVelocity < 0f)
					{
						state.BubbleVelocity = 0f;
					}
				}
				else if (num3 >= maximumLocalX)
				{
					localPosition.x = maximumLocalX;
					if (state.BubbleVelocity > 0f)
					{
						state.BubbleVelocity = 0f;
					}
				}
				else
				{
					localPosition.x = num3;
				}
			}
			state.BubbleTransform.localPosition = localPosition;
			return true;
		}

		private static void RefreshGravityDirection(Vector3 gravity, ref State state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			state.CachedGravity = gravity;
			float sqrMagnitude = ((Vector3)(ref gravity)).sqrMagnitude;
			if (sqrMagnitude < 1E-06f)
			{
				state.CachedGravityDirection = Vector3.zero;
				state.HasCachedGravityDirection = false;
			}
			else
			{
				state.CachedGravityDirection = gravity / Mathf.Sqrt(sqrMagnitude);
				state.HasCachedGravityDirection = true;
			}
		}

		private static float GetGravityTarget(float gravityAlongTravel, float centerLocalX, float minimumLocalX, float maximumLocalX)
		{
			if (gravityAlongTravel >= 0f)
			{
				return centerLocalX - gravityAlongTravel * (centerLocalX - minimumLocalX);
			}
			return centerLocalX - gravityAlongTravel * (maximumLocalX - centerLocalX);
		}

		private static float GetFullScaleTravel(float gravityAlongTravel, float fullScaleAngleDegrees, ref State state)
		{
			float num = Mathf.Clamp(fullScaleAngleDegrees, 1f, 45f);
			if (!state.HasCachedFullScaleGravity || Mathf.Abs(state.CachedFullScaleAngle - num) > 0.0001f)
			{
				state.CachedFullScaleAngle = num;
				state.CachedFullScaleGravity = Mathf.Sin(num * ((float)Math.PI / 180f));
				state.HasCachedFullScaleGravity = true;
			}
			return Mathf.Clamp(gravityAlongTravel / state.CachedFullScaleGravity, -1f, 1f);
		}
	}
}
namespace HLin_Mods.BubbleLevelSet
{
	public abstract class GravityBubbleLevelController : MonoBehaviour
	{
		private GravityBubbleLevelMotion.State motionState;

		protected abstract GameObject BaseObject { get; }

		protected abstract GameObject LevelBubble { get; }

		protected abstract float CenterLocalX { get; }

		protected abstract float MinimumLocalX { get; }

		protected abstract float MaximumLocalX { get; }

		protected abstract float FullScaleAngleDegrees { get; }

		protected abstract float RestoringAcceleration { get; }

		protected abstract float FluidDrag { get; }

		protected abstract float StaticFrictionDistance { get; }

		protected abstract float SettleVelocity { get; }

		protected abstract float MaximumVelocity { get; }

		protected bool InitializeRuntimeState()
		{
			return GravityBubbleLevelMotion.Initialize(BaseObject, LevelBubble, ref motionState);
		}

		protected void StepController()
		{
			if (!GravityBubbleLevelMotion.Step(BaseObject, LevelBubble, CenterLocalX, MinimumLocalX, MaximumLocalX, FullScaleAngleDegrees, RestoringAcceleration, FluidDrag, StaticFrictionDistance, SettleVelocity, MaximumVelocity, ref motionState))
			{
				((Behaviour)this).enabled = false;
			}
		}
	}
}