Decompiled source of ModulGlockarov v1.1.0

ModulGlockarov.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using ModularWorkshop;
using OpenScripts2;
using OtherLoader;
using Sodalite.Api;
using UnityEngine;
using UnityEngine.UI;

[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]
public class ForwardAssist : FVRInteractiveObject
{
	[Header("Animation Settings")]
	public Transform TargetTransform;

	public Vector3 StartPosition;

	public Vector3 EndPosition;

	public Vector3 StartRotation;

	public Vector3 EndRotation;

	public float MoveSpeed = 10f;

	public float ResetDelay = 0.2f;

	[Header("Audio Settings")]
	public AudioEvent PokeAudioEvent;

	public FVRPooledAudioType AudioType = (FVRPooledAudioType)0;

	private float m_animFloat = 0f;

	private bool m_isPoked = false;

	private float m_resetTimer = 0f;

	protected void Awake()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_006b: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)TargetTransform == (Object)null)
		{
			TargetTransform = ((Component)this).transform;
		}
		if (StartPosition == Vector3.zero)
		{
			StartPosition = TargetTransform.localPosition;
		}
		if (StartRotation == Vector3.zero)
		{
			StartRotation = TargetTransform.localEulerAngles;
		}
	}

	public override void Poke(FVRViveHand hand)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (PokeAudioEvent != null)
		{
			SM.PlayCoreSound(AudioType, PokeAudioEvent, ((Component)this).transform.position);
		}
		m_isPoked = true;
		m_resetTimer = ResetDelay;
	}

	private void Update()
	{
		//IL_009d: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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)
		if (m_isPoked)
		{
			m_animFloat = Mathf.MoveTowards(m_animFloat, 1f, Time.deltaTime * MoveSpeed);
			m_resetTimer -= Time.deltaTime;
			if (m_resetTimer <= 0f)
			{
				m_isPoked = false;
			}
		}
		else
		{
			m_animFloat = Mathf.MoveTowards(m_animFloat, 0f, Time.deltaTime * MoveSpeed);
		}
		if ((Object)(object)TargetTransform != (Object)null)
		{
			TargetTransform.localPosition = Vector3.Lerp(StartPosition, EndPosition, m_animFloat);
			TargetTransform.localEulerAngles = Vector3.Lerp(StartRotation, EndRotation, m_animFloat);
		}
	}
}
public class AudioConsistencyEnforcer : MonoBehaviour
{
	[Header("Audio Profiles")]
	public FVRFirearmAudioSet BaseHandlingAudioProfile;

	private FVRFireArm _firearm;

	private FVRFirearmAudioSet _lastAudioClipSet;

	private void Awake()
	{
		_firearm = ((Component)this).GetComponent<FVRFireArm>();
		if ((Object)(object)_firearm != (Object)null && (Object)(object)_firearm.AudioClipSet != (Object)null)
		{
			_lastAudioClipSet = _firearm.AudioClipSet;
			BaseHandlingAudioProfile = ScriptableObject.CreateInstance<FVRFirearmAudioSet>();
			SaveBaseHandlingAudio(_lastAudioClipSet);
		}
	}

	private void LateUpdate()
	{
		if ((Object)(object)_firearm == (Object)null)
		{
			return;
		}
		FVRFirearmAudioSet audioClipSet = _firearm.AudioClipSet;
		if (!((Object)(object)audioClipSet == (Object)null))
		{
			if ((Object)(object)audioClipSet != (Object)(object)_lastAudioClipSet)
			{
				_lastAudioClipSet = audioClipSet;
			}
			EnforceHandlingSounds(audioClipSet);
		}
	}

	private void SaveBaseHandlingAudio(FVRFirearmAudioSet source)
	{
		BaseHandlingAudioProfile.BoltRelease = source.BoltRelease;
		BaseHandlingAudioProfile.BoltSlideBack = source.BoltSlideBack;
		BaseHandlingAudioProfile.BoltSlideForward = source.BoltSlideForward;
		BaseHandlingAudioProfile.BoltSlideBackHeld = source.BoltSlideBackHeld;
		BaseHandlingAudioProfile.BoltSlideBackLocked = source.BoltSlideBackLocked;
		BaseHandlingAudioProfile.BreachOpen = source.BreachOpen;
		BaseHandlingAudioProfile.BreachClose = source.BreachClose;
		BaseHandlingAudioProfile.CatchOnSear = source.CatchOnSear;
		BaseHandlingAudioProfile.ChamberManual = source.ChamberManual;
		BaseHandlingAudioProfile.FireSelector = source.FireSelector;
		BaseHandlingAudioProfile.HammerHit = source.HammerHit;
		BaseHandlingAudioProfile.HandleBack = source.HandleBack;
		BaseHandlingAudioProfile.HandleBackEmpty = source.HandleBackEmpty;
		BaseHandlingAudioProfile.HandleForward = source.HandleForward;
		BaseHandlingAudioProfile.HandleForwardEmpty = source.HandleForwardEmpty;
		BaseHandlingAudioProfile.HandleUp = source.HandleUp;
		BaseHandlingAudioProfile.HandleDown = source.HandleDown;
		BaseHandlingAudioProfile.HandleGrab = source.HandleGrab;
		BaseHandlingAudioProfile.Prefire = source.Prefire;
		BaseHandlingAudioProfile.Safety = source.Safety;
		BaseHandlingAudioProfile.TriggerReset = source.TriggerReset;
		BaseHandlingAudioProfile.TopCoverRelease = source.TopCoverRelease;
		BaseHandlingAudioProfile.TopCoverUp = source.TopCoverUp;
		BaseHandlingAudioProfile.TopCoverDown = source.TopCoverDown;
		BaseHandlingAudioProfile.StockOpen = source.StockOpen;
		BaseHandlingAudioProfile.StockClosed = source.StockClosed;
		BaseHandlingAudioProfile.BipodOpen = source.BipodOpen;
		BaseHandlingAudioProfile.BipodClosed = source.BipodClosed;
		BaseHandlingAudioProfile.BeltGrab = source.BeltGrab;
		BaseHandlingAudioProfile.BeltRelease = source.BeltRelease;
		BaseHandlingAudioProfile.BeltSeat = source.BeltSeat;
		BaseHandlingAudioProfile.BeltSettle = source.BeltSettle;
	}

	private void EnforceHandlingSounds(FVRFirearmAudioSet targetProfile)
	{
		targetProfile.BoltRelease = BaseHandlingAudioProfile.BoltRelease;
		targetProfile.BoltSlideBack = BaseHandlingAudioProfile.BoltSlideBack;
		targetProfile.BoltSlideForward = BaseHandlingAudioProfile.BoltSlideForward;
		targetProfile.BoltSlideBackHeld = BaseHandlingAudioProfile.BoltSlideBackHeld;
		targetProfile.BoltSlideBackLocked = BaseHandlingAudioProfile.BoltSlideBackLocked;
		targetProfile.BreachOpen = BaseHandlingAudioProfile.BreachOpen;
		targetProfile.BreachClose = BaseHandlingAudioProfile.BreachClose;
		targetProfile.CatchOnSear = BaseHandlingAudioProfile.CatchOnSear;
		targetProfile.ChamberManual = BaseHandlingAudioProfile.ChamberManual;
		targetProfile.FireSelector = BaseHandlingAudioProfile.FireSelector;
		targetProfile.HammerHit = BaseHandlingAudioProfile.HammerHit;
		targetProfile.HandleBack = BaseHandlingAudioProfile.HandleBack;
		targetProfile.HandleBackEmpty = BaseHandlingAudioProfile.HandleBackEmpty;
		targetProfile.HandleForward = BaseHandlingAudioProfile.HandleForward;
		targetProfile.HandleForwardEmpty = BaseHandlingAudioProfile.HandleForwardEmpty;
		targetProfile.HandleUp = BaseHandlingAudioProfile.HandleUp;
		targetProfile.HandleDown = BaseHandlingAudioProfile.HandleDown;
		targetProfile.HandleGrab = BaseHandlingAudioProfile.HandleGrab;
		targetProfile.Prefire = BaseHandlingAudioProfile.Prefire;
		targetProfile.Safety = BaseHandlingAudioProfile.Safety;
		targetProfile.TriggerReset = BaseHandlingAudioProfile.TriggerReset;
		targetProfile.TopCoverRelease = BaseHandlingAudioProfile.TopCoverRelease;
		targetProfile.TopCoverUp = BaseHandlingAudioProfile.TopCoverUp;
		targetProfile.TopCoverDown = BaseHandlingAudioProfile.TopCoverDown;
		targetProfile.StockOpen = BaseHandlingAudioProfile.StockOpen;
		targetProfile.StockClosed = BaseHandlingAudioProfile.StockClosed;
		targetProfile.BipodOpen = BaseHandlingAudioProfile.BipodOpen;
		targetProfile.BipodClosed = BaseHandlingAudioProfile.BipodClosed;
		targetProfile.BeltGrab = BaseHandlingAudioProfile.BeltGrab;
		targetProfile.BeltRelease = BaseHandlingAudioProfile.BeltRelease;
		targetProfile.BeltSeat = BaseHandlingAudioProfile.BeltSeat;
		targetProfile.BeltSettle = BaseHandlingAudioProfile.BeltSettle;
	}
}
public class SecondaryMagSupport : ModularBarrelExtension
{
	[Header("Secondary Magazine Configuration")]
	public bool ChangesSecondaryMagazine = false;

	public FireArmMagazineType SecondaryMagazineType;

	public Transform CustomSecondaryMagMountPoint;

	public Transform CustomSecondaryMagEjectPoint;

	private FVRFireArm _firearm;

	private Transform _origSecMagMountPos;

	private Transform _origSecMagEjectPos;

	private FireArmMagazineType _origSecondaryMagazineType;

	private bool _hasCachedOriginals = false;

	public override void EnablePart()
	{
		((ModularBarrelExtension)this).EnablePart();
		if (UnityEngineExtensions.TryGetComponentInParent<FVRFireArm>((Component)(object)((Component)this).transform, ref _firearm) && ChangesSecondaryMagazine)
		{
			CacheOriginalSecondaryMagSettings(_firearm);
			UpdateSecondaryMagazine(_firearm);
		}
		else
		{
			Debug.LogWarning((object)"SecondaryMagSupport: Firearm not found or ChangesSecondaryMagazine is false!");
		}
	}

