Decompiled source of Swiss K31 v1.0.1

Swiss_K31.dll

Decompiled a day ago
using System;
using System.Collections;
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 OpenScripts2;
using OtherLoader;
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 AT4 : SimpleLauncher
{
	[Header("Trigger Settings")]
	public Transform Trigger;

	public Axis Trigger_Axis = (Axis)0;

	public Vector2 Trigger_ValRange = new Vector2(0f, 10f);

	private float m_triggerVal;

	[Header("Rocket Settings")]
	[HideInInspector]
	public bool hasFired = false;

	[Header("Self-Destruct")]
	public float DestroyDelay = 10f;

	private bool selfDestructStarted = false;

	public AT4ArmingLever ArmingLever;

	private void FireAT4()
	{
		if (base.Chamber.IsFull && !base.Chamber.IsSpent && !((Object)(object)ArmingLever == (Object)null) && ArmingLever.IsArmed)
		{
			base.Chamber.Fire();
			((FVRFireArm)this).FireMuzzleSmoke();
			hasFired = true;
			StartSelfDestructCheck();
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected I4, but got Unknown
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: 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_0080: Expected I4, but got Unknown
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ArmingLever != (Object)null && !ArmingLever.IsArmed)
		{
			if ((Object)(object)Trigger != (Object)null && (Object)(object)hand != (Object)null)
			{
				Vector3 localPosition = Trigger.localPosition;
				((Vector3)(ref localPosition))[(int)Trigger_Axis] = Mathf.Lerp(Trigger_ValRange.x, Trigger_ValRange.y, hand.Input.TriggerFloat);
				Trigger.localPosition = localPosition;
			}
			return;
		}
		((SimpleLauncher)this).UpdateInteraction(hand);
		if ((Object)(object)Trigger != (Object)null && (Object)(object)hand != (Object)null)
		{
			Vector3 localPosition2 = Trigger.localPosition;
			((Vector3)(ref localPosition2))[(int)Trigger_Axis] = Mathf.Lerp(Trigger_ValRange.x, Trigger_ValRange.y, hand.Input.TriggerFloat);
			Trigger.localPosition = localPosition2;
		}
		if ((Object)(object)ArmingLever != (Object)null && ArmingLever.IsArmed && !((FVRPhysicalObject)this).IsAltHeld && (Object)(object)hand != (Object)null && hand.Input.TriggerDown && !hasFired && base.Chamber.IsFull && !base.Chamber.IsSpent)
		{
			FireAT4();
		}
		if ((!base.Chamber.IsFull || hasFired) && !selfDestructStarted && !((FVRInteractiveObject)this).IsHeld)
		{
			StartSelfDestructCheck();
		}
	}

	private void StartSelfDestructCheck()
	{
		if (!selfDestructStarted)
		{
			selfDestructStarted = true;
			((MonoBehaviour)this).StartCoroutine(SelfDestructCheck());
		}
	}

	private IEnumerator SelfDestructCheck()
	{
		float timer = 0f;
		while (timer < DestroyDelay)
		{
			if (!((FVRInteractiveObject)this).IsHeld)
			{
				timer += Time.deltaTime;
			}
			yield return null;
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}
}
public class AT4ArmingLever : FVRInteractiveObject
{
	public AT4 Weapon;

	[Header("Lever Movement")]
	public Transform LeverRoot;

	public Transform ForwardPoint;

	public Transform RearPoint;

	[Header("Arming Settings")]
	public float ArmThreshold = 0.9f;

	[Header("Lever Rotation Settings")]
	[Tooltip("Which local axis to rotate around: 0=X, 1=Y, 2=Z")]
	public int RotationAxis = 1;

	[Tooltip("Starting rotation (degrees) for the selected axis.")]
	public float StartRotation = 0f;

	[Tooltip("Ending rotation (degrees) for the selected axis.")]
	public float EndRotation = 45f;

	[Tooltip("How far right (in local X units) the hand must move for full rotation.")]
	public float MaxRightOffset = 0.1f;

	private bool isArmed = false;

	private float leverProgress = 0f;

	private Vector3 startLocalPos;

	private Vector3 endLocalPos;

	public bool IsArmed => isArmed;

	public override void Awake()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)LeverRoot != (Object)null && (Object)(object)ForwardPoint != (Object)null && (Object)(object)RearPoint != (Object)null)
		{
			startLocalPos = RearPoint.localPosition;
			endLocalPos = ForwardPoint.localPosition;
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//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_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_006a: 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_0072: 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_007d: 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_0084: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).UpdateInteraction(hand);
		if ((Object)(object)LeverRoot == (Object)null || (Object)(object)ForwardPoint == (Object)null || (Object)(object)RearPoint == (Object)null || (Object)(object)Weapon == (Object)null)
		{
			return;
		}
		Vector3 position = RearPoint.position;
		Vector3 position2 = ForwardPoint.position;
		Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(position, position2, ((HandInput)(ref hand.Input)).Pos);
		float num = Vector3.Distance(position, closestValidPoint) / Vector3.Distance(position, position2);
		num = Mathf.Clamp01(num);
		if (num < 1f)
		{
			LeverRoot.position = closestValidPoint;
			leverProgress = num;
			SetLeverRotation(StartRotation);
		}
		else
		{
			LeverRoot.position = position2;
			float num2 = Mathf.Clamp(ForwardPoint.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos).x, 0f - MaxRightOffset, MaxRightOffset);
			float num3 = ((!(MaxRightOffset > 0f)) ? 0f : ((num2 + MaxRightOffset) / (2f * MaxRightOffset)));
			float leverRotation = Mathf.Lerp(StartRotation, EndRotation, num3);
			SetLeverRotation(leverRotation);
			leverProgress = 1f;
		}
		if (!isArmed && leverProgress >= ArmThreshold)
		{
			isArmed = true;
			if ((Object)(object)Weapon != (Object)null)
			{
				((FVRFireArm)Weapon).PlayAudioEvent((FirearmAudioEventType)12, 1f);
			}
		}
		else if (isArmed && leverProgress < 0.2f)
		{
			isArmed = false;
		}
	}

	private void SetLeverRotation(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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		Vector3 zero = Vector3.zero;
		if (RotationAxis == 0)
		{
			zero.x = angle;
		}
		else if (RotationAxis == 1)
		{
			zero.y = angle;
		}
		else
		{
			zero.z = angle;
		}
		LeverRoot.localRotation = Quaternion.Euler(zero);
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//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)
		//IL_001a: 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)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_0071: 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)
		((FVRInteractiveObject)this).EndInteraction(hand);
		Vector3 position = RearPoint.position;
		Vector3 position2 = ForwardPoint.position;
		float num = Vector3.Distance(LeverRoot.position, position);
		float num2 = Vector3.Distance(LeverRoot.position, position2);
		if (num2 < num)
		{
			LeverRoot.position = position2;
			SetLeverRotation(EndRotation);
		}
		else
		{
			LeverRoot.position = position;
			SetLeverRotation(StartRotation);
		}
	}
}
public class AT4SightCover : FVRInteractiveObject
{
	[Header("Sight References")]
	public Transform Sight;

	public Transform Cover;

	public Transform CoverRearPos;

	public Transform CoverForwardPos;

	[Header("Sight Local Positions & Rotations")]
	public Vector3 SightDownLocalPos;

	public Vector3 SightUpLocalPos;

	public Vector3 SightDownRot;

	public Vector3 SightUpRot;

	[Header("Interaction Settings")]
	[Range(0f, 1f)]
	public float CoverThreshold = 0.95f;

	private bool sightUp = false;

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_0047: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_006e: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: 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)
		((FVRInteractiveObject)this).UpdateInteraction(hand);
		if (!((Object)(object)Sight == (Object)null) && !((Object)(object)CoverRearPos == (Object)null) && !((Object)(object)CoverForwardPos == (Object)null))
		{
			Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(CoverRearPos.position, CoverForwardPos.position, ((HandInput)(ref hand.Input)).Pos);
			float num = Vector3.Distance(CoverRearPos.position, closestValidPoint) / Vector3.Distance(CoverRearPos.position, CoverForwardPos.position);
			num = Mathf.Clamp01(num);
			if ((Object)(object)Cover != (Object)null)
			{
				Cover.position = Vector3.Lerp(CoverRearPos.position, CoverForwardPos.position, num);
			}
			else
			{
				((Component)this).transform.position = Vector3.Lerp(CoverRearPos.position, CoverForwardPos.position, num);
			}
			Sight.localPosition = Vector3.Lerp(SightDownLocalPos, SightUpLocalPos, num);
			Sight.localEulerAngles = Vector3.Lerp(SightDownRot, SightUpRot, num);
			if (num >= CoverThreshold && !sightUp)
			{
				sightUp = true;
			}
			else if (num < CoverThreshold && sightUp)
			{
				sightUp = false;
			}
		}
	}
}
public class Arwen : FVRFireArm
{
	[Header("Arwen 37mm Config")]
	public ArwenCylinder Cylinder;

	public FVRFireArmChamber[] Chambers;

	[Header("Trigger")]
	public Transform Trigger;

	[Tooltip("Trigger float value at which the weapon fires (DAO pull depth).")]
	public float TriggerFiringThreshold = 0.95f;

	[Tooltip("Trigger float value below which a spent shell ejects on release.")]
	public float TriggerEjectThreshold = 0.35f;

	[Tooltip("Trigger float value below which the trigger is considered fully reset.")]
	public float TriggerResetThreshold = 0.1f;

	public bool TriggerUsesRotation = true;

	public Vector3 TriggerRotationAxis = Vector3.right;

	public float TriggerMinAngle = 0f;

	public float TriggerMaxAngle = 30f;

	public bool TriggerUsesTranslation = false;

	public Vector3 TriggerTranslationAxis = Vector3.back;

	public float TriggerMinPosition = 0f;

	public float TriggerMaxPosition = 0.02f;

	[Header("Hammer")]
	public Transform Hammer;

	public bool HammerUsesRotation = true;

	public Vector3 HammerRotationAxis = Vector3.right;

	public float HammerMinAngle = 0f;

	public float HammerMaxAngle = 45f;

	public bool HammerUsesTranslation = false;

	public Vector3 HammerTranslationAxis = Vector3.back;

	public float HammerMinPosition = 0f;

	public float HammerMaxPosition = 0.01f;

	[Header("Bolt (animates forward→rear as trigger pulls)")]
	public Transform BoltTransform;

	public Transform Point_Bolt_Forward;

	public Transform Point_Bolt_Rear;

