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;
}
}
}
}