	public override void DisablePart()
	{
		((ModularBarrelExtension)this).DisablePart();
		if ((Object)(object)_firearm != (Object)null && ChangesSecondaryMagazine)
		{
			ResetSecondaryMagazine(_firearm);
		}
	}

	private void CacheOriginalSecondaryMagSettings(FVRFireArm firearm)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (!_hasCachedOriginals && firearm.SecondaryMagazineSlots.Length != 0)
		{
			_origSecMagMountPos = firearm.SecondaryMagazineSlots[0].MagazineMountPos;
			_origSecMagEjectPos = firearm.SecondaryMagazineSlots[0].MagazineEjectPos;
			if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null)
			{
				_origSecondaryMagazineType = firearm.SecondaryMagazineSlots[0].Magazine.MagazineType;
			}
			_hasCachedOriginals = true;
		}
	}

	private void UpdateSecondaryMagazine(FVRFireArm firearm)
	{
		//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)
		if (firearm.SecondaryMagazineSlots.Length != 0)
		{
			firearm.SecondaryMagazineSlots[0].MagazineMountPos = CustomSecondaryMagMountPoint;
			firearm.SecondaryMagazineSlots[0].MagazineEjectPos = CustomSecondaryMagEjectPoint;
			if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null)
			{
				firearm.SecondaryMagazineSlots[0].Magazine.MagazineType = SecondaryMagazineType;
			}
			Debug.Log((object)"SecondaryMagSupport: Secondary magazine settings updated.");
		}
	}

	private void ResetSecondaryMagazine(FVRFireArm firearm)
	{
		//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)
		if (_hasCachedOriginals && firearm.SecondaryMagazineSlots.Length != 0)
		{
			firearm.SecondaryMagazineSlots[0].MagazineMountPos = _origSecMagMountPos;
			firearm.SecondaryMagazineSlots[0].MagazineEjectPos = _origSecMagEjectPos;
			if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null)
			{
				firearm.SecondaryMagazineSlots[0].Magazine.MagazineType = _origSecondaryMagazineType;
			}
			Debug.Log((object)"SecondaryMagSupport: Secondary magazine settings reset.");
		}
	}
}
public class AdvanceTopCoverControl : FVRFireArmTopCover
{
	public enum HingeAxis
	{
		X,
		Y,
		Z
	}

	public enum LatchButtonInput
	{
		TouchpadOrJoystick,
		BYButton,
		AXButton,
		TriggerPress
	}

	[Header("Axis Configuration")]
	[Tooltip("Local axis around which the top cover rotates.")]
	public HingeAxis RotationHingeAxis = HingeAxis.X;

	[Header("Bolt Interlock")]
	[Tooltip("If true, the top cover cannot be opened fully unless the bolt is locked to the rear on OpenBoltReceiver firearms.")]
	public bool RequireBoltAtRearToMove = true;

	[Tooltip("Maximum angle (in degrees) the cover can move/jiggle when pulled while the bolt is forward.")]
	[Range(0f, 5f)]
	public float InterlockJiggleMaxAngle = 0.75f;

	[Tooltip("Optional sound played when pulling against the bolt interlock.")]
	public AudioEvent InterlockRattleSound;

	[Header("Latch Button Release")]
	[Tooltip("If true, opening the top cover from closed requires pressing a controller button on the grabbing hand to release the mechanical latch.")]
	public bool RequireLatchButtonToOpen = false;

	[Tooltip("Which controller input acts as the latch release button.")]
	public LatchButtonInput LatchReleaseButton = LatchButtonInput.TouchpadOrJoystick;

	[Tooltip("Maximum angle (in degrees) the cover can move/jiggle when pulled without pressing the latch release button.")]
	[Range(0f, 5f)]
	public float LatchJiggleMaxAngle = 0.5f;

	[Tooltip("Optional sound played when the latch release button is pressed to unlock the cover.")]
	public AudioEvent LatchUnlockSound;

	[Tooltip("Optional sound played when pulling the cover while the latch is still locked.")]
	public AudioEvent LatchRattleSound;

	[Header("Bump / Slap to Slam Down")]
	[Tooltip("If true, hitting or bumping the open/ajar top cover with your controller instantly slams it shut.")]
	public bool AllowBumpToSlam = true;

	[Tooltip("Minimum hand speed (in meters per second) required when bumping the cover to slam it shut. Set low for effortless slaps.")]
	public float BumpSlamVelocityThreshold = 0.3f;

	[Tooltip("Optional sound played when bumping the cover shut.")]
	public AudioEvent BumpSlamSound;

	[Header("Slam-Shut Misfeed")]
	[Tooltip("If true, closing the cover violently wastes the next round on the belt.")]
	public bool CanMisfeedOnSlam = true;

	[Tooltip("Hand speed, in meters per second, at the moment of closing above which a misfeed is triggered.")]
	public float SlamVelocityThreshold = 2.5f;

	[Tooltip("Optional sound played when a slammed cover causes a misfeed.")]
	public AudioEvent MisfeedSound;

	[Header("Gravity Physics")]
	[Tooltip("If false (default), cover uses stock H3 friction hold (stays where released). If true, dynamic gravity swinging is enabled.")]
	public bool UseGravityPhysics = false;

	[Tooltip("How fast, in degrees per second, the cover swings under gravity when UseGravityPhysics is enabled.")]
	public float GravitySettleSpeed = 60f;

	[Tooltip("Direction in cover's local space at 0 degrees pointing toward its center of mass.")]
	public Vector3 LocalMassOffsetAtClosed = Vector3.forward;

	[Header("Imperfect Latch")]
	[Range(0f, 1f)]
	[Tooltip("Chance that closing the cover leaves it resting slightly ajar instead of fully latched.")]
	public float MislatchChance = 0.15f;

	[Tooltip("The resting angle (in degrees) when imperfectly latched.")]
	public float MislatchRestAngle = 8f;

	[Header("Debugging")]
	public bool debug = false;

	private bool m_isImperfectlyLatched;

	private bool m_isLatchUnlocked;

	private bool m_hasPlayedInterlockRattle;

	private bool m_hasPlayedLatchRattle;

	private Vector3 m_initialLocalEuler;