	[Header("Chamber Feed")]
	[Tooltip("How far (metres) the round nudges forward into the barrel as the trigger pulls.")]
	public float ChamberFeedDistance = 0.005f;

	[Header("Ejection")]
	public Transform EjectionPos;

	public Vector3 EjectionVelocity = new Vector3(0.2f, 0.5f, 0f);

	public Vector3 EjectionSpin = new Vector3(0f, 200f, 0f);

	[Header("Cylinder")]
	public float CylinderRotateDuration = 0.2f;

	[Header("Safety")]
	public Transform SafetySwitchLeft;

	public Transform SafetySwitchRight;

	public InterpStyle SafetyInterpStyle = (InterpStyle)1;

	public Axis SafetyAxis;

	public float SafetyPosition_Fire = 0f;

	public float SafetyPosition_Safe = 45f;

	private int m_curChamber = 0;

	private bool m_isSafetyOn = false;

	private bool m_hasTriggerCycled = false;

	private bool m_hasFired = false;

	private bool m_hasDryFired = false;

	private bool m_hasSafetyToggled = false;

	private bool m_isRestoringState = false;

	private bool[] m_prevChamberFull;

	private bool[] m_prevChamberPresent;

	private Coroutine m_cylinderCoroutine;

	public override void Awake()
	{
		((FVRFireArm)this).Awake();
		if (Chambers != null)
		{
			for (int i = 0; i < Chambers.Length; i++)
			{
				base.FChambers.Add(Chambers[i]);
			}
		}
		int num = ((Chambers != null) ? Chambers.Length : 0);
		m_prevChamberFull = new bool[num];
		m_prevChamberPresent = new bool[num];
		for (int j = 0; j < num; j++)
		{
			if (!((Object)(object)Chambers[j] == (Object)null))
			{
				m_prevChamberFull[j] = Chambers[j].IsFull && !Chambers[j].IsSpent;
				m_prevChamberPresent[j] = Chambers[j].IsFull;
			}
		}
		SetAllChambersAccessible(accessible: true);
		UpdateSafetyVisual();
	}

	public override void FVRUpdate()
	{
		((FVRFireArm)this).FVRUpdate();
		if (!m_isRestoringState)
		{
			DetectShellLoaded();
		}
	}

	private void DetectShellLoaded()
	{
		if (Chambers == null)
		{
			return;
		}
		for (int i = 0; i < Chambers.Length; i++)
		{
			bool flag = Chambers[i].IsFull && !Chambers[i].IsSpent;
			bool isFull = Chambers[i].IsFull;
			if (flag && !m_prevChamberFull[i])
			{
				OnShellLoaded();
			}
			if (!isFull && m_prevChamberPresent[i])
			{
				OnShellRemoved(i);
			}
			m_prevChamberFull[i] = flag;
			m_prevChamberPresent[i] = isFull;
		}
	}

	private void OnShellLoaded()
	{
		RotateToChamber(m_curChamber = (m_curChamber - 1 + Chambers.Length) % Chambers.Length);
		((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)20, 1f);
	}

	private void OnShellRemoved(int chamberIndex)
	{
		if (chamberIndex == m_curChamber)
		{
			int num = FindNextLoadedChamberClockwise();
			if (num != m_curChamber)
			{
				RotateToChamber(num);
				m_curChamber = num;
			}
		}
	}

	private int FindNextLoadedChamberClockwise()
	{
		for (int i = 1; i < Chambers.Length; i++)
		{
			int num = (m_curChamber + i) % Chambers.Length;
			if (Chambers[num].IsFull && !Chambers[num].IsSpent)
			{
				return num;
			}
		}
		return m_curChamber;
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		((FVRPhysicalObject)this).UpdateInteraction(hand);
		if (!((Object)(object)hand == (Object)null))
		{
			float triggerFloat = hand.Input.TriggerFloat;
			UpdateTriggerVisual(triggerFloat);
			UpdateHammerVisual(triggerFloat);
			UpdateBoltVisual(triggerFloat);
			UpdateChamberFeedVisual(triggerFloat);
			HandleSafetyInput(hand);
			if (m_hasFired && triggerFloat < TriggerEjectThreshold)
			{
				EjectCurrentChamber();
				AdvanceChamberClockwise();
				m_hasFired = false;
			}
			if (m_hasDryFired && triggerFloat < TriggerResetThreshold)
			{
				AdvanceChamberClockwise();
				m_hasDryFired = false;
			}
			if (!m_isSafetyOn && triggerFloat >= TriggerFiringThreshold && !m_hasTriggerCycled)
			{
				FireOrDryFire();
				m_hasTriggerCycled = true;
			}
			if (triggerFloat < TriggerResetThreshold && m_hasTriggerCycled)
			{
				((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)16, 1f);
				m_hasTriggerCycled = false;
			}
		}
	}

	private void FireOrDryFire()
	{
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		FVRFireArmChamber val = Chambers[m_curChamber];
		if (val.IsFull && !val.IsSpent)
		{
			val.Fire();
			((FVRFireArm)this).Fire(val, (!((Object)(object)base.MuzzlePos != (Object)null)) ? ((Component)this).transform : base.MuzzlePos, true, 1f, -1f);
			((FVRFireArm)this).FireMuzzleSmoke();
			((FVRFireArm)this).Recoil(((FVRFireArm)this).IsTwoHandStabilized(), (Object)(object)((FVRPhysicalObject)this).AltGrip != (Object)null, ((FVRFireArm)this).IsShoulderStabilized(), (FVRFireArmRecoilProfile)null, 1f);
			((FVRFireArm)this).PlayAudioGunShot(val.GetRound(), GM.CurrentPlayerBody.GetCurrentSoundEnvironment(), 1f);
			if (GM.CurrentSceneSettings.IsAmmoInfinite || GM.CurrentPlayerBody.IsInfiniteAmmo)
			{
				val.IsSpent = false;
				val.UpdateProxyDisplay();
			}
			m_hasFired = true;
		}
		else
		{
			((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)6, 1f);
			m_hasDryFired = true;
		}
	}

	private void EjectCurrentChamber()
	{
		//IL_0074: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		FVRFireArmChamber val = Chambers[m_curChamber];
		if (val.IsFull)
		{
			if ((Object)(object)EjectionPos != (Object)null)
			{
				val.EjectRound(EjectionPos.position, EjectionVelocity, EjectionSpin, EjectionPos.position, EjectionPos.rotation, false);
			}
			else
			{
				val.EjectRound(((Component)val).transform.position + ((Component)val).transform.forward * 0.1f, ((Component)val).transform.forward * 3f + Vector3.up * 1.5f, Vector3.up * 200f, true);
			}
		}
	}

	private void AdvanceChamberClockwise()
	{
		int num = (m_curChamber + 1) % Chambers.Length;
		RotateToChamber(num);
		m_curChamber = num;
	}

	private void RotateToChamber(int index)
	{
		if (m_cylinderCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(m_cylinderCoroutine);
		}
		m_cylinderCoroutine = ((MonoBehaviour)this).StartCoroutine(RotateCylinderTo(index));
	}

	private IEnumerator RotateCylinderTo(int toIndex)
	{
		if (!((Object)(object)Cylinder == (Object)null))
		{
			Quaternion from = ((Component)Cylinder).transform.localRotation;
			Quaternion to = Cylinder.GetLocalRotationFromCylinder(toIndex);
			float elapsed = 0f;
			float dur = Mathf.Max(0.01f, CylinderRotateDuration);
			while (elapsed < 1f)
			{
				elapsed += Time.deltaTime / dur;
				((Component)Cylinder).transform.localRotation = Quaternion.Slerp(from, to, elapsed);
				yield return null;
			}
			((Component)Cylinder).transform.localRotation = to;
		}
	}

	public void StopCylinderRotation()
	{
		if (m_cylinderCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(m_cylinderCoroutine);
			m_cylinderCoroutine = null;
		}
	}

	public void SyncChamberFromCylinder()
	{
		if ((Object)(object)Cylinder != (Object)null)
		{
			m_curChamber = Cylinder.GetClosestChamberIndex();
		}
	}