	public override void Awake()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		m_initialLocalEuler = ((Component)this).transform.localEulerAngles;
	}

	private void Update()
	{
		//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_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_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_0089: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)base.FireArm == (Object)null || ((FVRInteractiveObject)this).IsHeld || !UseGravityPhysics || m_isImperfectlyLatched)
		{
			return;
		}
		float clampedAngle = GetClampedAngle();
		if (clampedAngle > 0.5f && clampedAngle < 89.5f)
		{
			Vector3 gravity = Physics.gravity;
			Vector3 normalized = ((Vector3)(ref gravity)).normalized;
			Vector3 val = TransformMassOffsetAtAngle(0f);
			Vector3 val2 = TransformMassOffsetAtAngle(90f);
			float num = Vector3.Dot(val, normalized);
			float num2 = Vector3.Dot(val2, normalized);
			float num3 = ((!(num > num2)) ? 90f : 0f);
			float num4 = Mathf.MoveTowards(clampedAngle, num3, GravitySettleSpeed * Time.deltaTime);
			if (num4 <= 0.01f)
			{
				SetAngle(0f);
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
				base.FireArm.IsTopCoverUp = false;
				m_isLatchUnlocked = false;
				RollForMislatch();
			}
			else if (num4 >= 89.99f)
			{
				SetAngle(90f);
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)23, 1f);
				base.FireArm.IsTopCoverUp = true;
			}
			else
			{
				SetAngle(num4);
			}
		}
	}

	public override void Poke(FVRViveHand hand)
	{
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Poke(hand);
		if ((Object)(object)hand == (Object)null || ((FVRInteractiveObject)this).IsHeld || !AllowBumpToSlam || ((!((Object)(object)base.FireArm != (Object)null) || !base.FireArm.IsTopCoverUp) && !m_isImperfectlyLatched && !(GetClampedAngle() > 1f)))
		{
			return;
		}
		float magnitude = ((Vector3)(ref hand.Input.VelLinearWorld)).magnitude;
		if (!(magnitude >= BumpSlamVelocityThreshold))
		{
			return;
		}
		m_isImperfectlyLatched = false;
		SetAngle(0f);
		if ((Object)(object)base.FireArm != (Object)null)
		{
			base.FireArm.IsTopCoverUp = false;
			base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
		}
		if (BumpSlamSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)10, BumpSlamSound, ((Component)this).transform.position);
		}
		if ((Object)(object)hand.Buzzer != (Object)null)
		{
			hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
		}
		if (CanMisfeedOnSlam && magnitude >= SlamVelocityThreshold && (Object)(object)base.FireArm != (Object)null && base.FireArm.HasBelt && (Object)(object)base.FireArm.BeltDD != (Object)null && base.FireArm.BeltDD.BeltRounds.Count > 0)
		{
			base.FireArm.BeltDD.RemoveRound(false);
			if (MisfeedSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, MisfeedSound, ((Component)this).transform.position);
			}
			if (debug)
			{
				Debug.Log((object)("AdvanceTopCoverControl: Bump slam caused misfeed at " + magnitude + " m/s."));
			}
		}
		RollForMislatch();
		if (!m_isImperfectlyLatched)
		{
			m_isLatchUnlocked = false;
		}
		if (debug)
		{
			Debug.Log((object)("AdvanceTopCoverControl: Bump slammed cover shut at " + magnitude + " m/s."));
		}
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		((FVRFireArmTopCover)this).BeginInteraction(hand);
		m_hasPlayedInterlockRattle = false;
		m_hasPlayedLatchRattle = false;
		float clampedAngle = GetClampedAngle();
		if (clampedAngle <= 1f && RequireLatchButtonToOpen)
		{
			if (IsLatchButtonPressed(hand))
			{
				m_isLatchUnlocked = true;
				if (LatchUnlockSound != null)
				{
					SM.PlayCoreSound((FVRPooledAudioType)10, LatchUnlockSound, ((Component)this).transform.position);
				}
				if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
				{
					hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
				}
			}
			else
			{
				m_isLatchUnlocked = false;
			}
		}
		else
		{
			m_isLatchUnlocked = true;
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Invalid comparison between Unknown and I4
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: 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 (RequireBoltAtRearToMove && base.FireArm is OpenBoltReceiver)
		{
			OpenBoltReceiver val = (OpenBoltReceiver)base.FireArm;
			if ((Object)(object)val.Bolt != (Object)null && (int)val.Bolt.CurPos != 4)
			{
				SetAngle(Mathf.Min(GetClampedAngle(), InterlockJiggleMaxAngle));
				if (!m_hasPlayedInterlockRattle)
				{
					if (InterlockRattleSound != null)
					{
						SM.PlayCoreSound((FVRPooledAudioType)10, InterlockRattleSound, ((Component)this).transform.position);
					}
					if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
					{
						hand.Buzz(hand.Buzzer.Buzz_OnHoverInteractive);
					}
					m_hasPlayedInterlockRattle = true;
				}
				return;
			}
		}
		if (RequireLatchButtonToOpen && !m_isLatchUnlocked)
		{
			if (!IsLatchButtonPressed(hand))
			{
				SetAngle(Mathf.Min(GetClampedAngle(), LatchJiggleMaxAngle));
				if (!m_hasPlayedLatchRattle)
				{
					if (LatchRattleSound != null)
					{
						SM.PlayCoreSound((FVRPooledAudioType)10, LatchRattleSound, ((Component)this).transform.position);
					}
					if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
					{
						hand.Buzz(hand.Buzzer.Buzz_OnHoverInteractive);
					}
					m_hasPlayedLatchRattle = true;
				}
				return;
			}
			m_isLatchUnlocked = true;
			if (LatchUnlockSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, LatchUnlockSound, ((Component)this).transform.position);
			}
			if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
			}
		}
		((FVRFireArmTopCover)this).UpdateInteraction(hand);
		float clampedAngle = GetClampedAngle();
		if (clampedAngle > 15f)
		{
			m_isLatchUnlocked = true;
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Invalid comparison between Unknown and I4
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		if (RequireBoltAtRearToMove && base.FireArm is OpenBoltReceiver)
		{
			OpenBoltReceiver val = (OpenBoltReceiver)base.FireArm;
			if ((Object)(object)val.Bolt != (Object)null && (int)val.Bolt.CurPos != 4)
			{
				flag = true;
			}
		}
		bool flag2 = RequireLatchButtonToOpen && !m_isLatchUnlocked;
		if (flag || flag2)
		{
			SetAngle(0f);
			if ((Object)(object)base.FireArm != (Object)null)
			{
				base.FireArm.IsTopCoverUp = false;
			}
			((FVRFireArmTopCover)this).EndInteraction(hand);
			return;
		}
		float num = ((!((Object)(object)hand != (Object)null)) ? 0f : ((Vector3)(ref hand.Input.VelLinearWorld)).magnitude);
		float clampedAngle = GetClampedAngle();
		bool flag3 = (Object)(object)base.FireArm != (Object)null && base.FireArm.IsTopCoverUp;
		((FVRFireArmTopCover)this).EndInteraction(hand);
		if (flag3 && (clampedAngle <= 20f || num >= 0.5f))
		{
			SetAngle(0f);
			if ((Object)(object)base.FireArm != (Object)null)
			{
				base.FireArm.IsTopCoverUp = false;
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
			}
		}
		if (!((Object)(object)base.FireArm != (Object)null) || !flag3 || base.FireArm.IsTopCoverUp)
		{
			return;
		}
		if (CanMisfeedOnSlam && num >= SlamVelocityThreshold && base.FireArm.HasBelt && (Object)(object)base.FireArm.BeltDD != (Object)null && base.FireArm.BeltDD.BeltRounds.Count > 0)
		{
			base.FireArm.BeltDD.RemoveRound(false);
			if (MisfeedSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, MisfeedSound, ((Component)this).transform.position);
			}
			if (debug)
			{
				Debug.Log((object)("AdvanceTopCoverControl: Slammed shut at " + num + " m/s - misfed a round."));
			}
		}
		RollForMislatch();
		if (!m_isImperfectlyLatched)
		{
			m_isLatchUnlocked = false;
		}
	}

	private void RollForMislatch()
	{
		if (MislatchChance > 0f && Random.value < MislatchChance)
		{
			m_isImperfectlyLatched = true;
			SetAngle(MislatchRestAngle);
			if ((Object)(object)base.FireArm != (Object)null)
			{
				base.FireArm.IsTopCoverUp = true;
			}
			if (debug)
			{
				Debug.Log((object)"AdvanceTopCoverControl: Cover did not latch fully.");
			}
		}
		else
		{
			m_isImperfectlyLatched = false;
		}
	}

	private bool IsLatchButtonPressed(FVRViveHand hand)
	{
		if ((Object)(object)hand == (Object)null)
		{
			return false;
		}
		return LatchReleaseButton switch
		{
			LatchButtonInput.TouchpadOrJoystick => hand.Input.TouchpadDown || hand.Input.TouchpadPressed || hand.Input.Secondary2AxisNorthDown || hand.Input.Secondary2AxisCenterDown, 
			LatchButtonInput.BYButton => hand.Input.BYButtonDown || hand.Input.BYButtonPressed, 
			LatchButtonInput.AXButton => hand.Input.AXButtonDown || hand.Input.AXButtonPressed, 
			LatchButtonInput.TriggerPress => hand.Input.TriggerDown || hand.Input.TriggerPressed, 
			_ => false, 
		};
	}

	private float GetClampedAngle()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_005f: 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)
		float num = 0f;
		switch (RotationHingeAxis)
		{
		case HingeAxis.X:
			num = ((Component)this).transform.localEulerAngles.x;
			break;
		case HingeAxis.Y:
			num = ((Component)this).transform.localEulerAngles.y;
			break;
		case HingeAxis.Z:
			num = ((Component)this).transform.localEulerAngles.z;
			break;
		}
		if (num > 180f)
		{
			num -= 360f;
		}
		return Mathf.Clamp(num, 0f, 90f);
	}

	private void SetAngle(float angle)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		Vector3 initialLocalEuler = m_initialLocalEuler;
		switch (RotationHingeAxis)
		{
		case HingeAxis.X:
			initialLocalEuler.x = angle;
			break;
		case HingeAxis.Y:
			initialLocalEuler.y = angle;
			break;
		case HingeAxis.Z:
			initialLocalEuler.z = angle;
			break;
		}
		((Component)this).transform.localEulerAngles = initialLocalEuler;
	}

	private Vector3 TransformMassOffsetAtAngle(float angle)
	{
		//IL_0001: 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_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_0049: 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_004f: 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_0052: 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)
		//IL_0032: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: 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)
		Vector3 val = Vector3.right;
		switch (RotationHingeAxis)
		{
		case HingeAxis.X:
			val = Vector3.right;
			break;
		case HingeAxis.Y:
			val = Vector3.up;
			break;
		case HingeAxis.Z:
			val = Vector3.forward;
			break;
		}
		Quaternion val2 = Quaternion.AngleAxis(angle, val);
		Vector3 val3 = val2 * LocalMassOffsetAtClosed;
		if ((Object)(object)((Component)this).transform.parent != (Object)null)
		{
			return ((Component)this).transform.parent.TransformDirection(val3);
		}
		return val3;
	}
}
public class ObservedObjectEnabler : MonoBehaviour
{
	[Header("Observed Target")]
	[Tooltip("The GameObject mesh or joint to observe.")]
	public Transform ObservedObject;

	[Header("Tracking Mode")]
	public bool ObservePosition = false;

	public bool ObserveRotation = true;

	[Header("Target Values")]
	[Tooltip("The local position target to reach.")]
	public Vector3 TargetPosition = Vector3.zero;

	[Tooltip("The local rotation target to reach (Euler angles).")]
	public Vector3 TargetRotation = new Vector3(90f, 0f, 0f);

	[Header("Tolerance Settings")]
	[Tooltip("Distance in meters to consider the position reached.")]
	public float DistanceTolerance = 0.05f;

	[Tooltip("Angle in degrees to consider the rotation reached.")]
	public float AngleTolerance = 1f;

	[Header("Trigger Actions")]
	[Tooltip("The GameObject to enable or disable when the target is reached.")]
	public GameObject TargetObject;

	[Tooltip("Should the TargetObject be set Active (true) or Inactive (false) when reached?")]
	public bool SetObjectActiveOnReach = true;

	[Tooltip("The Collider to enable or disable when the target is reached.")]
	public Collider TargetCollider;

	[Tooltip("Should the TargetCollider be set Enabled (true) or Disabled (false) when reached?")]
	public bool SetColliderEnabledOnReach = true;

	[Header("Behavior Settings")]
	[Tooltip("If true, the target object/collider will revert to their opposite state when the observed object moves away from the target values.")]
	public bool ResetWhenLeavingTarget = true;

	private bool m_isTargetReached = false;

	private bool m_hasTriggered = false;

	private void Update()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_0063: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ObservedObject == (Object)null)
		{
			return;
		}
		bool flag = true;
		bool flag2 = true;
		if (ObservePosition)
		{
			float num = Vector3.Distance(ObservedObject.localPosition, TargetPosition);
			flag = num <= DistanceTolerance;
		}
		if (ObserveRotation)
		{
			Quaternion localRotation = ObservedObject.localRotation;
			Quaternion val = Quaternion.Euler(TargetRotation);
			float num2 = Quaternion.Angle(localRotation, val);
			flag2 = num2 <= AngleTolerance;
		}
		bool flag3 = true;
		if (ObservePosition && !flag)
		{
			flag3 = false;
		}
		if (ObserveRotation && !flag2)
		{
			flag3 = false;
		}
		if (flag3)
		{
			if (!m_isTargetReached)
			{
				m_isTargetReached = true;
				if (!m_hasTriggered || ResetWhenLeavingTarget)
				{
					ApplyTriggerState(targetReached: true);
					m_hasTriggered = true;
				}
			}
		}
		else if (m_isTargetReached)
		{
			m_isTargetReached = false;
			if (ResetWhenLeavingTarget)
			{
				ApplyTriggerState(targetReached: false);
				m_hasTriggered = false;
			}
		}
	}

	private void ApplyTriggerState(bool targetReached)
	{
		if ((Object)(object)TargetObject != (Object)null)
		{
			bool active = ((!targetReached) ? (!SetObjectActiveOnReach) : SetObjectActiveOnReach);
			TargetObject.SetActive(active);
		}
		if ((Object)(object)TargetCollider != (Object)null)
		{
			bool enabled = ((!targetReached) ? (!SetColliderEnabledOnReach) : SetColliderEnabledOnReach);
			TargetCollider.enabled = enabled;
		}
	}
}
public class HeatEffectToggleObject : FirearmHeatingEffect
{
	[Header("Explosion Spawn")]
	public GameObject PrefabToSpawn;