	private void UpdateTriggerVisual(float t)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Trigger == (Object)null))
		{
			if (TriggerUsesRotation)
			{
				Trigger.localRotation = Quaternion.AngleAxis(Mathf.Lerp(TriggerMinAngle, TriggerMaxAngle, t), TriggerRotationAxis);
			}
			if (TriggerUsesTranslation)
			{
				Trigger.localPosition = ((Vector3)(ref TriggerTranslationAxis)).normalized * Mathf.Lerp(TriggerMinPosition, TriggerMaxPosition, t);
			}
		}
	}

	private void UpdateHammerVisual(float t)
	{
		//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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Hammer == (Object)null))
		{
			float num = ((!m_isSafetyOn) ? t : 0f);
			if (HammerUsesRotation)
			{
				Hammer.localRotation = Quaternion.AngleAxis(Mathf.Lerp(HammerMinAngle, HammerMaxAngle, num), HammerRotationAxis);
			}
			if (HammerUsesTranslation)
			{
				Hammer.localPosition = ((Vector3)(ref HammerTranslationAxis)).normalized * Mathf.Lerp(HammerMinPosition, HammerMaxPosition, num);
			}
		}
	}

	private void UpdateBoltVisual(float t)
	{
		//IL_005c: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)BoltTransform == (Object)null) && !((Object)(object)Point_Bolt_Forward == (Object)null) && !((Object)(object)Point_Bolt_Rear == (Object)null))
		{
			float num = ((!m_isSafetyOn) ? t : 0f);
			BoltTransform.localPosition = Vector3.Lerp(Point_Bolt_Forward.localPosition, Point_Bolt_Rear.localPosition, num);
		}
	}

	private void UpdateChamberFeedVisual(float t)
	{
		//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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		if (Chambers != null && m_curChamber < Chambers.Length)
		{
			FVRFireArmChamber val = Chambers[m_curChamber];
			if (val.IsFull && !((Object)(object)val.ProxyRound == (Object)null))
			{
				float num = ((!m_isSafetyOn) ? t : 0f);
				val.ProxyRound.localPosition = Vector3.Lerp(Vector3.zero, Vector3.forward * ChamberFeedDistance, num);
			}
		}
	}

	private void HandleSafetyInput(FVRViveHand hand)
	{
		//IL_0072: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		if (hand.IsInStreamlinedMode)
		{
			if (hand.Input.BYButtonDown && !m_hasSafetyToggled)
			{
				ToggleSafety();
				m_hasSafetyToggled = true;
			}
			else if (!hand.Input.BYButtonDown)
			{
				m_hasSafetyToggled = false;
			}
		}
		else if (hand.Input.TouchpadDown)
		{
			Vector2 touchpadAxes = hand.Input.TouchpadAxes;
			if (((Vector2)(ref touchpadAxes)).magnitude > 0.2f && Vector2.Angle(touchpadAxes, Vector2.left) < 45f)
			{
				ToggleSafety();
			}
		}
	}

	private void ToggleSafety()
	{
		m_isSafetyOn = !m_isSafetyOn;
		UpdateSafetyVisual();
		((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)15, 1f);
	}

	private void UpdateSafetyVisual()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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)
		float num = ((!m_isSafetyOn) ? SafetyPosition_Fire : SafetyPosition_Safe);
		if ((Object)(object)SafetySwitchLeft != (Object)null)
		{
			((FVRPhysicalObject)this).SetAnimatedComponent(SafetySwitchLeft, num, SafetyInterpStyle, SafetyAxis);
		}
		if ((Object)(object)SafetySwitchRight != (Object)null)
		{
			((FVRPhysicalObject)this).SetAnimatedComponent(SafetySwitchRight, num, SafetyInterpStyle, SafetyAxis);
		}
	}

	private void SetAllChambersAccessible(bool accessible)
	{
		if (Chambers == null)
		{
			return;
		}
		for (int i = 0; i < Chambers.Length; i++)
		{
			if ((Object)(object)Chambers[i] != (Object)null)
			{
				Chambers[i].IsAccessible = accessible;
			}
		}
	}

	public override List<FireArmRoundClass> GetChamberRoundList()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		List<FireArmRoundClass> list = new List<FireArmRoundClass>();
		for (int i = 0; i < Chambers.Length; i++)
		{
			if (Chambers[i].IsFull && !Chambers[i].IsSpent)
			{
				list.Add(Chambers[i].GetRound().RoundClass);
				flag = true;
			}
			else
			{
				list.Add((FireArmRoundClass)(-1));
			}
		}
		return (!flag) ? null : list;
	}

	public override void SetLoadedChambers(List<FireArmRoundClass> rounds)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		if (rounds == null)
		{
			return;
		}
		m_isRestoringState = true;
		for (int i = 0; i < rounds.Count && i < Chambers.Length; i++)
		{
			if ((int)rounds[i] >= 0)
			{
				Chambers[i].Autochamber(rounds[i]);
			}
		}
		for (int j = 0; j < Chambers.Length; j++)
		{
			m_prevChamberFull[j] = Chambers[j].IsFull && !Chambers[j].IsSpent;
			m_prevChamberPresent[j] = Chambers[j].IsFull;
		}
		m_isRestoringState = false;
	}
}
public class ArwenCylinder : FVRInteractiveObject
{
	[Header("Arwen Cylinder Config")]
	public Arwen Arwen;

	public int numChambers = 5;

	private float m_fakeAngularVel;

	public override void Awake()
	{
		((FVRInteractiveObject)this).Awake();
	}

	public override bool IsInteractable()
	{
		return true;
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		((FVRInteractiveObject)this).BeginInteraction(hand);
		if ((Object)(object)Arwen != (Object)null)
		{
			Arwen.StopCylinderRotation();
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: 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)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).UpdateInteraction(hand);
		if (!((Object)(object)Arwen == (Object)null))
		{
			float num = (0f - ((Component)Arwen).transform.InverseTransformDirection(hand.Input.VelLinearWorld).y) * 120f;
			((Component)this).transform.localEulerAngles = new Vector3(0f, 0f, ((Component)this).transform.localEulerAngles.z + num);
			m_fakeAngularVel = Mathf.Clamp(num, -360f, 360f);
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//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_002f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Arwen != (Object)null)
		{
			m_fakeAngularVel = Mathf.Clamp((0f - ((Component)Arwen).transform.InverseTransformDirection(hand.Input.VelLinearWorld).y) * 120f, -360f, 360f);
			Arwen.SyncChamberFromCylinder();
		}
		((FVRInteractiveObject)this).EndInteraction(hand);
	}

	public override void FVRUpdate()
	{
		//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_0052: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).FVRUpdate();
		if (!((FVRInteractiveObject)this).IsHeld && Mathf.Abs(m_fakeAngularVel) > 0.01f)
		{
			((Component)this).transform.localEulerAngles = new Vector3(0f, 0f, ((Component)this).transform.localEulerAngles.z + m_fakeAngularVel);
			m_fakeAngularVel = Mathf.Lerp(m_fakeAngularVel, 0f, Time.deltaTime * 0.8f);
		}
		else if (!((FVRInteractiveObject)this).IsHeld)
		{
			m_fakeAngularVel = 0f;
		}
	}

	public int GetClosestChamberIndex()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f - ((Component)this).transform.localEulerAngles.z;
		num += 360f / (float)numChambers * 0.5f;
		num = Mathf.Repeat(num, 360f);
		return Mathf.Clamp(Mathf.CeilToInt(num / (360f / (float)numChambers)) - 1, 0, numChambers - 1);
	}

	public Quaternion GetLocalRotationFromCylinder(int cylinder)
	{
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Repeat((float)cylinder * (360f / (float)numChambers) * -1f, 360f);
		return Quaternion.Euler(0f, 0f, num);
	}
}
public class AdvanceCloseBoltRelease : FVRInteractiveObject
{
	public enum SlapDirectionAxis
	{
		Forward,
		NegativeForward,
		Right,
		NegativeRight,
		Up,
		NegativeUp
	}

	[Header("Firearm References")]
	[Tooltip("Parent closed bolt weapon component.")]
	public ClosedBoltWeapon Weapon;

	[Tooltip("Transform used as reference for directional slap normal calculation.")]
	public Transform SlapNormalTransform;

	[Header("Slap Detection Config")]
	[Tooltip("Enable velocity and optional angle thresholds for physical controller slaps.")]
	public bool EnableSlapDetection = true;

	[Tooltip("Minimum hand velocity required to register as a slap.")]
	public float MinSlapSpeed = 0.5f;

	[Tooltip("Require hand movement to align with a specific surface normal vector.")]
	public bool CheckSlapDirection;

	[Tooltip("Axis direction representing the inward slap normal.")]
	public SlapDirectionAxis SlapAxis = SlapDirectionAxis.NegativeForward;

	[Tooltip("Minimum dot product alignment required if directional check is enabled.")]
	public float SlapAngleThreshold = 0.2f;

	[Tooltip("Cooldown period after a slap to prevent double-triggering.")]
	public float SlapCooldownDuration = 0.2f;

	[Header("Grab And Click Config")]
	[Tooltip("Allow grabbing the button directly and pressing a button to release the bolt.")]
	public bool EnableGrabAndClick = true;

	private float m_slapCooldownTimer;

	public override void Awake()
	{
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)Weapon == (Object)null)
		{
			Weapon = ((Component)this).GetComponentInParent<ClosedBoltWeapon>();
		}
		if ((Object)(object)SlapNormalTransform == (Object)null)
		{
			SlapNormalTransform = ((Component)this).transform;
		}
	}

	private void OnDisable()
	{
		m_slapCooldownTimer = 0f;
	}

	public override void Poke(FVRViveHand hand)
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: 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)
		if ((Object)(object)hand == (Object)null || (Object)(object)Weapon == (Object)null || (Object)(object)Weapon.Bolt == (Object)null || !Weapon.Bolt.IsBoltLocked() || ((Object)(object)((FVRInteractiveObject)Weapon).m_hand != (Object)null && (Object)(object)hand == (Object)(object)((FVRInteractiveObject)Weapon).m_hand) || m_slapCooldownTimer > 0f)
		{
			return;
		}
		if (EnableSlapDetection)
		{
			Vector3 velLinearWorld = hand.Input.VelLinearWorld;
			if (((Vector3)(ref velLinearWorld)).magnitude < MinSlapSpeed)
			{
				return;
			}
			if (CheckSlapDirection && (Object)(object)SlapNormalTransform != (Object)null)
			{
				Vector3 inwardNormal = GetInwardNormal();
				float num = Vector3.Dot(((Vector3)(ref velLinearWorld)).normalized, inwardNormal);
				if (num < SlapAngleThreshold)
				{
					return;
				}
			}
		}
		ReleaseBoltAction(hand);
		m_slapCooldownTimer = SlapCooldownDuration;
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		((FVRInteractiveObject)this).UpdateInteraction(hand);
		if (EnableGrabAndClick && !((Object)(object)Weapon == (Object)null) && !((Object)(object)Weapon.Bolt == (Object)null) && Weapon.Bolt.IsBoltLocked() && !((Object)(object)hand == (Object)null) && IsReleaseInputPressed(hand))
		{
			ReleaseBoltAction(hand);
			((FVRInteractiveObject)this).EndInteraction(hand);
		}
	}

	public override void FVRUpdate()
	{
		((FVRInteractiveObject)this).FVRUpdate();
		if (m_slapCooldownTimer > 0f)
		{
			m_slapCooldownTimer -= Time.deltaTime;
			if (m_slapCooldownTimer < 0f)
			{
				m_slapCooldownTimer = 0f;
			}
		}
	}

	private bool IsReleaseInputPressed(FVRViveHand hand)
	{
		if ((Object)(object)hand == (Object)null)
		{
			return false;
		}
		if (hand.IsInStreamlinedMode)
		{
			return hand.Input.AXButtonDown || hand.Input.BYButtonDown || hand.Input.TriggerDown;
		}
		return hand.Input.TouchpadDown || hand.Input.TriggerDown;
	}

	private void ReleaseBoltAction(FVRViveHand hand)
	{
		if ((Object)(object)Weapon != (Object)null && (Object)(object)Weapon.Bolt != (Object)null && Weapon.Bolt.IsBoltLocked())
		{
			Weapon.Bolt.ReleaseBolt();
			if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
			}
		}
	}

	private Vector3 GetInwardNormal()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_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)
		//IL_0069: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)SlapNormalTransform == (Object)null)
		{
			return Vector3.forward;
		}
		return (Vector3)(SlapAxis switch
		{
			SlapDirectionAxis.Forward => SlapNormalTransform.forward, 
			SlapDirectionAxis.NegativeForward => -SlapNormalTransform.forward, 
			SlapDirectionAxis.Right => SlapNormalTransform.right, 
			SlapDirectionAxis.NegativeRight => -SlapNormalTransform.right, 
			SlapDirectionAxis.Up => SlapNormalTransform.up, 
			SlapDirectionAxis.NegativeUp => -SlapNormalTransform.up, 
			_ => -SlapNormalTransform.forward, 
		});
	}
}
public class BouncingBetty : PinnedGrenade
{
	[Header("Betty Settings")]
	public float BounceHeight = 2f;

	public float ExplosionDelay = 0.5f;

	public float ArmDelay = 0.4f;

	[Header("Proximity Settings")]
	public float ProxRange = 3f;

	public LayerMask LM_Prox;

	[Header("Parts")]
	public GameObject BottomPartToDisable;

	public AudioEvent LaunchSound;

	public AudioEvent ArmSound;

	[Header("Stick Settings")]
	[Tooltip("Point Z to direction to check. If an layer object is within 0.05m from the raycastdir, it will lock.")]
	public Transform RaycastDir;

	public LayerMask StickLayer;

	[Tooltip("If velocity is below this, it will allow it to lock.")]
	public float MinStickVelocity = 0.1f;

	private bool isArmed = false;

	private bool isSet = false;

	private bool hasBounced = false;

	private bool beginCountdown = false;

	private float timer = 0f;

	private bool timerReached = false;

	private bool hasExploded = false;

	private bool isPinPulled = false;

	private bool isStuck = false;

	private bool isLocked = false;

	private Vector3 stuckNormal;

	private Transform stuckToSurface;

	public override void Awake()
	{
		((PinnedGrenade)this).Awake();
		base.m_isLeverReleased = true;
		base.m_isFused = false;
		base.m_fuseTime = float.MaxValue;
		base.m_startFuseTime = float.MaxValue;
		base.FuseOnSpawn = false;
		if ((Object)(object)base.FakeHandle != (Object)null)
		{
			base.FakeHandle.SetActive(false);
		}
		if ((Object)(object)base.RealHandle != (Object)null)
		{
			base.RealHandle.SetActive(false);
		}
		if ((Object)(object)base.LeverJoint != (Object)null)
		{
			Object.Destroy((Object)(object)base.LeverJoint);
		}
	}

	public override void FVRUpdate()
	{
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		((PinnedGrenade)this).FVRUpdate();
		if (base.m_rings.Count > 0)
		{
			isPinPulled = true;
			foreach (PinnedGrenadeRing ring in base.m_rings)
			{
				if (!ring.HasPinDetached())
				{
					isPinPulled = false;
				}
			}
		}
		if (!isPinPulled || isStuck || !((FVRInteractiveObject)this).IsHeld)
		{
		}
		if (isStuck && !beginCountdown && !isArmed)
		{
			BeginArming();
		}
		if (beginCountdown && !timerReached)
		{
			timer += Time.deltaTime;
			if (timer >= ArmDelay)
			{
				isSet = true;
				beginCountdown = false;
				timerReached = true;
				isArmed = true;
			}
		}
		if (isSet && isArmed && !hasBounced && !hasExploded)
		{
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, ProxRange, LayerMask.op_Implicit(LM_Prox));
			if (array.Length > 0)
			{
				hasBounced = true;
				((MonoBehaviour)this).StartCoroutine(BounceAndExplode());
			}
		}
	}

	public override void OnCollisionEnter(Collision collision)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		if (isPinPulled && !isStuck && !((FVRInteractiveObject)this).IsHeld && ((1 << collision.gameObject.layer) & (LayerMask.GetMask(new string[1] { "Default" }) | LayerMask.GetMask(new string[1] { "Environment" }))) != 0)
		{
			ContactPoint val = collision.contacts[0];
			((Component)this).transform.position = ((ContactPoint)(ref val)).point;
			stuckNormal = ((ContactPoint)(ref val)).normal;
			stuckToSurface = collision.transform;
			Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.isKinematic = true;
				component.velocity = Vector3.zero;
				component.angularVelocity = Vector3.zero;
			}
			isStuck = true;
			if ((Object)(object)BottomPartToDisable != (Object)null)
			{
				BottomPartToDisable.SetActive(false);
			}
		}
	}

	private void BeginArming()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		beginCountdown = true;
		timer = 0f;
		if (ArmSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)0, ArmSound, ((Component)this).transform.position);
		}
	}

	private IEnumerator BounceAndExplode()
	{
		Rigidbody rb = ((Component)this).GetComponent<Rigidbody>();
		if ((Object)(object)rb == (Object)null)
		{
			rb = ((Component)this).gameObject.AddComponent<Rigidbody>();
		}
		rb.isKinematic = false;
		float bounceVel = Mathf.Sqrt(19.62f * BounceHeight);
		rb.velocity = Vector3.zero;
		rb.AddForce(Vector3.up * bounceVel, (ForceMode)2);
		if (LaunchSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)0, LaunchSound, ((Component)this).transform.position);
		}
		yield return (object)new WaitForSeconds(ExplosionDelay);
		TriggerExplosion();
	}

	private void TriggerExplosion()
	{
		//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)
		if (hasExploded)
		{
			return;
		}
		hasExploded = true;
		for (int i = 0; i < base.SpawnOnSplode.Count; i++)
		{
			GameObject val = Object.Instantiate<GameObject>(base.SpawnOnSplode[i], ((Component)this).transform.position, Quaternion.identity);
			Explosion component = val.GetComponent<Explosion>();
			if ((Object)(object)component != (Object)null)
			{
				component.IFF = base.IFF;
			}
			ExplosionSound component2 = val.GetComponent<ExplosionSound>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.IFF = base.IFF;
			}
			GrenadeExplosion component3 = val.GetComponent<GrenadeExplosion>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.IFF = base.IFF;
			}
		}
		if ((Object)(object)base.SmokeEmitter != (Object)null)
		{
			base.SmokeEmitter.Engaged = true;
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	private void OnDrawGizmosSelected()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		Gizmos.color = Color.red;
		Gizmos.DrawWireSphere(((Component)this).transform.position, ProxRange);
	}

	public override void FVRFixedUpdate()
	{
		//IL_004e: 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_007e: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		((PinnedGrenade)this).FVRFixedUpdate();
		base.m_isImpactFuseActive = false;
		base.m_impactFuseBurnDown = float.MaxValue;
		Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
		if ((Object)(object)component != (Object)null && !isStuck && isPinPulled && !((FVRInteractiveObject)this).IsHeld)
		{
			Vector3 velocity = component.velocity;
			RaycastHit val = default(RaycastHit);
			if (((Vector3)(ref velocity)).magnitude <= MinStickVelocity && (Object)(object)RaycastDir != (Object)null && Physics.Raycast(RaycastDir.position, RaycastDir.forward, ref val, 2f, LayerMask.op_Implicit(StickLayer)))
			{
				isStuck = true;
				isLocked = true;
				component.isKinematic = true;
				component.velocity = Vector3.zero;
				component.angularVelocity = Vector3.zero;
				((Component)this).transform.position = ((RaycastHit)(ref val)).point;
				stuckNormal = ((RaycastHit)(ref val)).normal;
				stuckToSurface = ((RaycastHit)(ref val)).transform;
				if ((Object)(object)BottomPartToDisable != (Object)null)
				{
					BottomPartToDisable.SetActive(false);
				}
			}
		}
		if (isLocked && ((FVRInteractiveObject)this).IsHeld)
		{
			isLocked = false;
			if ((Object)(object)component != (Object)null)
			{
				component.isKinematic = false;
			}
		}
	}
}
[Serializable]
public class GrenadeExplosionMapping
{
	[Tooltip("The ScriptableObject asset name of the rifle grenade round (e.g., 'RifleGrenade_HEAT' or 'M9_Frag').")]
	public string RoundNameID;

	[Tooltip("The custom explosion prefabs to trigger if this specific grenade is loaded and shot with a live round.")]
	public List<GameObject> ExplosionPrefabs = new List<GameObject>();
}
public class RifleGrenadeAdapterFixed : MuzzleDevice
{
	private enum WeaponActionType
	{
		None,
		OpenBolt,
		ClosedBolt,
		Handgun
	}

	[Header("Rifle Grenade Adapter Config")]
	public FVRFireArmChamber GrenadeChamber;

	public Transform GrenadeMuzzle;

	public float VelocityMultiplier = 1f;

	public float RangeOverride = -1f;

	public FVRFireArmRecoilProfile OverrideRecoilProfile;

	public FVRFireArmRecoilProfile OverrideRecoilProfileStocked;

	public AudioEvent GrenadeShot;

	[Tooltip("Normally, only caseless rounds will be removed from the chamber when fired. Enabling this will also remove fired cased rounds from the chamber automatically.")]
	public bool DoesClearCasedRounds = false;

	[Header("Safe Rounds Settings (\"Blank Firing rounds\")")]
	[Tooltip("Do you need to use a specific round class to not make the grenade go boom on the muzzle?\nLike Blank firing rounds and such.")]
	public bool UsesSafeRoundClass = false;

	public FireArmRoundClass SafeRoundClass;

	[Tooltip("Fallback explosion prefabs to spawn on the barrel if the loaded grenade's submunitions cannot be resolved statically.")]
	public List<GameObject> DefaultExplosionPrefabs = new List<GameObject>();

	[Header("Custom Grenade Detonation Map")]
	[Tooltip("List of specific rifle grenades and their custom on-barrel explosion prefabs.")]
	public List<GrenadeExplosionMapping> CustomDetonationMaps = new List<GrenadeExplosionMapping>();

	[Header("Gas Cutoff Configuration")]
	[Tooltip("If enabled, the player can manually shut off the gas system using the valve component.")]
	public bool SupportsManualGasCutoff = true;

	[Tooltip("If true, chambering a blank round will automatically cut off the gas, requiring a manual cycle.")]
	public bool AutoCutoffOnBlank = true;

	[Header("Gas Valve Animation & Sound")]
	public Transform GasValveGeo;

	[Tooltip("How fast the transition occurs (1 / duration in seconds). E.g., 2 means 0.5 seconds.")]
	public float TransitionSpeed = 2f;

	public AudioEvent AudEvent_ValveOpen;

	public AudioEvent AudEvent_ValveClose;

	[Header("Valve Local Transformations (Open vs. Closed)")]
	[Tooltip("The local position of the valve when the gas system is OPEN (normal weapon cycling).")]
	public Vector3 OpenLocalPosition = Vector3.zero;

	[Tooltip("The local position of the valve when the gas system is CLOSED (manual cycling required).")]
	public Vector3 ClosedLocalPosition = Vector3.zero;

	[Space(5f)]
	[Tooltip("The local Euler angles of the valve when the gas system is OPEN (normal weapon cycling).")]
	public Vector3 OpenLocalRotation = Vector3.zero;

	[Tooltip("The local Euler angles of the valve when the gas system is CLOSED (manual cycling required).")]
	public Vector3 ClosedLocalRotation = Vector3.zero;