	public Transform SpawnPoint;

	public float ToggleHeatThreshold = 0.95f;

	private bool hasSpawned = false;

	public void Update()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		((FirearmHeatingEffect)this).Update();
		if (hasSpawned || !(base.Heat >= ToggleHeatThreshold))
		{
			return;
		}
		if ((Object)(object)PrefabToSpawn != (Object)null)
		{
			if ((Object)(object)SpawnPoint != (Object)null)
			{
				Object.Instantiate<GameObject>(PrefabToSpawn, SpawnPoint.position, SpawnPoint.rotation);
			}
			else
			{
				Object.Instantiate<GameObject>(PrefabToSpawn, ((Component)this).transform.position, ((Component)this).transform.rotation);
			}
		}
		hasSpawned = true;
	}
}
public class MGBarrel : MuzzleDevice
{
	[Header("MGBarrel Lock Settings")]
	public float CatchRot;

	public bool IsLocked = false;

	public AudioSource AudSourceLock;

	public AudioClip AudClipLock;

	public Vector3 LockedLocalPosition;

	public Vector3 LockedLocalEulerAngles;

	public float LockAngle = 90f;

	public bool HasPlayedLockSound = false;

	[Header("Loose Barrel Settings")]
	public int ShotsUntilFallOff = 3;

	[HideInInspector]
	public int ShotsFiredWhileLoose = 0;

	protected void Awake()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		((MuzzleDevice)this).Awake();
		((FVRFireArmAttachment)this).Type = (FVRFireArmAttachementMountType)2;
	}

	public override void AttachToMount(FVRFireArmAttachmentMount m, bool playSound)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		((FVRFireArmAttachment)this).AttachToMount(m, playSound);
		((Component)this).transform.localEulerAngles = new Vector3(0f, 0f, CatchRot);
	}

	public override void OnShot(FVRFireArm f, FVRTailSoundClass tailClass)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (!IsLocked && (Object)(object)((FVRFireArmAttachment)this).curMount != (Object)null)
		{
			ShotsFiredWhileLoose++;
			if (ShotsFiredWhileLoose >= ShotsUntilFallOff)
			{
				((FVRFireArmAttachment)this).DetachFromMount();
			}
		}
		else
		{
			ShotsFiredWhileLoose = 0;
		}
		((MuzzleDevice)this).OnShot(f, tailClass);
	}
}
public class MGBarrelInterface : MuzzleDeviceInterface
{
	private MGBarrel tempBarrel;

	private Vector3 lastHandForward = Vector3.zero;

	private Vector3 lastMountForward = Vector3.zero;

	public AudioClip AudClipUnlock;

	public AudioSource AudSourceUnlock;

	private const float lockThreshold = 2f;

	private const float unlockThreshold = 2f;

	private float lockCooldownTime = 0f;

	private float lockCooldownTimer = 0f;

	public float LockSnapBuffer = 3f;

	public float LockedPreventDetachTime = 0.35f;

	private float lockedGraceTimer = 0f;

	public float UnlockAllowDetachTime = 0.5f;

	private float canBePulledTimer = 0f;

	private Vector3 mountedLocalPosition = Vector3.zero;

	private bool mountedLocalPositionRecorded = false;

	public float DetachDistanceThreshold = 0.08f;

	private bool m_isInSnappingMode = false;

	private bool hasPlayedUnlockSoundThisUnlock = false;

	public float IgnoreDetachOnGrabTime = 0.12f;

	private float ignoreDetachTimer = 0f;

	public override void Awake()
	{
		((FVRFireArmAttachmentInterface)this).Awake();
		tempBarrel = ((FVRFireArmAttachmentInterface)this).Attachment as MGBarrel;
	}

	public override void OnAttach()
	{
		//IL_0036: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: 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)
		((MuzzleDeviceInterface)this).OnAttach();
		tempBarrel = ((FVRFireArmAttachmentInterface)this).Attachment as MGBarrel;
		if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null)
		{
			mountedLocalPosition = ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition;
			mountedLocalPositionRecorded = true;
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, (!((Object)(object)tempBarrel != (Object)null)) ? 0f : tempBarrel.CatchRot);
		}
		if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null && ((FVRInteractiveObject)this).IsHeld && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)
		{
			SetSnapping(b: true);
			lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up;
			lastMountForward = ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up;
			lockCooldownTimer = 0f;
			lockedGraceTimer = 0f;
			canBePulledTimer = 0f;
			hasPlayedUnlockSoundThisUnlock = false;
			TryLockImmediateOnAttach();
		}
	}

	private void TryLockImmediateOnAttach()
	{
		if ((Object)(object)tempBarrel == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount == (Object)null)
		{
			return;
		}
		float lockAngle = tempBarrel.LockAngle;
		float num = 2f + LockSnapBuffer;
		if (tempBarrel.IsLocked)
		{
			return;
		}
		if (lockAngle >= 0f)
		{
			if (tempBarrel.CatchRot >= lockAngle - num)
			{
				DoLock(lockAngle);
			}
		}
		else if (tempBarrel.CatchRot <= lockAngle + num)
		{
			DoLock(lockAngle);
		}
	}

	private void DoLock(float target)
	{
		//IL_0080: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		tempBarrel.CatchRot = target;
		tempBarrel.IsLocked = true;
		lockedGraceTimer = LockedPreventDetachTime;
		lockCooldownTimer = lockCooldownTime;
		if (mountedLocalPositionRecorded)
		{
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition + tempBarrel.LockedLocalPosition;
		}
		else
		{
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition + tempBarrel.LockedLocalPosition;
		}
		((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, target);
		if (!tempBarrel.HasPlayedLockSound && (Object)(object)tempBarrel.AudSourceLock != (Object)null && (Object)(object)tempBarrel.AudClipLock != (Object)null)
		{
			tempBarrel.AudSourceLock.PlayOneShot(tempBarrel.AudClipLock);
			tempBarrel.HasPlayedLockSound = true;
		}
		canBePulledTimer = 0f;
		hasPlayedUnlockSoundThisUnlock = false;
	}

	private void DoUnlock()
	{
		//IL_0043: 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)
		tempBarrel.IsLocked = false;
		tempBarrel.HasPlayedLockSound = false;
		tempBarrel.CatchRot = 0f;
		((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, 0f);
		if (mountedLocalPositionRecorded)
		{
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition;
		}
		canBePulledTimer = UnlockAllowDetachTime;
		if (!hasPlayedUnlockSoundThisUnlock && (Object)(object)AudSourceUnlock != (Object)null && (Object)(object)AudClipUnlock != (Object)null)
		{
			AudSourceUnlock.PlayOneShot(AudClipUnlock);
			hasPlayedUnlockSoundThisUnlock = true;
		}
	}

	public override void OnDetach()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)tempBarrel != (Object)null && mountedLocalPositionRecorded && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null)
		{
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition;
		}
		if ((Object)(object)tempBarrel != (Object)null)
		{
			tempBarrel.IsLocked = false;
			tempBarrel.HasPlayedLockSound = false;
			tempBarrel.CatchRot = 0f;
		}
		((MuzzleDeviceInterface)this).OnDetach();
		mountedLocalPositionRecorded = false;
		canBePulledTimer = 0f;
		hasPlayedUnlockSoundThisUnlock = false;
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).BeginInteraction(hand);
		lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up;
		lastMountForward = ((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? Vector3.up : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up);
		lockCooldownTimer = 0f;
		lockedGraceTimer = 0f;
		canBePulledTimer = 0f;
		hasPlayedUnlockSoundThisUnlock = false;
		ignoreDetachTimer = IgnoreDetachOnGrabTime;
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		((FVRFireArmAttachmentInterface)this).UpdateInteraction(hand);
		if (lockedGraceTimer > 0f)
		{
			lockedGraceTimer -= Time.deltaTime;
			if (lockedGraceTimer < 0f)
			{
				lockedGraceTimer = 0f;
			}
		}
		if (lockCooldownTimer > 0f)
		{
			lockCooldownTimer -= Time.deltaTime;
			if (lockCooldownTimer < 0f)
			{
				lockCooldownTimer = 0f;
			}
		}
		if (canBePulledTimer > 0f)
		{
			canBePulledTimer -= Time.deltaTime;
			if (canBePulledTimer <= 0f)
			{
				canBePulledTimer = 0f;
			}
		}
		if (ignoreDetachTimer > 0f)
		{
			ignoreDetachTimer -= Time.deltaTime;
			if (ignoreDetachTimer < 0f)
			{
				ignoreDetachTimer = 0f;
			}
		}
		UpdateSnappingBasedOnDistance();
		if (((FVRInteractiveObject)this).IsHeld && (Object)(object)tempBarrel != (Object)null)
		{
			((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, tempBarrel.CatchRot);
		}
		if ((Object)(object)tempBarrel == (Object)null)
		{
			return;
		}
		float lockAngle = tempBarrel.LockAngle;
		float num = 2f + LockSnapBuffer;
		if (!tempBarrel.IsLocked)
		{
			if (lockAngle >= 0f)
			{
				if (tempBarrel.CatchRot >= lockAngle - num)
				{
					DoLock(lockAngle);
				}
			}
			else if (tempBarrel.CatchRot <= lockAngle + num)
			{
				DoLock(lockAngle);
			}
		}
		else if (Mathf.Abs(tempBarrel.CatchRot) <= 2f && lockedGraceTimer <= 0f)
		{
			DoUnlock();
		}
		if (tempBarrel.IsLocked || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null))
		{
			return;
		}
		FVRFireArmAttachmentMount rootMount = ((FVRFireArmAttachmentInterface)this).Attachment.curMount.GetRootMount();
		Transform val = ((!((Object)(object)rootMount != (Object)null) || !(rootMount.MyObject is FVRFireArm)) ? null : ((FVRFireArm)rootMount.MyObject).MuzzlePos);
		if (!((Object)(object)val != (Object)null))
		{
			return;
		}
		Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Front.position, val.position, ((Component)this).transform.position);
		float num2 = Vector3.Distance(((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Pos, closestValidPoint);
		if (canBePulledTimer > 0f)
		{
			if (num2 > DetachDistanceThreshold)
			{
				canBePulledTimer = 0f;
				((FVRInteractiveObject)this).EndInteraction(hand);
				hand.ForceSetInteractable((FVRInteractiveObject)(object)((FVRFireArmAttachmentInterface)this).Attachment);
				((FVRInteractiveObject)((FVRFireArmAttachmentInterface)this).Attachment).BeginInteraction(hand);
			}
		}
		else if (ignoreDetachTimer <= 0f && num2 > DetachDistanceThreshold)
		{
			((FVRInteractiveObject)this).EndInteraction(hand);
			hand.ForceSetInteractable((FVRInteractiveObject)(object)((FVRFireArmAttachmentInterface)this).Attachment);
			((FVRInteractiveObject)((FVRFireArmAttachmentInterface)this).Attachment).BeginInteraction(hand);
		}
	}

	public override void FVRFixedUpdate()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//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_0075: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: 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_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)tempBarrel == (Object)null)
		{
			((FVRInteractiveObject)this).FVRFixedUpdate();
			return;
		}
		if (((FVRInteractiveObject)this).IsHeld && m_isInSnappingMode && lockCooldownTimer <= 0f && lockedGraceTimer <= 0f)
		{
			Vector3 val = Vector3.ProjectOnPlane(((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up, ((Component)this).transform.forward);
			Vector3 val2 = Vector3.ProjectOnPlane(lastHandForward, ((Component)this).transform.forward);
			float num = Mathf.Atan2(Vector3.Dot(((Component)this).transform.forward, Vector3.Cross(val, val2)), Vector3.Dot(val, val2)) * 57.29578f;
			Vector3 val3 = Vector3.ProjectOnPlane((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? Vector3.up : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up, ((Component)this).transform.forward);
			Vector3 val4 = Vector3.ProjectOnPlane(lastMountForward, ((Component)this).transform.forward);
			float num2 = Mathf.Atan2(Vector3.Dot(((Component)this).transform.forward, Vector3.Cross(val3, val4)), Vector3.Dot(val3, val4)) * 57.29578f;
			tempBarrel.CatchRot -= num;
			tempBarrel.CatchRot += num2;
			float lockAngle = tempBarrel.LockAngle;
			float num3 = Mathf.Min(0f, lockAngle);
			float num4 = Mathf.Max(0f, lockAngle);
			tempBarrel.CatchRot = Mathf.Clamp(tempBarrel.CatchRot, num3, num4);
			lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up;
			lastMountForward = ((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? lastMountForward : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up);
		}
		((FVRInteractiveObject)this).FVRFixedUpdate();
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		if (!tempBarrel.IsLocked && Mathf.Abs(tempBarrel.CatchRot) <= 2f && lockedGraceTimer <= 0f)
		{
			((FVRInteractiveObject)this).EndInteraction(hand);
		}
	}

	private void UpdateSnappingBasedOnDistance()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount == (Object)null)
		{
			SetSnapping(b: false);
			return;
		}
		if (((FVRInteractiveObject)this).IsHeld)
		{
			SetSnapping(b: true);
			return;
		}
		Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Front.position, ((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Rear.position, ((Component)this).transform.position);
		if (Vector3.Distance(closestValidPoint, ((Component)this).transform.position) < DetachDistanceThreshold || ((Object)(object)tempBarrel != (Object)null && Mathf.Abs(tempBarrel.CatchRot) > 1f))
		{
			SetSnapping(b: true);
		}
		else
		{
			SetSnapping(b: false);
		}
	}

	private void SetSnapping(bool b)
	{
		//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_0093: 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)
		if (m_isInSnappingMode == b)
		{
			return;
		}
		m_isInSnappingMode = b;
		if (m_isInSnappingMode)
		{
			((FVRInteractiveObject)this).SetAllCollidersToLayer(false, "NoCol");
			if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
			{
				lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up;
			}
			if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)
			{
				lastMountForward = ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up;
			}
		}
		else
		{
			((FVRInteractiveObject)this).SetAllCollidersToLayer(false, "Default");
		}
	}
}
namespace Volks.ModulGlockarov;

[BepInPlugin("Volks.ModulGlockarov", "ModulGlockarov", "1.1.0")]
[BepInProcess("h3vr.exe")]
[Description("Built with MeatKit")]
[BepInDependency("h3vr.cityrobo.ModularWorkshopManager", "1.0.0")]
[BepInDependency("nrgill28.Sodalite", "1.4.1")]
[BepInDependency("h3vr.otherloader", "1.3.0")]
public class ModulGlockarovPlugin : 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(), "Volks.ModulGlockarov");
		GameAPI.PreloadAllAssets(Path.Combine(BasePath, "mw_modulglockarov"));
		OtherLoader.RegisterDirectLoad(BasePath, "Volks.ModulGlockarov", "", "", "modulglockarov", "");
	}
}
[RequireComponent(typeof(FVRFireArmMagazine))]
public class BeltMagazinePhysics : MonoBehaviour
{
	[Header("Debugging")]
	public bool EnableDebug = false;

	[Header("Compatibility")]
	public bool BypassTypeMatching = false;

	public FireArmMagazineType[] CompatibleMagazineTypes;

	[Header("Loading Controls")]
	[Tooltip("Disable magazine reload triggers on Awake. Keep false for standard M249 box/drum magazines so they can mount.")]
	public bool DisableNativeReloadTriggers = false;

	[Header("Visual Container")]
	[Tooltip("The actual child Transform inside the magazine prefab that represents the visual belt.")]
	public Transform VisualBeltContainer;

	[Header("Belt Chain")]
	[Tooltip("The point where the belt exits the magazine when not loaded.")]
	public Transform BeltExitPoint;

	[Tooltip("Number of physics nodes rigidly locked along the anchor exit axis before free simulation begins.")]
	public int PinnedNodes = 1;

	[Tooltip("Total number of simulation nodes in the chain.")]
	public int ChainNodeCount = 32;

	[Tooltip("Distance between each chain node in metres.")]
	public float NodeDistance = 0.02f;

	[Tooltip("Velocity damping per frame when not loaded in mid-air.")]
	[Range(0f, 1f)]
	public float Damping = 0.95f;

	[Tooltip("Gravity scale applied to chain nodes.")]
	public float GravityScale = 1f;

	[Tooltip("Number of constraint solving iterations per frame.")]
	public int ConstraintIterations = 3;

	[Header("Surface Rest and Jitter Control")]
	[Range(0f, 1f)]
	[Tooltip("How much velocity is absorbed when resting on a floor/surface. Higher values (0.8 - 0.95) completely eliminate surface jitter.")]
	public float SurfaceFriction = 0.85f;

	[Tooltip("Minimum movement threshold below which resting nodes sleep to prevent micro-vibrations.")]
	public float FloorSleepVelocityThreshold = 0.002f;

	[Header("Hand Physics and Haptics")]
	[Tooltip("If true, the player hands can physically push and deflect the hanging belt.")]
	public bool EnableHandInteraction = true;

	[Tooltip("Physical radius of the player palm collision sphere.")]
	public float HandInteractionRadius = 0.055f;

	[Tooltip("If true, provides subtle haptic rumble to the hand when pushing the belt.")]
	public bool EnableHandHaptics = true;

	[Header("Gun Self-Collision")]
	[Tooltip("If true, the hanging belt will physically bump and collide against its own firearm body.")]
	public bool CollideWithOwnGun = true;

	[Tooltip("Number of nodes near the top feed tray that ignore gun collision so the belt does not snag on the feed lip.")]
	public int SkipGunCollisionNodeCount = 2;

	[Header("Loaded Physics Override")]
	[Range(0f, 1f)]
	[Tooltip("How rigid the belt becomes when loaded into the gun.")]
	public float LoadedRigidity = 0f;

	[Range(0f, 1f)]
	[Tooltip("Damping applied strictly when the belt is loaded into the gun.")]
	public float LoadedDamping = 0.9f;

	[Header("Bending Stiffness")]
	[Range(0f, 1f)]
	[Tooltip("How strongly the belt resists folding at each joint. 0 = fully floppy rope, 1 = nearly rigid straight line.")]
	public float BendingStiffness = 0f;

	[Header("Pin Transition Smoothing")]
	[Tooltip("How many free nodes right after the pinned section get extra straightening toward the pinned direction.")]
	public int PinTransitionNodeCount = 3;

	[Range(0f, 1f)]
	[Tooltip("Strength of the pin transition pull on the first free node, easing to zero by the end of Pin Transition Node Count.")]
	public float PinTransitionRigidity = 0.5f;

	[Header("Bullet Orientation and Constraints")]
	[Tooltip("Base Euler rotation offset applied to flat bullets sitting on the gun feed tray.")]
	public Vector3 FeedTrayRotationOffset = Vector3.zero;

	[Tooltip("Optional: per-bullet Euler rotation offsets for each bullet pinned to the feed tray.")]
	public Vector3[] FeedTrayPerBulletRotationOffsets;

	[Tooltip("Euler rotation offset applied strictly to the dangling/simulated bullets hanging down.")]
	public Vector3 HangingRotationOffset = Vector3.zero;

	[Tooltip("The name of the child GameObject inside your bullet prefab representing the metal link (case-insensitive).")]
	public string LinkChildName = "link";

	public bool ReverseBulletOrder = false;

	public bool ReverseBeltDirection = false;

	[Header("Snapped Feed Tray Rounds")]
	[Tooltip("How many bullets sit rigidly flat on the gun top feed tray cover before the belt hangs down dynamically.")]
	public int SnappedFeedTrayRounds = 4;

	[Header("Loading")]
	[Tooltip("Detection radius around BeltExitPoint for feed tray detection.")]
	public float LoadDetectionRadius = 0.12f;

	[Tooltip("After ejecting or removing the belt, how many seconds to wait before it can be loaded again.")]
	public float ReinsertCooldown = 1f;

	[Header("Collision and Physics Layers")]
	[Tooltip("Layers the belt chain will physically collide and raycast against.")]
	public LayerMask CollisionLayerMask;