	[Header("One-Handed Firing Penalty")]
	[Tooltip("If enabled, firing the grenade one-handed (without stabilization) forces the player to drop the gun.")]
	public bool ForceDropOneHanded = true;

	[Tooltip("If true, shoulder-bracing (stock pressed to chest) bypasses the one-handed drop penalty.")]
	public bool AllowShoulderStabilization = true;

	[Tooltip("How violently the gun kicks backward out of the hands during a one-handed drop.")]
	public float RearwardLurchForce = 12f;

	private Vector3 _origMuzzlePos;

	private Quaternion _origMuzzleRot;

	private FVRFireArm _fireArm;

	private FVRFireArmRecoilProfile _origRecoilProfile;

	private FVRFireArmRecoilProfile _origRecoilProfileStocked;

	private bool _recoilProfileSet = false;

	private bool _isFiringGrenade = false;

	private bool _isGasCutoffActive = false;

	private bool _isBoltSpeedModified = false;

	private float _prevBoltSpeedRearward = 0f;

	private float _valveProgress = 0f;

	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)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		((MuzzleDevice)this).Awake();
		_origMuzzlePos = base.Muzzle.localPosition;
		_origMuzzleRot = base.Muzzle.localRotation;
		_valveProgress = 0f;
		OpenScripts2_BasePlugin.ProjectileFiredEvent += new ProjectileFired(ProjectileFiredEvent);
	}

	private void ProjectileFiredEvent(FVRFireArm fireArm, ref BallisticProjectile projectile)
	{
		if (!_isFiringGrenade && !((Object)(object)((FVRFireArmAttachment)this).curMount == (Object)null) && !((Object)(object)((FVRFireArmAttachment)this).curMount.GetRootMount() == (Object)null) && !((Object)(object)GrenadeChamber == (Object)null) && (Object)(object)fireArm == (Object)(object)((FVRFireArmAttachment)this).curMount.GetRootMount().MyObject && GrenadeChamber.IsFull)
		{
			Object.Destroy((Object)(object)((Component)projectile).gameObject);
		}
	}

	public override void OnDestroy()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		OpenScripts2_BasePlugin.ProjectileFiredEvent -= new ProjectileFired(ProjectileFiredEvent);
		((FVRPhysicalObject)this).OnDestroy();
	}

	public override void FVRUpdate()
	{
		((FVRPhysicalObject)this).FVRUpdate();
		if ((Object)(object)((FVRFireArmAttachment)this).curMount != (Object)null && (Object)(object)_fireArm == (Object)null)
		{
			ref FVRFireArm fireArm = ref _fireArm;
			FVRPhysicalObject myObject = ((FVRFireArmAttachment)this).curMount.GetRootMount().MyObject;
			fireArm = (FVRFireArm)(object)((myObject is FVRFireArm) ? myObject : null);
		}
		else if ((Object)(object)((FVRFireArmAttachment)this).curMount == (Object)null && (Object)(object)_fireArm != (Object)null)
		{
			OnDetach();
		}
		if ((Object)(object)GrenadeChamber == (Object)null)
		{
			return;
		}
		if (GrenadeChamber.IsFull)
		{
			if (!_recoilProfileSet && (Object)(object)_fireArm != (Object)null && (Object)(object)OverrideRecoilProfile != (Object)null)
			{
				_origRecoilProfile = _fireArm.RecoilProfile;
				_origRecoilProfileStocked = _fireArm.RecoilProfileStocked;
				if ((Object)(object)OverrideRecoilProfileStocked != (Object)null)
				{
					_fireArm.RecoilProfile = OverrideRecoilProfile;
					_fireArm.RecoilProfileStocked = OverrideRecoilProfileStocked;
				}
				else
				{
					_fireArm.RecoilProfile = OverrideRecoilProfile;
					_fireArm.RecoilProfileStocked = OverrideRecoilProfile;
				}
				_recoilProfileSet = true;
			}
			if (GrenadeChamber.IsSpent && (GrenadeChamber.GetRound().IsCaseless || DoesClearCasedRounds))
			{
				GrenadeChamber.Unload();
			}
		}
		else if (_recoilProfileSet && (Object)(object)_fireArm != (Object)null)
		{
			_fireArm.RecoilProfile = _origRecoilProfile;
			_fireArm.RecoilProfileStocked = _origRecoilProfileStocked;
			_recoilProfileSet = false;
		}
		UpdateGasCutoffState();
		UpdateValveAnimation();
	}

	private void OnDetach()
	{
		if (_recoilProfileSet && (Object)(object)_fireArm != (Object)null)
		{
			_fireArm.RecoilProfile = _origRecoilProfile;
			_fireArm.RecoilProfileStocked = _origRecoilProfileStocked;
			_recoilProfileSet = false;
		}
		if (_isBoltSpeedModified && (Object)(object)_fireArm != (Object)null)
		{
			WeaponActionType weaponActionType = GetWeaponActionType(_fireArm);
			if (weaponActionType != WeaponActionType.None)
			{
				SetBoltSpeedRearward(_fireArm, weaponActionType, _prevBoltSpeedRearward);
			}
			_isBoltSpeedModified = false;
		}
		_fireArm = null;
	}

	public void ToggleGasCutoff()
	{
		//IL_0077: 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)
		if (SupportsManualGasCutoff)
		{
			_isGasCutoffActive = !_isGasCutoffActive;
			AudioEvent val = ((!_isGasCutoffActive) ? AudEvent_ValveOpen : AudEvent_ValveClose);
			if ((Object)(object)_fireArm != (Object)null)
			{
				_fireArm.PlayAudioAsHandling(val, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, val, ((Component)this).transform.position);
			}
		}
	}

	private void UpdateGasCutoffState()
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_fireArm == (Object)null)
		{
			if (_isBoltSpeedModified)
			{
				_isBoltSpeedModified = false;
			}
			return;
		}
		WeaponActionType weaponActionType = GetWeaponActionType(_fireArm);
		if (weaponActionType == WeaponActionType.None)
		{
			return;
		}
		bool flag = false;
		FVRFireArmChamber currentChamber = OpenScripts2_BasePlugin.GetCurrentChamber(_fireArm);
		if ((Object)(object)currentChamber != (Object)null && (Object)(object)currentChamber.m_round != (Object)null && currentChamber.m_round.RoundClass == SafeRoundClass)
		{
			flag = true;
		}
		if (_isGasCutoffActive || (flag && AutoCutoffOnBlank))
		{
			if (!_isBoltSpeedModified)
			{
				_prevBoltSpeedRearward = GetBoltSpeedRearward(_fireArm, weaponActionType);
				SetBoltSpeedRearward(_fireArm, weaponActionType, 0f);
				_isBoltSpeedModified = true;
			}
		}
		else if (_isBoltSpeedModified)
		{
			SetBoltSpeedRearward(_fireArm, weaponActionType, _prevBoltSpeedRearward);
			_isBoltSpeedModified = false;
		}
	}

	private void UpdateValveAnimation()
	{
		//IL_006f: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)GasValveGeo == (Object)null))
		{
			float num = ((!_isGasCutoffActive) ? 0f : 1f);
			if (Mathf.Abs(_valveProgress - num) > 0.001f)
			{
				_valveProgress = Mathf.MoveTowards(_valveProgress, num, Time.deltaTime * TransitionSpeed);
				GasValveGeo.localPosition = Vector3.Lerp(OpenLocalPosition, ClosedLocalPosition, _valveProgress);
				GasValveGeo.localRotation = Quaternion.Slerp(Quaternion.Euler(OpenLocalRotation), Quaternion.Euler(ClosedLocalRotation), _valveProgress);
			}
		}
	}

	public override void OnShot(FVRFireArm f, FVRTailSoundClass tailClass)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		((MuzzleDevice)this).OnShot(f, tailClass);
		FireGrenade();
	}

	private void FireGrenade()
	{
		//IL_0424: Unknown result type (might be due to invalid IL or missing references)
		//IL_043d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_044c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d5: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_049e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0501: Unknown result type (might be due to invalid IL or missing references)
		//IL_0508: Unknown result type (might be due to invalid IL or missing references)
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_053c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0572: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cc: 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_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_03ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_040e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)GrenadeChamber == (Object)null || (Object)(object)_fireArm == (Object)null)
		{
			return;
		}
		if (UsesSafeRoundClass && GrenadeChamber.IsFull && !GrenadeChamber.IsSpent)
		{
			FVRFireArmChamber currentChamber = OpenScripts2_BasePlugin.GetCurrentChamber(_fireArm);
			if ((Object)(object)currentChamber != (Object)null && (Object)(object)currentChamber.m_round != (Object)null && currentChamber.m_round.RoundClass != SafeRoundClass)
			{
				FVRFireArmRound loadedGrenade = GrenadeChamber.GetRound();
				List<GameObject> list = new List<GameObject>();
				if ((Object)(object)loadedGrenade != (Object)null && CustomDetonationMaps != null && CustomDetonationMaps.Count > 0)
				{
					GrenadeExplosionMapping grenadeExplosionMapping = CustomDetonationMaps.FirstOrDefault((GrenadeExplosionMapping map) => !string.IsNullOrEmpty(map.RoundNameID) && ((Object)loadedGrenade).name.IndexOf(map.RoundNameID, StringComparison.OrdinalIgnoreCase) >= 0);
					if (grenadeExplosionMapping != null && grenadeExplosionMapping.ExplosionPrefabs != null && grenadeExplosionMapping.ExplosionPrefabs.Count > 0)
					{
						list = grenadeExplosionMapping.ExplosionPrefabs;
					}
				}
				if (list.Count == 0 && DefaultExplosionPrefabs != null && DefaultExplosionPrefabs.Count > 0)
				{
					list = DefaultExplosionPrefabs;
				}
				if (list.Count == 0)
				{
					BallisticProjectile val = ((!((Object)(object)loadedGrenade != (Object)null) || !((Object)(object)loadedGrenade.BallisticProjectilePrefab != (Object)null)) ? null : loadedGrenade.BallisticProjectilePrefab.GetComponent<BallisticProjectile>());
					if ((Object)(object)val != (Object)null && val.Submunitions != null)
					{
						foreach (Submunition item in val.Submunitions.Where((Submunition submun) => (int)submun.Type == 0))
						{
							if (item.Prefabs == null)
							{
								continue;
							}
							foreach (GameObject prefab in item.Prefabs)
							{
								if ((Object)(object)prefab != (Object)null)
								{
									list.Add(prefab);
								}
							}
						}
					}
				}
				foreach (GameObject item2 in list)
				{
					if ((Object)(object)item2 != (Object)null)
					{
						Object.Instantiate<GameObject>(item2, ((Component)this).transform.TransformPoint(_origMuzzlePos), ((Component)this).transform.rotation);
					}
				}
				GrenadeChamber.Unload();
				return;
			}
		}
		if (!GrenadeChamber.Fire())
		{
			return;
		}
		if (ForceDropOneHanded && !_fireArm.IsTwoHandStabilized() && !_fireArm.IsForegripStabilized() && (!AllowShoulderStabilization || !_fireArm.IsShoulderStabilized()))
		{
			FVRAlternateGrip altGrip = ((FVRPhysicalObject)_fireArm).AltGrip;
			((FVRInteractiveObject)_fireArm).ForceBreakInteraction();
			if ((Object)(object)altGrip != (Object)null)
			{
				((FVRInteractiveObject)altGrip).ForceBreakInteraction();
			}
			Rigidbody rootRigidbody = ((FVRPhysicalObject)_fireArm).RootRigidbody;
			if ((Object)(object)rootRigidbody != (Object)null && !rootRigidbody.isKinematic)
			{
				Vector3 val2 = -GrenadeMuzzle.forward * RearwardLurchForce + Vector3.up * (RearwardLurchForce * 0.33f);
				rootRigidbody.AddForce(val2, (ForceMode)1);
				Vector3 val3 = Random.onUnitSphere * (RearwardLurchForce * 0.66f);
				rootRigidbody.AddTorque(val3, (ForceMode)1);
			}
		}
		float num = _fireArm.GetCombinedFixedDrop(base.MechanicalAccuracy) * 0.0166667f;
		Vector2 val4 = _fireArm.GetCombinedFixedDrift(base.MechanicalAccuracy) * 0.0166667f;
		_isFiringGrenade = true;
		for (int num2 = 0; num2 < GrenadeChamber.GetRound().NumProjectiles; num2++)
		{
			float num3 = GrenadeChamber.GetRound().ProjectileSpread + base.m_mechanicalAccuracy;
			if ((Object)(object)GrenadeChamber.GetRound().BallisticProjectilePrefab != (Object)null)
			{
				Vector3 val5 = GrenadeMuzzle.forward * 0.005f;
				GameObject val6 = Object.Instantiate<GameObject>(GrenadeChamber.GetRound().BallisticProjectilePrefab, GrenadeMuzzle.position - val5, GrenadeMuzzle.rotation);
				Vector2 val7 = (Random.insideUnitCircle + Random.insideUnitCircle + Random.insideUnitCircle) * (1f / 3f) * num3;
				val6.transform.Rotate(new Vector3(val7.x + val4.y + num, val7.y + val4.x, 0f));
				BallisticProjectile component = val6.GetComponent<BallisticProjectile>();
				component.Fire(component.MuzzleVelocityBase * GrenadeChamber.ChamberVelocityMultiplier * VelocityMultiplier, val6.transform.forward, _fireArm, true);
				if (RangeOverride > 0f)
				{
					component.ForceSetMaxDist(RangeOverride);
				}
			}
		}
		_isFiringGrenade = false;
		SM.PlayCoreSound((FVRPooledAudioType)1, GrenadeShot, GrenadeMuzzle.position);
	}

	private WeaponActionType GetWeaponActionType(FVRFireArm weapon)
	{
		if (weapon is OpenBoltReceiver)
		{
			return WeaponActionType.OpenBolt;
		}
		if (weapon is ClosedBoltWeapon)
		{
			return WeaponActionType.ClosedBolt;
		}
		if (weapon is Handgun)
		{
			return WeaponActionType.Handgun;
		}
		return WeaponActionType.None;
	}

	private float GetBoltSpeedRearward(FVRFireArm weapon, WeaponActionType type)
	{
		switch (type)
		{
		case WeaponActionType.OpenBolt:
		{
			OpenBoltReceiver val3 = (OpenBoltReceiver)(object)((weapon is OpenBoltReceiver) ? weapon : null);
			return (!((Object)(object)val3 != (Object)null) || !((Object)(object)val3.Bolt != (Object)null)) ? 0f : val3.Bolt.BoltSpeed_Rearward;
		}
		case WeaponActionType.ClosedBolt:
		{
			ClosedBoltWeapon val2 = (ClosedBoltWeapon)(object)((weapon is ClosedBoltWeapon) ? weapon : null);
			return (!((Object)(object)val2 != (Object)null) || !((Object)(object)val2.Bolt != (Object)null)) ? 0f : val2.Bolt.Speed_Rearward;
		}
		case WeaponActionType.Handgun:
		{
			Handgun val = (Handgun)(object)((weapon is Handgun) ? weapon : null);
			return (!((Object)(object)val != (Object)null) || !((Object)(object)val.Slide != (Object)null)) ? 0f : val.Slide.Speed_Rearward;
		}
		default:
			return 0f;
		}
	}

	private void SetBoltSpeedRearward(FVRFireArm weapon, WeaponActionType type, float speed)
	{
		switch (type)
		{
		case WeaponActionType.OpenBolt:
		{
			OpenBoltReceiver val3 = (OpenBoltReceiver)(object)((weapon is OpenBoltReceiver) ? weapon : null);
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.Bolt != (Object)null)
			{
				val3.Bolt.BoltSpeed_Rearward = speed;
			}
			break;
		}
		case WeaponActionType.ClosedBolt:
		{
			ClosedBoltWeapon val2 = (ClosedBoltWeapon)(object)((weapon is ClosedBoltWeapon) ? weapon : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.Bolt != (Object)null)
			{
				val2.Bolt.Speed_Rearward = speed;
			}
			break;
		}
		case WeaponActionType.Handgun:
		{
			Handgun val = (Handgun)(object)((weapon is Handgun) ? weapon : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.Slide != (Object)null)
			{
				val.Slide.Speed_Rearward = speed;
			}
			break;
		}
		}
	}
}
public class RifleGrenadeGasValve : FVRInteractiveObject
{
	public RifleGrenadeAdapterFixed Adapter;