	[Tooltip("If true, chain nodes will push out of solid objects in CollisionLayerMask in full 3D.")]
	public bool EnableNodeCollision = true;

	[Tooltip("Collision radius around each chain node.")]
	public float NodeCollisionRadius = 0.012f;

	public float MaxFloorRaycastDistance = 2f;

	public float FloorOffset = 0.015f;

	public Vector3 LoadedExitDirection = new Vector3(-1f, 0f, 0f);

	public Vector3 UnloadedExitDirection = new Vector3(0f, -1f, 0f);

	private const float SqrMagnitudeEpsilon = 0.0001f;

	private FVRFireArmMagazine _magazine;

	private Vector3[] _positions;

	private Vector3[] _prevPositions;

	private Transform[] _cachedLinkTransforms;

	private Vector3[] _originalLinkLocalPositions;

	private Quaternion[] _originalLinkLocalRotations;

	private bool _chainInitialized = false;

	private bool _wasLoadedLastFrame = false;

	private FVRFireArm _lastLoadedFireArm = null;

	private float _cooldownTimer = 0f;

	private bool _originalIsBeltBox;

	private bool _originalCanBeTornOut;

	private bool _isBeingDestroyed = false;

	private float _currentFloorY = -100f;

	private int _floorScanThrottle = 0;

	private int _scanFrameThrottle = 0;

	private float _leftHandHapticCooldown = 0f;

	private float _rightHandHapticCooldown = 0f;

	private readonly Collider[] _overlapResults = (Collider[])(object)new Collider[32];

	private readonly Collider[] _nodeCollisionBuffer = (Collider[])(object)new Collider[32];

	private readonly RaycastHit[] _floorHitBuffer = (RaycastHit[])(object)new RaycastHit[16];

	private readonly List<Renderer> _cachedGunRenderers = new List<Renderer>();

	private readonly List<Collider> _cachedMagColliders = new List<Collider>();

	private readonly List<Collider> _cachedVisualBeltColliders = new List<Collider>();

	private FVRFireArmReloadTriggerMag[] _nativeTriggers;

	private bool[] _originalTriggerStates;

	private bool[] _originalColliderStates;

	private bool _originalHidesDisplayBullets;

	private FVRFireArm _lastScannedFireArm = null;

	private FVRFireArmReloadTriggerWell[] _cachedTriggerWells;

	private bool _lastCoverState = true;

	private bool _collidersCached = false;