	public override void SimpleInteraction(FVRViveHand hand)
	{
		((FVRInteractiveObject)this).SimpleInteraction(hand);
		if ((Object)(object)Adapter != (Object)null)
		{
			Adapter.ToggleGasCutoff();
		}
	}
}
public class Idle : StateMachineBehaviour
{
}
public class AdvanceFireSelector : FVRInteractiveObject
{
	public enum InteractionMode
	{
		DragAndSnap,
		ClickCycle,
		Hybrid
	}

	public enum FireModeType
	{
		Safe,
		Single,
		Burst,
		FullAuto
	}

	[Serializable]
	public class SelectorModeDefinition
	{
		[Tooltip("Target rotation angle or translation offset for this mode.")]
		public float SelectorPosition;

		[Tooltip("Fire mode type: Safe, Single, Burst, FullAuto.")]
		public FireModeType ModeType = FireModeType.Single;

		[Tooltip("Number of shots per burst if ModeType is Burst.")]
		public int BurstAmount = 3;

		[Tooltip("If true on BoltActionRifle, locks the bolt handle down while on this mode.")]
		public bool IsBoltLocked;
	}

	[Header("Firearm References")]
	[Tooltip("Parent firearm component (BoltActionRifle, OpenBoltReceiver, or ClosedBoltWeapon).")]
	public FVRFireArm FireArm;

	[Tooltip("Reference root transform used for local axis orientation (defaults to weapon receiver).")]
	public Transform RootTransform;

	[Tooltip("Visual safety piece that rotates or slides.")]
	public Transform DisplayPiece;

	[Tooltip("Optional ambidextrous piece that mirrors movement.")]
	public Transform SecondaryDisplayPiece;

	[Header("Definable Selector Modes")]
	[Tooltip("Custom list of selector modes, positions, and firing behaviors.")]
	public SelectorModeDefinition[] Modes;

	[Tooltip("Current active mode index in the Modes array.")]
	public int CurModeIndex;

	[Header("Motion Configuration")]
	[Tooltip("Style of interpolation: Rotation for flags/levers, Translate for push tabs.")]
	public InterpStyle InterpStyle = (InterpStyle)1;

	[Tooltip("Axis along which the safety rotates or slides.")]
	public Axis Axis = (Axis)2;

	[Tooltip("Interaction behavior mode.")]
	public InteractionMode Mode = InteractionMode.Hybrid;

	[Tooltip("Angle or distance threshold within which the safety snaps to detent.")]
	public float MagneticSnapThreshold = 8f;

	[Tooltip("Degrees of rotation required to switch from click mode to drag mode in Hybrid.")]
	public float AngularDragThreshold = 3f;

	[Tooltip("Distance hand must travel to trigger drag instead of tap-cycle in translation mode.")]
	public float ClickDragDistanceThreshold = 0.015f;

	[Tooltip("Speed at which safety returns to resting position when not held.")]
	public float ReturnSpeed = 25f;

	[Tooltip("Invert input motion direction.")]
	public bool InvertDirection;

	[Header("Safety Bolt Constraint Config")]
	[Tooltip("Enable partial bolt movement or jiggle when weapon is on Safe.")]
	public bool ConstrainBoltOnSafe;

	[Tooltip("Maximum allowed bolt handle rotation on bolt action rifles when on Safe.")]
	public float SafeHandleMaxRot = 12f;

	[Tooltip("Maximum allowed rearward bolt travel percentage on closed/open bolt weapons when on Safe.")]
	public float SafeBoltTravelPercent = 0.2f;

	[Header("Debug")]
	[Tooltip("Print real-time selector state changes and angles to the console.")]
	public bool EnableDebugLogs;

	private BoltActionRifle m_boltAction;

	private OpenBoltReceiver m_openBolt;

	private ClosedBoltWeapon m_closedBolt;

	private float m_currentValue;

	private float m_targetValue;

	private float m_lastHandAngle;

	private float m_grabStartValue;

	private bool m_isActivelyDragging;

	private float m_minLimit;

	private float m_maxLimit;

	private float m_originalHandleMaxRot;

	private bool m_hasStoredHandleMaxRot;

	private Vector3 m_initialDisplayLocalPos;

	private Quaternion m_initialDisplayLocalRot;

	private Vector3 m_initialSecondaryLocalPos;

	private Quaternion m_initialSecondaryLocalRot;

	private bool m_isInitialized;