	private void Awake()
	{
		//IL_002d: 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)
		_magazine = ((Component)this).GetComponent<FVRFireArmMagazine>();
		if ((Object)(object)_magazine == (Object)null)
		{
			_magazine = ((Component)this).GetComponentInParent<FVRFireArmMagazine>();
		}
		if (LayerMask.op_Implicit(CollisionLayerMask) == 0)
		{
			CollisionLayerMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Default", "Interactable", "Environment" }));
		}
		if ((Object)(object)_magazine != (Object)null)
		{
			_originalHidesDisplayBullets = _magazine.HidesAllDisplayBulletsWhenGrabbed;
			_originalIsBeltBox = _magazine.IsBeltBox;
			_originalCanBeTornOut = _magazine.CanBeTornOut;
			_magazine.HidesAllDisplayBulletsWhenGrabbed = false;
		}
		_nativeTriggers = ((Component)this).GetComponentsInChildren<FVRFireArmReloadTriggerMag>(true);
		_originalTriggerStates = new bool[_nativeTriggers.Length];
		_originalColliderStates = new bool[_nativeTriggers.Length];
		for (int i = 0; i < _nativeTriggers.Length; i++)
		{
			if (!((Object)(object)_nativeTriggers[i] == (Object)null))
			{
				_originalTriggerStates[i] = ((Behaviour)_nativeTriggers[i]).enabled;
				Collider component = ((Component)_nativeTriggers[i]).GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					_originalColliderStates[i] = component.enabled;
				}
			}
		}
		CacheMagazineAndVisualColliders();
		if (DisableNativeReloadTriggers)
		{
			DisableNativeTriggers();
		}
	}

	private void Start()
	{
		InitChain();
		CacheLinkTransforms();
	}

	private void OnEnable()
	{
		if (_chainInitialized)
		{
			InitChain();
			CacheLinkTransforms();
		}
	}

	private void CacheMagazineAndVisualColliders()
	{
		_cachedMagColliders.Clear();
		_cachedVisualBeltColliders.Clear();
		if ((Object)(object)_magazine != (Object)null)
		{
			Collider[] componentsInChildren = ((Component)_magazine).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					_cachedMagColliders.Add(componentsInChildren[i]);
				}
			}
		}
		else
		{
			Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Collider>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if ((Object)(object)componentsInChildren2[j] != (Object)null)
				{
					_cachedMagColliders.Add(componentsInChildren2[j]);
				}
			}
		}
		if ((Object)(object)VisualBeltContainer != (Object)null)
		{
			Collider[] componentsInChildren3 = ((Component)VisualBeltContainer).GetComponentsInChildren<Collider>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				if ((Object)(object)componentsInChildren3[k] != (Object)null)
				{
					_cachedVisualBeltColliders.Add(componentsInChildren3[k]);
				}
			}
		}
		_collidersCached = true;
	}

	private void DisableNativeTriggers()
	{
		for (int i = 0; i < _nativeTriggers.Length; i++)
		{
			if (!((Object)(object)_nativeTriggers[i] == (Object)null))
			{
				((Behaviour)_nativeTriggers[i]).enabled = false;
				Collider component = ((Component)_nativeTriggers[i]).GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					component.enabled = false;
				}
			}
		}
	}

	private void FixedUpdate()
	{
		if (_isBeingDestroyed)
		{
			return;
		}
		if (_cooldownTimer > 0f)
		{
			_cooldownTimer -= Time.fixedDeltaTime;
		}
		else
		{
			_cooldownTimer = 0f;
		}
		if (_leftHandHapticCooldown > 0f)
		{
			_leftHandHapticCooldown -= Time.fixedDeltaTime;
		}
		if (_rightHandHapticCooldown > 0f)
		{
			_rightHandHapticCooldown -= Time.fixedDeltaTime;
		}
		if (_cooldownTimer <= 0f)
		{
			_scanFrameThrottle++;
			if (_scanFrameThrottle >= 5)
			{
				_scanFrameThrottle = 0;
				HandleFeedTrayDetection();
			}
		}
		if (_chainInitialized)
		{
			UpdateChain();
		}
	}

	private bool IsGunTopCoverOpen(FVRFireArm gun)
	{
		if ((Object)(object)gun == (Object)null)
		{
			return true;
		}
		if (!gun.UsesTopCover)
		{
			return true;
		}
		return gun.IsTopCoverUp;
	}

	private void HandleFeedTrayDetection()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: 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)
		//IL_00e5: 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_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Invalid comparison between Unknown and I4
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		//IL_037e: Unknown result type (might be due to invalid IL or missing references)
		if (_isBeingDestroyed || (Object)(object)_magazine == (Object)null || (!((FVRInteractiveObject)_magazine).IsHeld && (!((Object)(object)_magazine.BeltGrabTrigger != (Object)null) || !((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld)) || (int)_magazine.State != 0)
		{
			return;
		}
		Transform val = ((!((Object)(object)BeltExitPoint != (Object)null)) ? ((Component)this).transform : BeltExitPoint);
		Vector3 position = val.position;
		if ((Object)(object)_magazine.BeltGrabTrigger != (Object)null && ((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld)
		{
			position = ((Component)_magazine.BeltGrabTrigger).transform.position;
		}
		int num = Physics.OverlapSphereNonAlloc(position, LoadDetectionRadius, _overlapResults, LayerMask.op_Implicit(CollisionLayerMask), (QueryTriggerInteraction)2);
		for (int i = 0; i < num; i++)
		{
			Collider val2 = _overlapResults[i];
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			FVRFireArm componentInParent = ((Component)val2).GetComponentInParent<FVRFireArm>();
			if ((Object)(object)componentInParent == (Object)null || ((Object)(object)componentInParent.Magazine != (Object)null && (Object)(object)componentInParent.Magazine != (Object)(object)_magazine) || !componentInParent.UsesBelts || (Object)(object)componentInParent.BeltDD == (Object)null || !IsGunTopCoverOpen(componentInParent))
			{
				continue;
			}
			FVRFireArmReloadTriggerWell[] cachedTriggerWells;
			if ((Object)(object)componentInParent == (Object)(object)_lastScannedFireArm)
			{
				cachedTriggerWells = _cachedTriggerWells;
			}
			else
			{
				_lastScannedFireArm = componentInParent;
				_cachedTriggerWells = ((Component)componentInParent).GetComponentsInChildren<FVRFireArmReloadTriggerWell>(true);
				cachedTriggerWells = _cachedTriggerWells;
			}
			FireArmMagazineType val3 = componentInParent.MagazineType;
			if (cachedTriggerWells != null)
			{
				foreach (FVRFireArmReloadTriggerWell val4 in cachedTriggerWells)
				{
					if (!((Object)(object)val4 == (Object)null) && ((_magazine.IsBeltBox && val4.IsBeltBox) || (val4.UsesTypeOverride && val4.TypeOverride == _magazine.MagazineType)))
					{
						if (val4.UsesTypeOverride)
						{
							val3 = val4.TypeOverride;
						}
						break;
					}
				}
			}
			bool flag = BypassTypeMatching || val3 == _magazine.MagazineType;
			if (!flag && CompatibleMagazineTypes != null)
			{
				for (int k = 0; k < CompatibleMagazineTypes.Length; k++)
				{
					if ((int)val3 == (int)CompatibleMagazineTypes[k])
					{
						val3 = _magazine.MagazineType;
						break;
					}
				}
			}
			if ((!flag && val3 != _magazine.MagazineType) || (componentInParent.EjectDelay > 0f && (Object)(object)_magazine == (Object)(object)componentInParent.LastEjectedMag))
			{
				continue;
			}
			List<Transform> proxyRounds = componentInParent.BeltDD.ProxyRounds;
			if (proxyRounds == null || proxyRounds.Count == 0 || (Object)(object)proxyRounds[0] == (Object)null)
			{
				continue;
			}
			float num2 = Vector3.Distance(position, proxyRounds[0].position);
			if (num2 <= LoadDetectionRadius)
			{
				if (EnableDebug)
				{
					Debug.Log((object)$"[BeltPhysicsDebug] Mounting belt into firearm: {((Object)((Component)componentInParent).gameObject).name}");
				}
				_magazine.Load(componentInParent);
				break;
			}
		}
	}

	private void LateUpdate()
	{
		//IL_051e: Unknown result type (might be due to invalid IL or missing references)
		//IL_052e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		if (!_chainInitialized || (Object)(object)_magazine == (Object)null || _isBeingDestroyed)
		{
			return;
		}
		FVRFireArm fireArm = _magazine.FireArm;
		bool flag = (Object)(object)fireArm != (Object)null;
		int num = _magazine.m_numRounds;
		if (flag && (Object)(object)fireArm.BeltDD != (Object)null)
		{
			num += fireArm.BeltDD.m_roundsOnBelt;
		}
		if (flag && num == 0)
		{
			_isBeingDestroyed = true;
			((Behaviour)this).enabled = false;
			FVRFireArm val = fireArm;
			if ((Object)(object)VisualBeltContainer != (Object)null)
			{
				((Component)VisualBeltContainer).gameObject.SetActive(false);
			}
			SetGunProxyRenderersEnabled(enabled: true, val);
			if ((Object)(object)val.BeltDD != (Object)null)
			{
				val.ConnectedToBox = false;
				val.HasBelt = false;
				val.BeltDD.PullPushBelt((FVRFireArmMagazine)null, 0);
			}
			((FVRInteractiveObject)_magazine).ForceBreakInteraction();
			if ((Object)(object)((FVRPhysicalObject)_magazine).QuickbeltSlot != (Object)null)
			{
				((FVRPhysicalObject)_magazine).ClearQuickbeltState();
			}
			val.EjectMag(true);
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		if (flag && !_wasLoadedLastFrame)
		{
			_magazine.HidesAllDisplayBulletsWhenGrabbed = false;
			if ((Object)(object)fireArm.BeltDD != (Object)null)
			{
				_magazine.IsBeltBox = true;
				fireArm.ConnectedToBox = true;
				fireArm.HasBelt = true;
				fireArm.BeltDD.PullPushBelt(_magazine, Mathf.Min(fireArm.BeltDD.BeltCapacity, _magazine.m_numRounds));
			}
			else
			{
				_magazine.IsBeltBox = false;
			}
			CacheGunRenderers(fireArm);
			SetGunProxyRenderersEnabled(enabled: false, fireArm);
			((FVRInteractiveObject)_magazine).SetAllCollidersToLayer(false, "NoCol");
			_lastLoadedFireArm = fireArm;
			_wasLoadedLastFrame = true;
			_lastCoverState = IsGunTopCoverOpen(fireArm);
		}
		else if (!flag && _wasLoadedLastFrame)
		{
			_magazine.IsBeltBox = _originalIsBeltBox;
			_magazine.CanBeTornOut = _originalCanBeTornOut;
			RestoreDisplayBulletSetting();
			if ((Object)(object)_lastLoadedFireArm != (Object)null)
			{
				SetGunProxyRenderersEnabled(enabled: true, _lastLoadedFireArm);
				if ((Object)(object)_lastLoadedFireArm.BeltDD != (Object)null)
				{
					_lastLoadedFireArm.ConnectedToBox = false;
					_lastLoadedFireArm.HasBelt = false;
					_lastLoadedFireArm.BeltDD.PullPushBelt((FVRFireArmMagazine)null, 0);
				}
			}
			_cachedGunRenderers.Clear();
			_lastLoadedFireArm = null;
			((FVRInteractiveObject)_magazine).SetAllCollidersToLayer(false, "Default");
			SetAllMagazineCollidersEnabled(enabled: true);
			_wasLoadedLastFrame = false;
		}
		if (flag)
		{
			bool flag2 = IsGunTopCoverOpen(fireArm);
			if (flag2 != _lastCoverState)
			{
				_magazine.CanBeTornOut = flag2;
				SetAllMagazineCollidersEnabled(flag2);
				_lastCoverState = flag2;
			}
			if (flag2)
			{
				bool flag3 = (Object)(object)_magazine.BeltGrabTrigger != (Object)null && ((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld;
				if (flag3 || ((FVRInteractiveObject)_magazine).IsHeld)
				{
					FVRViveHand val2 = ((!flag3) ? ((FVRInteractiveObject)_magazine).m_hand : ((FVRInteractiveObject)_magazine.BeltGrabTrigger).m_hand);
					if ((Object)(object)val2 != (Object)null)
					{
						SetGunProxyRenderersEnabled(enabled: true, fireArm);
						if ((Object)(object)fireArm.BeltDD != (Object)null)
						{
							fireArm.BeltDD.PullPushBelt(_magazine, 0);
						}
						_magazine.IsBeltBox = _originalIsBeltBox;
						_magazine.CanBeTornOut = _originalCanBeTornOut;
						RestoreDisplayBulletSetting();
						fireArm.EjectMag(false);
						if ((Object)(object)_magazine.BeltGrabTrigger != (Object)null)
						{
							((FVRInteractiveObject)_magazine.BeltGrabTrigger).ForceBreakInteraction();
						}
						((FVRInteractiveObject)_magazine).ForceBreakInteraction();
						((FVRInteractiveObject)_magazine).SetAllCollidersToLayer(false, "Default");
						SetAllMagazineCollidersEnabled(enabled: true);
						val2.ForceSetInteractable((FVRInteractiveObject)(object)_magazine);
						((FVRInteractiveObject)_magazine).BeginInteraction(val2);
						flag = false;
					}
				}
			}
			else
			{
				if ((Object)(object)_magazine.BeltGrabTrigger != (Object)null && ((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld)
				{
					((FVRInteractiveObject)_magazine.BeltGrabTrigger).ForceBreakInteraction();
				}
				if (((FVRInteractiveObject)_magazine).IsHeld)
				{
					((FVRInteractiveObject)_magazine).ForceBreakInteraction();
				}
			}
		}
		if ((Object)(object)VisualBeltContainer != (Object)null)
		{
			if (flag)
			{
				Transform anchorTransform = GetAnchorTransform();
				if ((Object)(object)anchorTransform != (Object)null)
				{
					VisualBeltContainer.position = anchorTransform.position;
					VisualBeltContainer.rotation = ((Component)_magazine.FireArm).transform.rotation;
				}
			}
			else
			{
				VisualBeltContainer.localPosition = Vector3.zero;
				VisualBeltContainer.localRotation = Quaternion.identity;
			}
		}
		PositionBullets();
	}

	private void SetAllMagazineCollidersEnabled(bool enabled)
	{
		if (!_collidersCached)
		{
			CacheMagazineAndVisualColliders();
		}
		for (int i = 0; i < _cachedMagColliders.Count; i++)
		{
			if ((Object)(object)_cachedMagColliders[i] != (Object)null && _cachedMagColliders[i].enabled != enabled)
			{
				_cachedMagColliders[i].enabled = enabled;
			}
		}
		for (int j = 0; j < _cachedVisualBeltColliders.Count; j++)
		{
			if ((Object)(object)_cachedVisualBeltColliders[j] != (Object)null && _cachedVisualBeltColliders[j].enabled != enabled)
			{
				_cachedVisualBeltColliders[j].enabled = enabled;
			}
		}
	}

	private void InitChain()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		int num = Mathf.Max(ChainNodeCount, (!((Object)(object)_magazine != (Object)null) || _magazine.DisplayBullets == null) ? 34 : (_magazine.DisplayBullets.Length + 2));
		_positions = (Vector3[])(object)new Vector3[num];
		_prevPositions = (Vector3[])(object)new Vector3[num];
		Transform val = ((!((Object)(object)BeltExitPoint != (Object)null)) ? ((Component)this).transform : BeltExitPoint);
		Vector3 position = val.position;
		Vector3 val2 = val.TransformDirection(((Vector3)(ref UnloadedExitDirection)).normalized);
		for (int i = 0; i < _positions.Length; i++)
		{
			ref Vector3 reference = ref _positions[i];
			reference = position + val2 * (NodeDistance * (float)i);
			ref Vector3 reference2 = ref _prevPositions[i];
			reference2 = _positions[i];
		}
		_chainInitialized = true;
	}

	private void UpdateChain()
	{
		//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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: 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_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0724: Unknown result type (might be due to invalid IL or missing references)
		//IL_0736: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0435: Unknown result type (might be due to invalid IL or missing references)
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_043f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c01: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c0c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c11: Unknown result type (might be due to invalid IL or missing references)
		//IL_0533: Unknown result type (might be due to invalid IL or missing references)
		//IL_0538: Unknown result type (might be due to invalid IL or missing references)
		//IL_053d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0559: Unknown result type (might be due to invalid IL or missing references)
		//IL_055b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0560: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_0487: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_0495: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ca9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0caa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cb6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cbb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cc0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cdc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ce1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ce9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cee: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05de: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0607: Unknown result type (might be due to invalid IL or missing references)
		//IL_060c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0852: Unknown result type (might be due to invalid IL or missing references)
		//IL_0857: Unknown result type (might be due to invalid IL or missing references)
		//IL_085c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0897: Unknown result type (might be due to invalid IL or missing references)
		//IL_089c: Unknown result type (might be due to invalid IL or missing references)
		//IL_089e: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0696: Unknown result type (might be due to invalid IL or missing references)
		//IL_0697: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_090b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0910: Unknown result type (might be due to invalid IL or missing references)
		//IL_091b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0920: Unknown result type (might be due to invalid IL or missing references)
		//IL_0925: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0867: Unknown result type (might be due to invalid IL or missing references)
		//IL_086c: Unknown result type (might be due to invalid IL or missing references)
		//IL_087d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0882: Unknown result type (might be due to invalid IL or missing references)
		//IL_0887: Unknown result type (might be due to invalid IL or missing references)
		//IL_0833: Unknown result type (might be due to invalid IL or missing references)
		//IL_0945: Unknown result type (might be due to invalid IL or missing references)
		//IL_0957: Unknown result type (might be due to invalid IL or missing references)
		//IL_0962: Unknown result type (might be due to invalid IL or missing references)
		//IL_0967: Unknown result type (might be due to invalid IL or missing references)
		Transform anchorTransform = GetAnchorTransform();
		if ((Object)(object)anchorTransform == (Object)null)
		{
			return;
		}
		bool flag = (Object)(object)_magazine.FireArm != (Object)null;
		bool flag2 = (Object)(object)((FVRPhysicalObject)_magazine).QuickbeltSlot != (Object)null;
		Vector3 position = anchorTransform.position;
		Vector3 val = ((!flag) ? anchorTransform.TransformDirection(((Vector3)(ref UnloadedExitDirection)).normalized) : anchorTransform.TransformDirection(((Vector3)(ref LoadedExitDirection)).normalized));
		int num = (flag ? 1 : Mathf.Clamp(PinnedNodes, 1, _positions.Length));
		if (flag2)
		{
			for (int i = 0; i < _positions.Length; i++)
			{
				ref Vector3 reference = ref _positions[i];
				reference = position + val * (NodeDistance * (float)i);
				ref Vector3 reference2 = ref _prevPositions[i];
				reference2 = _positions[i];
			}
			return;
		}
		for (int j = 0; j < num; j++)
		{
			ref Vector3 reference3 = ref _positions[j];
			reference3 = position + val * (NodeDistance * (float)j);
			ref Vector3 reference4 = ref _prevPositions[j];
			reference4 = _positions[j];
		}
		float num2 = ((!flag) ? Damping : LoadedDamping);
		float fixedDeltaTime = Time.fixedDeltaTime;
		for (int k = num; k < _positions.Length; k++)
		{
			Vector3 val2 = (_positions[k] - _prevPositions[k]) * num2;
			ref Vector3 reference5 = ref _prevPositions[k];
			reference5 = _positions[k];
			ref Vector3 reference6 = ref _positions[k];
			reference6 += val2 + Physics.gravity * GravityScale * fixedDeltaTime * fixedDeltaTime;
		}
		_floorScanThrottle++;
		if (_floorScanThrottle >= 10)
		{
			_floorScanThrottle = 0;
			int num3 = Physics.RaycastNonAlloc(position, Vector3.down, _floorHitBuffer, MaxFloorRaycastDistance, LayerMask.op_Implicit(CollisionLayerMask));
			float num4 = float.MaxValue;
			for (int l = 0; l < num3; l++)
			{
				if (!((Object)(object)((RaycastHit)(ref _floorHitBuffer[l])).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref _floorHitBuffer[l])).collider).transform.root == (Object)(object)((Component)this).transform.root) && (!flag || !((Object)(object)_magazine.FireArm != (Object)null) || !((Object)(object)((Component)((RaycastHit)(ref _floorHitBuffer[l])).collider).transform.root == (Object)(object)((Component)_magazine.FireArm).transform.root)) && ((RaycastHit)(ref _floorHitBuffer[l])).distance < num4)
				{
					num4 = ((RaycastHit)(ref _floorHitBuffer[l])).distance;
					_currentFloorY = ((RaycastHit)(ref _floorHitBuffer[l])).point.y;
				}
			}
		}
		for (int m = 0; m < ConstraintIterations; m++)
		{
			for (int n = 0; n < num; n++)
			{
				ref Vector3 reference7 = ref _positions[n];
				reference7 = position + val * (NodeDistance * (float)n);
			}
			for (int num5 = 0; num5 < _positions.Length - 1; num5++)
			{
				if (num5 + 1 < num)
				{
					continue;
				}
				Vector3 val3 = _positions[num5 + 1] - _positions[num5];
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (!(magnitude < 0.0001f))
				{
					float num6 = (magnitude - NodeDistance) / magnitude;
					if (num5 < num)
					{
						ref Vector3 reference8 = ref _positions[num5 + 1];
						reference8 -= val3 * num6;
						continue;
					}
					ref Vector3 reference9 = ref _positions[num5];
					reference9 += val3 * num6 * 0.5f;
					ref Vector3 reference10 = ref _positions[num5 + 1];
					reference10 -= val3 * num6 * 0.5f;
				}
			}
			for (int num7 = num; num7 < _positions.Length; num7++)
			{
				Vector3 val4 = anchorTransform.InverseTransformPoint(_positions[num7]);
				val4.z = 0f;
				ref Vector3 reference11 = ref _positions[num7];
				reference11 = anchorTransform.TransformPoint(val4);
			}
			if (BendingStiffness > 0f)
			{
				for (int num8 = 0; num8 < _positions.Length - 2; num8++)
				{
					int num9 = num8 + 1;
					if (num9 >= num)
					{
						Vector3 val5 = (_positions[num8] + _positions[num8 + 2]) * 0.5f;
						ref Vector3 reference12 = ref _positions[num9];
						reference12 = Vector3.Lerp(_positions[num9], val5, BendingStiffness);
					}
				}
			}
			if (!(PinTransitionRigidity > 0f) || PinTransitionNodeCount <= 0)
			{
				continue;
			}
			int num10 = Mathf.Min(PinTransitionNodeCount, _positions.Length - num);
			for (int num11 = 0; num11 < num10; num11++)
			{
				int num12 = num + num11;
				float num13 = PinTransitionRigidity * (1f - (float)num11 / (float)num10);
				if (!(num13 <= 0f))
				{
					Vector3 val6 = position + val * (NodeDistance * (float)num12);
					ref Vector3 reference13 = ref _positions[num12];
					reference13 = Vector3.Lerp(_positions[num12], val6, num13);
				}
			}
		}
		if (EnableNodeCollision)
		{
			for (int num14 = num; num14 < _positions.Length; num14++)
			{
				int num15 = Physics.OverlapSphereNonAlloc(_positions[num14], NodeCollisionRadius, _nodeCollisionBuffer, LayerMask.op_Implicit(CollisionLayerMask), (QueryTriggerInteraction)1);
				for (int num16 = 0; num16 < num15; num16++)
				{
					Collider val7 = _nodeCollisionBuffer[num16];
					if ((Object)(object)val7 == (Object)null || val7.isTrigger || (Object)(object)((Component)val7).transform.root == (Object)(object)((Component)this).transform.root || (flag && (Object)(object)_magazine.FireArm != (Object)null && (Object)(object)((Component)val7).transform.root == (Object)(object)((Component)_magazine.FireArm).transform.root && (!CollideWithOwnGun || num14 < SkipGunCollisionNodeCount)))
					{
						continue;
					}
					Vector3 val8;
					if (val7 is BoxCollider || val7 is SphereCollider || val7 is CapsuleCollider || (val7 is MeshCollider && ((MeshCollider)val7).convex))
					{
						val8 = val7.ClosestPoint(_positions[num14]);
					}
					else
					{
						Bounds bounds = val7.bounds;
						val8 = ((Bounds)(ref bounds)).ClosestPoint(_positions[num14]);
					}
					Vector3 val9 = _positions[num14] - val8;
					float magnitude2 = ((Vector3)(ref val9)).magnitude;
					if (magnitude2 < NodeCollisionRadius)
					{
						if (magnitude2 > 0.0001f)
						{
							ref Vector3 reference14 = ref _positions[num14];
							reference14 = val8 + val9 / magnitude2 * NodeCollisionRadius;
						}
						else
						{
							ref Vector3 reference15 = ref _positions[num14];
							reference15 += Vector3.up * NodeCollisionRadius;
						}
						ref Vector3 reference16 = ref _prevPositions[num14];
						reference16 = Vector3.Lerp(_prevPositions[num14], _positions[num14], SurfaceFriction);
					}
				}
			}
		}
		if (EnableHandInteraction)
		{
			FVRViveHand val10 = ((!((FVRInteractiveObject)_magazine).IsHeld) ? null : ((FVRInteractiveObject)_magazine).m_hand);
			FVRViveHand val11 = ((!((Object)(object)_magazine.BeltGrabTrigger != (Object)null) || !((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld) ? null : ((FVRInteractiveObject)_magazine.BeltGrabTrigger).m_hand);
			if ((Object)(object)GM.CurrentMovementManager != (Object)null && GM.CurrentMovementManager.Hands != null)
			{
				int num17 = 0;
				for (int num18 = 0; num18 < GM.CurrentMovementManager.Hands.Length; num18++)
				{
					FVRViveHand val12 = GM.CurrentMovementManager.Hands[num18];
					if ((Object)(object)val12 != (Object)null && (Object)(object)val12 != (Object)(object)val10 && (Object)(object)val12 != (Object)(object)val11)
					{
						if (num17 == 0)
						{
							HandlePalmDeflection(val12, ref _leftHandHapticCooldown);
						}
						else
						{
							HandlePalmDeflection(val12, ref _rightHandHapticCooldown);
						}
					}
					num17++;
				}
			}
			else if ((Object)(object)GM.CurrentPlayerBody != (Object)null)
			{
				if ((Object)(object)GM.CurrentPlayerBody.LeftHand != (Object)null)
				{
					FVRViveHand component = ((Component)GM.CurrentPlayerBody.LeftHand).GetComponent<FVRViveHand>();
					if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)val10 && (Object)(object)component != (Object)(object)val11)
					{
						HandlePalmDeflection(component, ref _leftHandHapticCooldown);
					}
				}
				if ((Object)(object)GM.CurrentPlayerBody.RightHand != (Object)null)
				{
					FVRViveHand component2 = ((Component)GM.CurrentPlayerBody.RightHand).GetComponent<FVRViveHand>();
					if ((Object)(object)component2 != (Object)null && (Object)(object)component2 != (Object)(object)val10 && (Object)(object)component2 != (Object)(object)val11)
					{
						HandlePalmDeflection(component2, ref _rightHandHapticCooldown);
					}
				}
			}
		}
		for (int num19 = 1; num19 < _positions.Length; num19++)
		{
			float num20 = _currentFloorY + FloorOffset;
			if (_positions[num19].y < num20)
			{
				_positions[num19].y = num20;
				ref Vector3 reference17 = ref _prevPositions[num19];
				reference17 = Vector3.Lerp(_prevPositions[num19], _positions[num19], SurfaceFriction);
				if (Mathf.Abs(_positions[num19].y - _prevPositions[num19].y) < FloorSleepVelocityThreshold)
				{
					_prevPositions[num19].y = _positions[num19].y;
				}
			}
		}
		if (flag && LoadedRigidity > 0f)
		{