	public override void Awake()
	{
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)FireArm == (Object)null)
		{
			FireArm = ((Component)this).GetComponentInParent<FVRFireArm>();
		}
		DetectFirearmType();
		if (Mode == InteractionMode.ClickCycle)
		{
			base.IsSimpleInteract = true;
		}
		if ((Object)(object)DisplayPiece == (Object)null)
		{
			DisplayPiece = ((Component)this).transform;
		}
		if ((Object)(object)RootTransform == (Object)null || (Object)(object)RootTransform == (Object)(object)DisplayPiece || (Object)(object)RootTransform == (Object)(object)((Component)this).transform)
		{
			RootTransform = (((Object)(object)((Component)this).transform.parent != (Object)null) ? ((Component)this).transform.parent : ((!((Object)(object)FireArm != (Object)null)) ? ((Component)this).transform : ((Component)FireArm).transform));
		}
		if ((Object)(object)DisplayPiece != (Object)null)
		{
			m_initialDisplayLocalPos = DisplayPiece.localPosition;
			m_initialDisplayLocalRot = DisplayPiece.localRotation;
		}
		if ((Object)(object)SecondaryDisplayPiece != (Object)null)
		{
			m_initialSecondaryLocalPos = SecondaryDisplayPiece.localPosition;
			m_initialSecondaryLocalRot = SecondaryDisplayPiece.localRotation;
		}
		ComputeModeLimits();
		if (Modes != null && Modes.Length > 0)
		{
			CurModeIndex = Mathf.Clamp(CurModeIndex, 0, Modes.Length - 1);
			m_currentValue = Modes[CurModeIndex].SelectorPosition;
			m_targetValue = m_currentValue;
			ApplyModeToWeapon(CurModeIndex, null, isInitialization: true);
			ApplyTransformValue(m_currentValue);
		}
	}

	public override void Start()
	{
		((FVRInteractiveObject)this).Start();
		if ((Object)(object)m_boltAction == (Object)null && (Object)(object)m_openBolt == (Object)null && (Object)(object)m_closedBolt == (Object)null)
		{
			DetectFirearmType();
			ComputeModeLimits();
		}
	}

	private void OnDisable()
	{
		RestoreOriginalBoltLimits();
	}

	public override void OnDestroy()
	{
		RestoreOriginalBoltLimits();
		((FVRInteractiveObject)this).OnDestroy();
	}

	private void RestoreOriginalBoltLimits()
	{
		if ((Object)(object)m_boltAction != (Object)null && (Object)(object)m_boltAction.BoltHandle != (Object)null && m_hasStoredHandleMaxRot)
		{
			m_boltAction.BoltHandle.MaxRot = m_originalHandleMaxRot;
		}
	}

	private void DetectFirearmType()
	{
		if ((Object)(object)FireArm == (Object)null)
		{
			return;
		}
		if (FireArm is BoltActionRifle)
		{
			ref BoltActionRifle boltAction = ref m_boltAction;
			FVRFireArm fireArm = FireArm;
			boltAction = (BoltActionRifle)(object)((fireArm is BoltActionRifle) ? fireArm : null);
			if ((Object)(object)m_boltAction.BoltHandle != (Object)null && !m_hasStoredHandleMaxRot)
			{
				m_originalHandleMaxRot = m_boltAction.BoltHandle.MaxRot;
				m_hasStoredHandleMaxRot = true;
			}
		}
		else if (FireArm is OpenBoltReceiver)
		{
			ref OpenBoltReceiver openBolt = ref m_openBolt;
			FVRFireArm fireArm2 = FireArm;
			openBolt = (OpenBoltReceiver)(object)((fireArm2 is OpenBoltReceiver) ? fireArm2 : null);
		}
		else if (FireArm is ClosedBoltWeapon)
		{
			ref ClosedBoltWeapon closedBolt = ref m_closedBolt;
			FVRFireArm fireArm3 = FireArm;
			closedBolt = (ClosedBoltWeapon)(object)((fireArm3 is ClosedBoltWeapon) ? fireArm3 : null);
		}
		if (EnableDebugLogs && (Object)(object)FireArm != (Object)null)
		{
			Debug.Log((object)("AdvanceFireSelector: Detected Firearm: " + ((object)FireArm).GetType().Name));
		}
	}

	private void ComputeModeLimits()
	{
		if (Modes == null || Modes.Length == 0)
		{
			m_minLimit = 0f;
			m_maxLimit = 0f;
			return;
		}
		float num = float.MaxValue;
		float num2 = float.MinValue;
		for (int i = 0; i < Modes.Length; i++)
		{
			float selectorPosition = Modes[i].SelectorPosition;
			if (selectorPosition < num)
			{
				num = selectorPosition;
			}
			if (selectorPosition > num2)
			{
				num2 = selectorPosition;
			}
		}
		m_minLimit = num;
		m_maxLimit = num2;
		if (EnableDebugLogs)
		{
			Debug.Log((object)("AdvanceFireSelector: Limits Computed -> Min: " + m_minLimit + ", Max: " + m_maxLimit));
		}
	}

	public override bool IsInteractable()
	{
		//IL_0065: 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_009e: Invalid comparison between Unknown and I4
		if ((Object)(object)FireArm == (Object)null)
		{
			return false;
		}
		if ((Object)(object)m_boltAction != (Object)null)
		{
			if ((Object)(object)m_boltAction.BoltHandle != (Object)null && ((FVRInteractiveObject)m_boltAction.BoltHandle).IsHeld)
			{
				return false;
			}
			if ((int)m_boltAction.CurBoltHandleState != 0)
			{
				return false;
			}
			if ((Object)(object)m_boltAction.BoltHandle != (Object)null && (int)m_boltAction.BoltHandle.HandleRot != 2)
			{
				return false;
			}
			if (m_boltAction.RequiresHammerUncockedToToggleFireSelector && m_boltAction.IsHammerCocked)
			{
				return false;
			}
		}
		else if ((Object)(object)m_closedBolt != (Object)null && (Object)(object)m_closedBolt.Bolt != (Object)null && m_closedBolt.Bolt.UsesAKSafetyLock && !m_closedBolt.Bolt.IsBoltForwardOfSafetyLock())
		{
			return false;
		}
		return ((FVRInteractiveObject)this).IsInteractable();
	}

	public override void SimpleInteraction(FVRViveHand hand)
	{
		((FVRInteractiveObject)this).SimpleInteraction(hand);
		if (!((Object)(object)hand == (Object)null))
		{
			CycleToNextMode(hand);
		}
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)hand == (Object)null))
		{
			((FVRInteractiveObject)this).BeginInteraction(hand);
			m_lastHandAngle = CalculateHandAngle(((HandInput)(ref hand.Input)).Pos);
			m_grabStartValue = m_currentValue;
			m_isActivelyDragging = false;
			if (Mode == InteractionMode.ClickCycle)
			{
				CycleToNextMode(hand);
				((FVRInteractiveObject)this).EndInteraction(hand);
			}
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Invalid comparison between Unknown and I4
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: 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_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: 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)
		if ((Object)(object)hand == (Object)null)
		{
			return;
		}
		((FVRInteractiveObject)this).UpdateInteraction(hand);
		if (Mode == InteractionMode.ClickCycle)
		{
			return;
		}
		if (IsClickInputPressed(hand))
		{
			CycleToNextMode(hand);
			return;
		}
		if ((int)InterpStyle == 1)
		{
			float num = CalculateHandAngle(((HandInput)(ref hand.Input)).Pos);
			float num2 = Mathf.DeltaAngle(m_lastHandAngle, num);
			m_lastHandAngle = num;
			if (!m_isActivelyDragging)
			{
				if (Mathf.Abs(num2) >= 0.001f)
				{
					m_isActivelyDragging = true;
				}
				else if (Mode == InteractionMode.Hybrid)
				{
					return;
				}
			}
			if (InvertDirection)
			{
				num2 = 0f - num2;
			}
			float val = Mathf.Clamp(m_currentValue + num2, m_minLimit, m_maxLimit);
			m_currentValue = ApplyMagneticSnap(val);
			m_currentValue = Mathf.Clamp(m_currentValue, m_minLimit, m_maxLimit);
		}
		else
		{
			Vector3 axisVector = GetAxisVector(Axis);
			Vector3 val2 = ((HandInput)(ref hand.Input)).Pos - ((Component)this).transform.position;
			float num3 = Vector3.Dot(val2, axisVector);
			if (!m_isActivelyDragging)
			{
				if (Mathf.Abs(num3) >= ClickDragDistanceThreshold)
				{
					m_isActivelyDragging = true;
				}
				else if (Mode == InteractionMode.Hybrid)
				{
					return;
				}
			}
			if (InvertDirection)
			{
				num3 = 0f - num3;
			}
			float val3 = Mathf.Clamp(m_grabStartValue + num3, m_minLimit, m_maxLimit);
			m_currentValue = ApplyMagneticSnap(val3);
			m_currentValue = Mathf.Clamp(m_currentValue, m_minLimit, m_maxLimit);
		}
		int closestModeIndex = GetClosestModeIndex(m_currentValue);
		if (closestModeIndex != CurModeIndex)
		{
			ApplyModeToWeapon(closestModeIndex, hand);
		}
		ApplyTransformValue(m_currentValue);
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		if ((Object)(object)hand != (Object)null && Mode == InteractionMode.Hybrid && !m_isActivelyDragging)
		{
			CycleToNextMode(hand);
		}
		((FVRInteractiveObject)this).EndInteraction(hand);
	}

	public override void FVRUpdate()
	{
		((FVRInteractiveObject)this).FVRUpdate();
		if (!((Object)(object)FireArm == (Object)null) && Modes != null && Modes.Length != 0 && !((FVRInteractiveObject)this).IsHeld)
		{
			m_targetValue = Modes[CurModeIndex].SelectorPosition;
			if (Mathf.Abs(m_currentValue - m_targetValue) > 0.001f)
			{
				m_currentValue = Mathf.MoveTowards(m_currentValue, m_targetValue, Time.deltaTime * ReturnSpeed * Mathf.Max(1f, Mathf.Abs(m_targetValue - m_currentValue)));
				ApplyTransformValue(m_currentValue);
			}
		}
	}

	private void LateUpdate()
	{
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)FireArm == (Object)null || Modes == null || Modes.Length == 0)
		{
			return;
		}
		bool flag = Modes[CurModeIndex].ModeType == FireModeType.Safe;
		if ((Object)(object)m_boltAction != (Object)null && (Object)(object)m_boltAction.BoltHandle != (Object)null && m_hasStoredHandleMaxRot)
		{
			if (ConstrainBoltOnSafe && flag)
			{
				m_boltAction.BoltHandle.MaxRot = Mathf.Min(m_originalHandleMaxRot, SafeHandleMaxRot);
			}
			else
			{
				m_boltAction.BoltHandle.MaxRot = m_originalHandleMaxRot;
			}
		}
		else if ((Object)(object)m_openBolt != (Object)null && (Object)(object)m_openBolt.Bolt != (Object)null && ConstrainBoltOnSafe && flag)
		{
			float z = m_openBolt.Bolt.Point_Bolt_Forward.localPosition.z;
			float z2 = m_openBolt.Bolt.Point_Bolt_Rear.localPosition.z;
			float num = Mathf.Lerp(z, z2, SafeBoltTravelPercent);
			Vector3 localPosition = ((Component)m_openBolt.Bolt).transform.localPosition;
			if (z2 < z)
			{
				if (localPosition.z < num)
				{
					((Component)m_openBolt.Bolt).transform.localPosition = new Vector3(localPosition.x, localPosition.y, num);
				}
			}
			else if (localPosition.z > num)
			{
				((Component)m_openBolt.Bolt).transform.localPosition = new Vector3(localPosition.x, localPosition.y, num);
			}
		}
		else
		{
			if (!((Object)(object)m_closedBolt != (Object)null) || !((Object)(object)m_closedBolt.Bolt != (Object)null) || !ConstrainBoltOnSafe || !flag || !((Object)(object)m_closedBolt.Bolt.Point_Bolt_Forward != (Object)null) || !((Object)(object)m_closedBolt.Bolt.Point_Bolt_Rear != (Object)null))
			{
				return;
			}
			float z3 = m_closedBolt.Bolt.Point_Bolt_Forward.localPosition.z;
			float z4 = m_closedBolt.Bolt.Point_Bolt_Rear.localPosition.z;
			float num2 = Mathf.Lerp(z3, z4, SafeBoltTravelPercent);
			Vector3 localPosition2 = ((Component)m_closedBolt.Bolt).transform.localPosition;
			if (z4 < z3)
			{
				if (localPosition2.z < num2)
				{
					((Component)m_closedBolt.Bolt).transform.localPosition = new Vector3(localPosition2.x, localPosition2.y, num2);
				}
			}
			else if (localPosition2.z > num2)
			{
				((Component)m_closedBolt.Bolt).transform.localPosition = new Vector3(localPosition2.x, localPosition2.y, num2);
			}
		}
	}

	private bool IsClickInputPressed(FVRViveHand hand)
	{
		if ((Object)(object)hand == (Object)null)
		{
			return false;
		}
		if (hand.IsInStreamlinedMode)
		{
			return hand.Input.AXButtonDown || hand.Input.BYButtonDown || hand.Input.TriggerDown;
		}
		return hand.Input.TouchpadDown || hand.Input.TriggerDown;
	}

	private float CalculateHandAngle(Vector3 handPos)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//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_002b: 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_003c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0072: 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_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)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: 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)
		if ((Object)(object)RootTransform == (Object)null)
		{
			return 0f;
		}
		Vector3 axisVector = GetAxisVector(Axis);
		Vector3 val = handPos - RootTransform.position;
		Vector3 val2 = Vector3.ProjectOnPlane(val, axisVector);
		Vector3 normalized = ((Vector3)(ref val2)).normalized;
		if (((Vector3)(ref normalized)).sqrMagnitude < 0.001f)
		{
			return 0f;
		}
		Vector3 val3 = Vector3.up;
		if (Mathf.Abs(Vector3.Dot(axisVector, Vector3.up)) > 0.9f)
		{
			val3 = Vector3.forward;
		}
		Vector3 val4 = Vector3.ProjectOnPlane(val3, axisVector);
		Vector3 val5 = ((Vector3)(ref val4)).normalized;
		if (((Vector3)(ref val5)).sqrMagnitude < 0.001f)
		{
			val5 = Vector3.right;
		}
		return Mathf.Atan2(Vector3.Dot(axisVector, Vector3.Cross(val5, normalized)), Vector3.Dot(val5, normalized)) * 57.29578f;
	}

	private void CycleToNextMode(FVRViveHand hand = null)
	{
		if (Modes != null && Modes.Length > 1)
		{
			int num = CurModeIndex + 1;
			if (num >= Modes.Length)
			{
				num = 0;
			}
			ApplyModeToWeapon(num, hand);
			m_targetValue = Modes[CurModeIndex].SelectorPosition;
			m_currentValue = m_targetValue;
			ApplyTransformValue(m_currentValue);
		}
	}

	private void ApplyModeToWeapon(int modeIndex, FVRViveHand hand = null, bool isInitialization = false)
	{
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		if (Modes == null || Modes.Length == 0 || modeIndex < 0 || modeIndex >= Modes.Length)
		{
			return;
		}
		CurModeIndex = modeIndex;
		SelectorModeDefinition selectorModeDefinition = Modes[modeIndex];
		if ((Object)(object)m_boltAction != (Object)null)
		{
			if (m_boltAction.FireSelector_Modes != null && m_boltAction.FireSelector_Modes.Length > 0)
			{
				int num = Mathf.Clamp(m_boltAction.m_fireSelectorMode, 0, m_boltAction.FireSelector_Modes.Length - 1);
				m_boltAction.FireSelector_Modes[num].ModeType = (FireSelectorModeType)((selectorModeDefinition.ModeType != FireModeType.Safe) ? 1 : 0);
				m_boltAction.FireSelector_Modes[num].IsBoltLocked = selectorModeDefinition.IsBoltLocked;
			}
			if (!isInitialization)
			{
				((FVRFireArm)m_boltAction).PlayAudioEvent((FirearmAudioEventType)14, 1f);
			}
		}
		else if ((Object)(object)m_openBolt != (Object)null)
		{
			if (m_openBolt.FireSelector_Modes != null && m_openBolt.FireSelector_Modes.Length > 0)
			{
				int num2 = Mathf.Clamp(m_openBolt.m_fireSelectorMode, 0, m_openBolt.FireSelector_Modes.Length - 1);
				m_openBolt.FireSelector_Modes[num2].ModeType = ConvertToOpenBoltMode(selectorModeDefinition.ModeType);
				m_openBolt.FireSelector_Modes[num2].BurstAmount = selectorModeDefinition.BurstAmount;
			}
			m_openBolt.ResetCamBurst();
			if (!isInitialization)
			{
				((FVRFireArm)m_openBolt).PlayAudioEvent((FirearmAudioEventType)14, 1f);
			}
		}
		else if ((Object)(object)m_closedBolt != (Object)null)
		{
			if (m_closedBolt.FireSelector_Modes != null && m_closedBolt.FireSelector_Modes.Length > 0)
			{
				int num3 = Mathf.Clamp(m_closedBolt.FireSelectorModeIndex, 0, m_closedBolt.FireSelector_Modes.Length - 1);
				m_closedBolt.FireSelector_Modes[num3].ModeType = ConvertToClosedBoltMode(selectorModeDefinition.ModeType);
				m_closedBolt.FireSelector_Modes[num3].BurstAmount = selectorModeDefinition.BurstAmount;
			}
			m_closedBolt.ResetCamBurst();
			if (!isInitialization)
			{
				((FVRFireArm)m_closedBolt).PlayAudioEvent((FirearmAudioEventType)14, 1f);
			}
			if (m_closedBolt.HasWrap && (Object)(object)m_closedBolt.CarrierWrap != (Object)null)
			{
				m_closedBolt.CarrierWrap.OnFireModeChanged();
			}
		}
		if (!isInitialization)
		{
			if ((Object)(object)hand != (Object)null && (Object)(object)hand.Buzzer != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
			}
			else if ((Object)(object)base.m_hand != (Object)null && (Object)(object)base.m_hand.Buzzer != (Object)null)
			{
				base.m_hand.Buzz(base.m_hand.Buzzer.Buzz_BeginInteraction);
			}
		}
		if (EnableDebugLogs)
		{
			Debug.Log((object)("AdvanceFireSelector: Set Mode " + modeIndex + " (" + selectorModeDefinition.ModeType.ToString() + ") -> Target Pos: " + selectorModeDefinition.SelectorPosition));
		}
	}

	private FireSelectorModeType ConvertToClosedBoltMode(FireModeType type)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		return (FireSelectorModeType)(type switch
		{
			FireModeType.Safe => 0, 
			FireModeType.Single => 1, 
			FireModeType.Burst => 2, 
			FireModeType.FullAuto => 3, 
			_ => 1, 
		});
	}

	private FireSelectorModeType ConvertToOpenBoltMode(FireModeType type)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		return (FireSelectorModeType)(type switch
		{
			FireModeType.Safe => 0, 
			FireModeType.Single => 1, 
			FireModeType.Burst => 4, 
			FireModeType.FullAuto => 2, 
			_ => 1, 
		});
	}

	private int GetClosestModeIndex(float val)
	{
		if (Modes == null || Modes.Length == 0)
		{
			return 0;
		}
		int result = 0;
		float num = float.MaxValue;
		for (int i = 0; i < Modes.Length; i++)
		{
			float selectorPosition = Modes[i].SelectorPosition;
			float num2 = Mathf.Abs(selectorPosition - val);
			if (num2 < num)
			{
				num = num2;
				result = i;
			}
		}
		return result;
	}

	private float ApplyMagneticSnap(float val)
	{
		if (Modes == null || Modes.Length == 0)
		{
			return val;
		}
		for (int i = 0; i < Modes.Length; i++)
		{
			float selectorPosition = Modes[i].SelectorPosition;
			if (Mathf.Abs(val - selectorPosition) <= MagneticSnapThreshold)
			{
				return selectorPosition;
			}
		}
		return val;
	}

	private Vector3 GetAxisVector(Axis axis)
	{
		//IL_001e: 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)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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)
		if ((Object)(object)RootTransform == (Object)null)
		{
			return Vector3.forward;
		}
		if ((int)axis == 0)
		{
			return RootTransform.right;
		}
		if ((int)axis == 1)
		{
			return RootTransform.up;
		}
		return RootTransform.forward;
	}

	private void ApplyTransformValue(float val)
	{
		//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_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Invalid comparison between Unknown and I4
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Invalid comparison between Unknown and I4
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Invalid comparison between Unknown and I4
		//IL_007d: 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_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_0059: 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_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_00df: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val2 = Vector3.forward;
		if ((int)Axis == 0)
		{
			val2 = Vector3.right;
		}
		else if ((int)Axis == 1)
		{
			val2 = Vector3.up;
		}
		if ((Object)(object)DisplayPiece != (Object)null)
		{
			if ((int)InterpStyle == 1)
			{
				DisplayPiece.localRotation = m_initialDisplayLocalRot * Quaternion.Ang