Decompiled source of MPF45 v1.0.0

MPF45.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.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;

[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]
[DisallowMultipleComponent]
public class MetalClashEffect : MonoBehaviour
{
	[Header("Collider Filtering")]
	[Tooltip("Specific blade colliders on this weapon that can trigger clashes. If empty, all local colliders are used.")]
	public Collider[] BladeColliders;

	[Header("Target Material Filtering")]
	[Tooltip("Specific MatDef assets allowed to trigger clashes. If empty, any metal MatDef will trigger.")]
	public MatDef[] AllowedTargetMatDefs;

	[Header("Velocity Thresholds")]
	[Tooltip("Minimum collision speed required to trigger sparks and sound.")]
	public float MinClashVelocity = 1.5f;

	[Tooltip("Speed required to trigger maximum spark magnitude and hard impact sound.")]
	public float HighClashVelocity = 4.5f;

	[Header("Cooldown")]
	[Tooltip("Minimum time in seconds between clash events to prevent multi-contact frame spam.")]
	public float CooldownTime = 0.08f;

	[Header("Audio Config")]
	[Tooltip("Impact sound category to play on collision.")]
	public ImpactType WeaponImpactType = (ImpactType)130;

	[Tooltip("Audio pool to use for impact sounds.")]
	public FVRPooledAudioType AudioPool = (FVRPooledAudioType)41;

	[Tooltip("Maximum audible distance for the clash sound.")]
	public float MaxAudioDistance = 25f;

	private float m_cooldownTimer;

	private HashSet<Collider> m_bladeColliderSet = new HashSet<Collider>();

	private void Awake()
	{
		if (BladeColliders != null && BladeColliders.Length > 0)
		{
			for (int i = 0; i < BladeColliders.Length; i++)
			{
				if ((Object)(object)BladeColliders[i] != (Object)null)
				{
					m_bladeColliderSet.Add(BladeColliders[i]);
				}
			}
			return;
		}
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		for (int j = 0; j < componentsInChildren.Length; j++)
		{
			if (!componentsInChildren[j].isTrigger)
			{
				m_bladeColliderSet.Add(componentsInChildren[j]);
			}
		}
	}

	private void Update()
	{
		if (m_cooldownTimer > 0f)
		{
			m_cooldownTimer -= Time.deltaTime;
		}
	}

	private void OnCollisionEnter(Collision col)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: 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_00cf: 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)
		if (m_cooldownTimer > 0f || col.contacts == null || col.contacts.Length == 0)
		{
			return;
		}
		Vector3 relativeVelocity = col.relativeVelocity;
		float magnitude = ((Vector3)(ref relativeVelocity)).magnitude;
		if (magnitude < MinClashVelocity)
		{
			return;
		}
		ContactPoint val = col.contacts[0];
		if (m_bladeColliderSet.Contains(((ContactPoint)(ref val)).thisCollider) && IsTargetValidMetal(((ContactPoint)(ref val)).otherCollider, col))
		{
			m_cooldownTimer = CooldownTime;
			Vector3 point = ((ContactPoint)(ref val)).point;
			Vector3 normal = ((ContactPoint)(ref val)).normal;
			AudioImpactIntensity val2 = (AudioImpactIntensity)1;
			ImpactEffectMagnitude val3 = (ImpactEffectMagnitude)1;
			if (magnitude >= HighClashVelocity)
			{
				val2 = (AudioImpactIntensity)2;
				val3 = (ImpactEffectMagnitude)2;
			}
			FXM.SpawnImpactEffect(point, normal, 1, val3, false, false, Color.white, (Material)null);
			SM.PlayImpactSound(WeaponImpactType, (MatSoundType)4, val2, point, AudioPool, MaxAudioDistance);
		}
	}

	private bool IsTargetValidMetal(Collider otherCollider, Collision col)
	{
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Invalid comparison between Unknown and I4
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Invalid comparison between Unknown and I4
		PMat component = ((Component)otherCollider).GetComponent<PMat>();
		if ((Object)(object)component == (Object)null && (Object)(object)col.collider.attachedRigidbody != (Object)null)
		{
			component = ((Component)col.collider.attachedRigidbody).GetComponent<PMat>();
		}
		if ((Object)(object)component == (Object)null || (Object)(object)component.MatDef == (Object)null)
		{
			if ((Object)(object)otherCollider.sharedMaterial != (Object)null)
			{
				return ((Object)otherCollider.sharedMaterial).name.IndexOf("Metal", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}
		MatDef matDef = component.MatDef;
		if (AllowedTargetMatDefs != null && AllowedTargetMatDefs.Length > 0)
		{
			for (int i = 0; i < AllowedTargetMatDefs.Length; i++)
			{
				if ((Object)(object)AllowedTargetMatDefs[i] == (Object)(object)matDef)
				{
					return true;
				}
			}
			return false;
		}
		if ((int)matDef.SoundType == 4 || (int)matDef.SoundType == 0)
		{
			return true;
		}
		if ((int)matDef.ImpactEffectType == 1)
		{
			return true;
		}
		return false;
	}
}
public class HarshRecoilController : MonoBehaviour
{
	[Header("Weapon Reference")]
	public FVRFireArm weapon;

	[Header("Disarm Configuration")]
	[Tooltip("Probability (0.0 to 1.0) that the gun is knocked out of your hand when fired one-handed.")]
	public float disarmChance = 1f;

	public float recoilForceUp = 4f;

	public float recoilForceBack = 6f;

	public float recoilTorque = 12f;

	public float recoilRandomness = 1.5f;

	[Tooltip("Extra angular drag applied immediately after disarm to prevent endless tumbling in the air.")]
	public float postDisarmAngularDrag = 3f;

	[Header("Stabilization & Stock")]
	[Tooltip("If true, shouldering the stock (IsShoulderStabilized) prevents the weapon from being disarmed.")]
	public bool checkShoulderStabilization = true;

	[Header("Recoil Return / Recovery Speed")]
	[Tooltip("If true, automatically adjusts the weapon's interpolation speeds so it snaps back to hand alignment quickly.")]
	public bool overrideInterpSpeeds = true;

	[Tooltip("Speed at which the gun returns to hand position (standard snappy value: 15.0 - 25.0).")]
	public float targetPositionInterpSpeed = 20f;

	[Tooltip("Speed at which the gun returns to hand rotation/level (standard snappy value: 15.0 - 25.0).")]
	public float targetRotationInterpSpeed = 20f;

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

	private List<bool> lastFrameSpent = new List<bool>();

	private List<Collider> disabledColliders = new List<Collider>();

	private float colliderRestoreTimer;

	private float dragRestoreTimer;

	private float origAngularDrag = 0.05f;

	private bool initialized;

	private void Start()
	{
		TryInitialize();
	}

	private void Update()
	{
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: 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)
		//IL_02c2: 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_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: 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)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized)
		{
			TryInitialize();
		}
		else
		{
			if ((Object)(object)weapon == (Object)null || weapon.FChambers == null)
			{
				return;
			}
			if (colliderRestoreTimer > 0f)
			{
				colliderRestoreTimer -= Time.deltaTime;
				if (colliderRestoreTimer <= 0f)
				{
					RestoreColliders();
				}
			}
			if (dragRestoreTimer > 0f)
			{
				dragRestoreTimer -= Time.deltaTime;
				if (dragRestoreTimer <= 0f && (Object)(object)((FVRPhysicalObject)weapon).RootRigidbody != (Object)null)
				{
					((FVRPhysicalObject)weapon).RootRigidbody.angularDrag = origAngularDrag;
				}
			}
			for (int i = 0; i < weapon.FChambers.Count; i++)
			{
				FVRFireArmChamber val = weapon.FChambers[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (i >= lastFrameSpent.Count)
				{
					lastFrameSpent.Add(val.IsSpent);
				}
				bool isSpent = val.IsSpent;
				bool flag = isSpent && !lastFrameSpent[i];
				lastFrameSpent[i] = isSpent;
				if (!flag)
				{
					continue;
				}
				bool flag2 = (Object)(object)((FVRPhysicalObject)weapon).AltGrip != (Object)null && ((FVRInteractiveObject)((FVRPhysicalObject)weapon).AltGrip).IsHeld;
				bool flag3 = weapon.IsTwoHandStabilized();
				bool flag4 = checkShoulderStabilization && weapon.IsShoulderStabilized();
				bool flag5 = flag3 || flag2 || flag4;
				if (((FVRInteractiveObject)weapon).IsHeld && !flag5 && Random.value <= disarmChance)
				{
					if (debug)
					{
						Debug.Log((object)"HarshRecoilController: Weapon fired unsupported. Applying launch physics and disarming.");
					}
					FVRViveHand hand = ((FVRInteractiveObject)weapon).m_hand;
					if ((Object)(object)hand != (Object)null)
					{
						hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
					}
					((FVRInteractiveObject)weapon).ForceBreakInteraction();
					DisableColliders();
					Rigidbody rootRigidbody = ((FVRPhysicalObject)weapon).RootRigidbody;
					if ((Object)(object)rootRigidbody != (Object)null)
					{
						origAngularDrag = rootRigidbody.angularDrag;
						rootRigidbody.angularDrag = postDisarmAngularDrag;
						dragRestoreTimer = 1.5f;
						Vector3 val2 = -((Component)weapon).transform.forward * recoilForceBack + ((Component)weapon).transform.up * recoilForceUp;
						Vector3 val3 = Random.insideUnitSphere * recoilRandomness;
						rootRigidbody.AddForce(val2 + val3, (ForceMode)2);
						Vector3 val4 = ((Component)weapon).transform.right * recoilTorque;
						Vector3 val5 = Random.insideUnitSphere * (recoilRandomness * 3f);
						rootRigidbody.AddTorque(val4 + val5, (ForceMode)2);
					}
				}
			}
		}
	}

	private void DisableColliders()
	{
		disabledColliders.Clear();
		Collider[] componentsInChildren = ((Component)weapon).GetComponentsInChildren<Collider>();
		foreach (Collider val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && val.enabled)
			{
				val.enabled = false;
				disabledColliders.Add(val);
			}
		}
		colliderRestoreTimer = 0.08f;
	}

	private void RestoreColliders()
	{
		for (int i = 0; i < disabledColliders.Count; i++)
		{
			if ((Object)(object)disabledColliders[i] != (Object)null)
			{
				disabledColliders[i].enabled = true;
			}
		}
		disabledColliders.Clear();
	}

	private void TryInitialize()
	{
		if ((Object)(object)weapon == (Object)null)
		{
			weapon = ((Component)this).GetComponent<FVRFireArm>();
		}
		if (!((Object)(object)weapon != (Object)null) || weapon.FChambers == null)
		{
			return;
		}
		if (overrideInterpSpeeds)
		{
			((FVRInteractiveObject)weapon).PositionInterpSpeed = targetPositionInterpSpeed;
			((FVRInteractiveObject)weapon).RotationInterpSpeed = targetRotationInterpSpeed;
		}
		lastFrameSpent.Clear();
		for (int i = 0; i < weapon.FChambers.Count; i++)
		{
			if ((Object)(object)weapon.FChambers[i] != (Object)null)
			{
				lastFrameSpent.Add(weapon.FChambers[i].IsSpent);
			}
			else
			{
				lastFrameSpent.Add(item: false);
			}
		}
		if ((Object)(object)((FVRPhysicalObject)weapon).RootRigidbody != (Object)null)
		{
			origAngularDrag = ((FVRPhysicalObject)weapon).RootRigidbody.angularDrag;
		}
		initialized = true;
	}
}
internal class ManualChamberLoad : FVRInteractiveObject
{
	public FVRFireArmChamber chamber;

	public Transform ChamberSeatedPoint;

	public Collider vanillaChamberCollider;

	public float loadThreshold = -0.005f;

	public float extractThreshold = -0.05f;

	public float maxCasingPushDistance = 0.025f;

	public float shuckForceThreshold = 1.5f;

	public float spentShuckResistance = 6f;

	public float shuckSensitivity = 1.2f;

	public AudioEvent AudEvent_ShellInStart;

	public AudioEvent AudEvent_ShellIn;

	public AudioEvent AudEvent_ShellOutStart;

	public AudioEvent AudEvent_ShellOut;

	public bool debug;

	private FVRFireArmRound m_loadingRound;

	private float m_roundHandOffsetZ;

	private bool m_isExtracting;

	private float m_gravitySlideZ;

	public override void Awake()
	{
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)chamber == (Object)null)
		{
			chamber = ((Component)this).GetComponent<FVRFireArmChamber>();
		}
		if ((Object)(object)vanillaChamberCollider != (Object)null)
		{
			vanillaChamberCollider.enabled = false;
			if (debug)
			{
				Debug.Log((object)"ManualChamberLoad: Disabled specified vanilla chamber collider.");
			}
		}
	}

	private void Update()
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0374: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0403: 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_04b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_052b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)chamber == (Object)null || (Object)(object)ChamberSeatedPoint == (Object)null)
		{
			return;
		}
		if ((Object)(object)m_loadingRound != (Object)null)
		{
			FVRViveHand hand = ((FVRInteractiveObject)m_loadingRound).m_hand;
			if ((Object)(object)hand == (Object)null || !((FVRInteractiveObject)m_loadingRound).IsHeld)
			{
				m_loadingRound = null;
				return;
			}
			float num = ChamberSeatedPoint.InverseTransformPoint(((Component)hand).transform.position).z + m_roundHandOffsetZ;
			if (num >= loadThreshold)
			{
				PlaySound(AudEvent_ShellIn);
				if (m_loadingRound.ProxyRounds != null && m_loadingRound.ProxyRounds.Count > 0)
				{
					m_loadingRound.CycleToProxy(true, false);
				}
				((FVRInteractiveObject)m_loadingRound).ForceBreakInteraction();
				chamber.SetRound(m_loadingRound, false);
				Object.Destroy((Object)(object)((Component)m_loadingRound).gameObject);
				m_loadingRound = null;
				if (debug)
				{
					Debug.Log((object)"ManualChamberLoad: Round successfully seated with palming preserved.");
				}
			}
			else if (num < extractThreshold * 1.5f)
			{
				m_loadingRound = null;
				if (debug)
				{
					Debug.Log((object)"ManualChamberLoad: Loading aborted.");
				}
			}
			else
			{
				((Component)m_loadingRound).transform.position = ChamberSeatedPoint.TransformPoint(new Vector3(0f, 0f, num));
				((Component)m_loadingRound).transform.rotation = ChamberSeatedPoint.rotation;
			}
		}
		if (m_isExtracting)
		{
			if (!((FVRInteractiveObject)this).IsHeld || (Object)(object)base.m_hand == (Object)null)
			{
				m_isExtracting = false;
				if ((Object)(object)chamber.ProxyRound != (Object)null)
				{
					chamber.ProxyRound.localPosition = Vector3.zero;
				}
				return;
			}
			float num2 = ChamberSeatedPoint.InverseTransformPoint(((Component)base.m_hand).transform.position).z + m_roundHandOffsetZ;
			if (num2 <= extractThreshold)
			{
				PlaySound(AudEvent_ShellOut);
				FVRFireArmRound val = chamber.EjectRound(ChamberSeatedPoint.position, Vector3.zero, Vector3.zero, false);
				if ((Object)(object)val != (Object)null)
				{
					((FVRInteractiveObject)val).BeginInteraction(base.m_hand);
					base.m_hand.ForceSetInteractable((FVRInteractiveObject)(object)val);
				}
				((FVRInteractiveObject)this).ForceBreakInteraction();
				m_isExtracting = false;
				m_gravitySlideZ = 0f;
				if (debug)
				{
					Debug.Log((object)"ManualChamberLoad: Round successfully extracted.");
				}
			}
			else
			{
				float num3 = Mathf.Clamp(num2, extractThreshold, 0f);
				if ((Object)(object)chamber.ProxyRound != (Object)null)
				{
					chamber.ProxyRound.localPosition = new Vector3(0f, 0f, num3);
				}
			}
		}
		if (!chamber.IsFull || !chamber.IsAccessible || ((FVRInteractiveObject)this).IsHeld || !((Object)(object)m_loadingRound == (Object)null))
		{
			return;
		}
		float num4 = Vector3.Angle(((Component)chamber).transform.forward, Vector3.up);
		float num5 = 0f;
		if (!chamber.IsSpent && num4 < 70f)
		{
			num5 -= Time.deltaTime * 0.2f;
		}
		Rigidbody val2 = ((!((Object)(object)chamber.Firearm != (Object)null)) ? null : ((FVRPhysicalObject)chamber.Firearm).RootRigidbody);
		if ((Object)(object)val2 != (Object)null)
		{
			float num6 = 0f - ChamberSeatedPoint.InverseTransformDirection(val2.velocity).z;
			float num7 = num6 - shuckForceThreshold;
			if (num7 > 0f)
			{
				float num8 = ((!chamber.IsSpent) ? 1f : spentShuckResistance);
				num5 -= num7 / num8 * Time.deltaTime * shuckSensitivity;
			}
		}
		if (num5 != 0f)
		{
			m_gravitySlideZ += num5;
			if (m_gravitySlideZ <= extractThreshold)
			{
				PlaySound(AudEvent_ShellOut);
				chamber.EjectRound(ChamberSeatedPoint.position, -ChamberSeatedPoint.forward * 0.5f, Random.onUnitSphere, false);
				m_gravitySlideZ = 0f;
				if (debug)
				{
					Debug.Log((object)"ManualChamberLoad: Round ejected via gravity/shucking.");
				}
			}
			else if ((Object)(object)chamber.ProxyRound != (Object)null)
			{
				chamber.ProxyRound.localPosition = new Vector3(0f, 0f, m_gravitySlideZ);
			}
		}
		else if (m_gravitySlideZ < 0f)
		{
			m_gravitySlideZ = Mathf.MoveTowards(m_gravitySlideZ, 0f, Time.deltaTime * 0.5f);
			if ((Object)(object)chamber.ProxyRound != (Object)null)
			{
				chamber.ProxyRound.localPosition = new Vector3(0f, 0f, m_gravitySlideZ);
			}
		}
	}

	private void OnTriggerStay(Collider other)
	{
		//IL_0083: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)chamber == (Object)null || (Object)(object)ChamberSeatedPoint == (Object)null || !chamber.IsAccessible || chamber.IsFull || (Object)(object)m_loadingRound != (Object)null || m_isExtracting)
		{
			return;
		}
		FVRFireArmRound componentInParent = ((Component)other).GetComponentInParent<FVRFireArmRound>();
		if (!((Object)(object)componentInParent != (Object)null) || !((FVRInteractiveObject)componentInParent).IsHeld || componentInParent.RoundType != chamber.RoundType)
		{
			return;
		}
		FVRViveHand hand = ((FVRInteractiveObject)componentInParent).m_hand;
		if ((Object)(object)hand != (Object)null)
		{
			PlaySound(AudEvent_ShellInStart);
			m_loadingRound = componentInParent;
			Vector3 val = ChamberSeatedPoint.InverseTransformPoint(((Component)hand).transform.position);
			m_roundHandOffsetZ = ChamberSeatedPoint.InverseTransformPoint(((Component)m_loadingRound).transform.position).z - val.z;
			if (debug)
			{
				Debug.Log((object)"ManualChamberLoad: Round entered loading zone. Initializing sliding guide.");
			}
		}
	}

	public override bool IsInteractable()
	{
		return (Object)(object)chamber != (Object)null && chamber.IsFull && chamber.IsAccessible;
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		((FVRInteractiveObject)this).BeginInteraction(hand);
		if ((Object)(object)chamber != (Object)null && chamber.IsFull && chamber.IsAccessible)
		{
			PlaySound(AudEvent_ShellOutStart);
			m_isExtracting = true;
			Vector3 val = ChamberSeatedPoint.InverseTransformPoint(((Component)hand).transform.position);
			float num = 0f;
			if ((Object)(object)chamber.ProxyRound != (Object)null)
			{
				num = chamber.ProxyRound.localPosition.z;
			}
			m_roundHandOffsetZ = num - val.z;
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).EndInteraction(hand);
		m_isExtracting = false;
		if ((Object)(object)chamber != (Object)null && (Object)(object)chamber.ProxyRound != (Object)null)
		{
			chamber.ProxyRound.localPosition = Vector3.zero;
		}
	}

	private void PlaySound(AudioEvent aud)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (aud != null)
		{
			if ((Object)(object)chamber != (Object)null && (Object)(object)chamber.Firearm != (Object)null)
			{
				chamber.Firearm.PlayAudioAsHandling(aud, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, aud, ((Component)this).transform.position);
			}
		}
	}
}
internal class ManualCylinderIndex : FVRAlternateGrip
{
	public SingleActionRevolver Revolver;

	public float indexCooldown = 0.2f;

	public bool debug;

	private float m_cooldownTimer;

	public override void Awake()
	{
		if ((Object)(object)((FVRInteractiveObject)this).PoseOverride == (Object)null)
		{
			((FVRInteractiveObject)this).PoseOverride = ((Component)this).transform;
		}
		((FVRAlternateGrip)this).Awake();
		if ((Object)(object)base.PrimaryObject == (Object)null && (Object)(object)Revolver != (Object)null)
		{
			base.PrimaryObject = (FVRPhysicalObject)(object)Revolver;
		}
		base.DoesBracing = false;
	}

	private void Update()
	{
		if ((Object)(object)Revolver == (Object)null)
		{
			return;
		}
		if (m_cooldownTimer > 0f)
		{
			m_cooldownTimer -= Time.deltaTime;
		}
		FVRViveHand holdingHand = GetHoldingHand();
		if ((Object)(object)holdingHand != (Object)null)
		{
			bool flag = false;
			if (holdingHand.IsInStreamlinedMode)
			{
				if (holdingHand.Input.AXButtonDown || holdingHand.Input.BYButtonDown)
				{
					flag = true;
				}
			}
			else if (holdingHand.Input.TouchpadDown)
			{
				flag = true;
			}
			if (flag && m_cooldownTimer <= 0f && Revolver.m_isStateToggled)
			{
				if (debug)
				{
					Debug.Log((object)"ManualCylinderIndex: Indexing cylinder forward one chamber.");
				}
				Revolver.AdvanceCylinder();
				m_cooldownTimer = indexCooldown;
				holdingHand.Buzz(holdingHand.Buzzer.Buzz_BeginInteraction);
			}
		}
		if ((Object)(object)holdingHand != (Object)null)
		{
			Revolver.UpdateCylinderRot();
		}
	}

	public override bool IsInteractable()
	{
		return (Object)(object)Revolver != (Object)null && ((FVRAlternateGrip)this).IsInteractable();
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		((FVRAlternateGrip)this).BeginInteraction(hand);
		if (debug)
		{
			Debug.Log((object)"ManualCylinderIndex: Cylinder grabbed safely via AltGrip.");
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		((FVRAlternateGrip)this).EndInteraction(hand);
		if (debug)
		{
			Debug.Log((object)"ManualCylinderIndex: Cylinder released.");
		}
	}

	private FVRViveHand GetHoldingHand()
	{
		if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
		{
			return ((FVRInteractiveObject)this).m_hand;
		}
		if ((Object)(object)Revolver != (Object)null && ((FVRPhysicalObject)Revolver).IsAltHeld)
		{
			return ((FVRInteractiveObject)Revolver).m_hand;
		}
		return null;
	}
}
internal class ManualRevolverEjectorRod : FVRInteractiveObject
{
	public SingleActionRevolver Revolver;

	public Transform EjectorRod;

	public Transform Point_Rod_Forward;

	public Transform Point_Rod_Rearward;

	public float Speed_Forward = 10f;

	public float Speed_Held = 20f;

	public float SpringStiffness = 40f;

	public float EjectThreshold = 0.9f;

	public float maxCasingPushDistance = 0.025f;

	public AudioEvent AudEvent_RodBack;

	public AudioEvent AudEvent_RodForward;

	public bool debug;

	private float m_rodZ;

	private float m_rodZ_forward;

	private float m_rodZ_rear;

	private float m_curSpeed;

	private bool m_isRearPlayed;

	private bool m_isForwardPlayed;

	private bool m_isAutoPushing;

	private int m_autoPushDir = 1;

	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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		if ((Object)(object)EjectorRod != (Object)null && (Object)(object)Point_Rod_Forward != (Object)null && (Object)(object)Point_Rod_Rearward != (Object)null)
		{
			m_rodZ_forward = Point_Rod_Forward.localPosition.z;
			m_rodZ_rear = Point_Rod_Rearward.localPosition.z;
			m_rodZ = m_rodZ_forward;
		}
	}

	private void Update()
	{
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Revolver == (Object)null || (Object)(object)EjectorRod == (Object)null || (Object)(object)EjectorRod.parent == (Object)null)
		{
			return;
		}
		bool isHeld = ((FVRInteractiveObject)this).IsHeld;
		float rodZ_forward = m_rodZ_forward;
		if ((Object)(object)((FVRInteractiveObject)Revolver).m_hand != (Object)null && ((FVRInteractiveObject)Revolver).m_hand.Input.TriggerDown && Revolver.m_isStateToggled && !isHeld)
		{
			m_isAutoPushing = true;
			m_autoPushDir = 1;
		}
		if (m_isAutoPushing)
		{
			m_curSpeed = 0f;
			if (m_autoPushDir == 1)
			{
				m_rodZ = Mathf.MoveTowards(m_rodZ, m_rodZ_rear, Speed_Held * 2f * Time.deltaTime);
				if (Mathf.Abs(m_rodZ - m_rodZ_rear) < 0.001f)
				{
					m_autoPushDir = -1;
				}
			}
			else
			{
				m_rodZ = Mathf.MoveTowards(m_rodZ, m_rodZ_forward, Speed_Forward * 2f * Time.deltaTime);
				if (Mathf.Abs(m_rodZ - m_rodZ_forward) < 0.001f)
				{
					m_isAutoPushing = false;
					m_autoPushDir = 1;
				}
			}
		}
		else if (isHeld && (Object)(object)base.m_hand != (Object)null)
		{
			Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(Point_Rod_Forward.position, Point_Rod_Rearward.position, ((HandInput)(ref base.m_hand.Input)).Pos);
			rodZ_forward = EjectorRod.parent.InverseTransformPoint(closestValidPoint).z;
			m_curSpeed = 0f;
			m_rodZ = Mathf.MoveTowards(m_rodZ, rodZ_forward, Speed_Held * Time.deltaTime);
		}
		else
		{
			m_curSpeed = Mathf.MoveTowards(m_curSpeed, Speed_Forward, Time.deltaTime * SpringStiffness);
			m_rodZ = Mathf.MoveTowards(m_rodZ, rodZ_forward, m_curSpeed * Time.deltaTime);
		}
		float num = Mathf.Min(m_rodZ_forward, m_rodZ_rear);
		float num2 = Mathf.Max(m_rodZ_forward, m_rodZ_rear);
		m_rodZ = Mathf.Clamp(m_rodZ, num, num2);
		EjectorRod.localPosition = new Vector3(EjectorRod.localPosition.x, EjectorRod.localPosition.y, m_rodZ);
		float num3 = Mathf.InverseLerp(m_rodZ_forward, m_rodZ_rear, m_rodZ);
		if (num3 > EjectThreshold)
		{
			if (!m_isRearPlayed)
			{
				PlaySound(AudEvent_RodBack);
				m_isRearPlayed = true;
				m_isForwardPlayed = false;
				if (!m_isAutoPushing)
				{
					Revolver.EjectPrevCylinder();
				}
				if (debug)
				{
					Debug.Log((object)"ManualRevolverEjectorRod: Rod reached threshold. Ejecting.");
				}
			}
		}
		else if (num3 < 0.1f && !m_isForwardPlayed)
		{
			PlaySound(AudEvent_RodForward);
			m_isForwardPlayed = true;
			m_isRearPlayed = false;
		}
		int num4 = Revolver.PrevChamber;
		if (Revolver.IsAccessTwoChambersBack)
		{
			num4 = Revolver.PrevChamber2;
		}
		if ((Object)(object)Revolver.Cylinder != (Object)null && Revolver.Cylinder.Chambers != null && num4 < Revolver.Cylinder.Chambers.Length)
		{
			FVRFireArmChamber val = Revolver.Cylinder.Chambers[num4];
			if ((Object)(object)val != (Object)null && val.IsFull && (Object)(object)val.ProxyRound != (Object)null)
			{
				val.ProxyRound.localPosition = new Vector3(0f, 0f, (0f - num3) * maxCasingPushDistance);
			}
		}
	}

	public override bool IsInteractable()
	{
		return (Object)(object)Revolver != (Object)null && Revolver.m_isStateToggled;
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		((FVRInteractiveObject)this).BeginInteraction(hand);
		if ((Object)(object)EjectorRod != (Object)null && (Object)(object)Point_Rod_Forward != (Object)null && (Object)(object)EjectorRod.parent != (Object)(object)Point_Rod_Forward.parent)
		{
			EjectorRod.SetParent(Point_Rod_Forward.parent);
		}
	}

	private void PlaySound(AudioEvent aud)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		if (aud != null && (Object)(object)Revolver != (Object)null)
		{
			((FVRFireArm)Revolver).PlayAudioAsHandling(aud, ((Component)this).transform.position);
		}
	}
}
public class SingleActionPhysicalEnhancer : MonoBehaviour
{
	public float CartridgeLength = 0.04f;

	public float CartridgePivotOffset = 0f;

	public bool DebugMode = false;

	private SingleActionRevolver _revolver;

	private List<ActiveSlidingRound> _slidingRounds = new List<ActiveSlidingRound>();

	private FVRViveHand _ejectorHand;

	private FVRViveHand _gateHand;

	private FVRViveHand _cylinderHand;

	private float _gateStartLocalY;

	private bool _hasEjectedThisStroke;

	private bool _hasIndexedThisPress;

	private void Awake()
	{
		_revolver = ((Component)this).GetComponent<SingleActionRevolver>();
		if (!((Object)(object)_revolver != (Object)null))
		{
			return;
		}
		_revolver.StateToggles = false;
		if (DebugMode)
		{
			Debug.Log((object)("SingleActionPhysicalEnhancer: Initialized on revolver " + ((Object)((Component)this).gameObject).name));
		}
		SingleActionEjectorRod componentInChildren = ((Component)this).GetComponentInChildren<SingleActionEjectorRod>();
		if ((Object)(object)componentInChildren != (Object)null)
		{
			Collider component = ((Component)componentInChildren).GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				component.enabled = false;
			}
		}
	}

	private void Update()
	{
		if (!((Object)(object)_revolver == (Object)null))
		{
			FVRViveHand[] hands = Object.FindObjectsOfType<FVRViveHand>();
			UpdateGateInteraction(hands);
			UpdateEjectorInteraction(hands);
			UpdateCylinderInteraction(hands);
			UpdateCartridgeDetection(hands);
			UpdateSlidingRounds(hands);
		}
	}

	private void OffsetChamber(int offset)
	{
		int numChambers = _revolver.Cylinder.NumChambers;
		int num = (_revolver.CurChamber + offset) % numChambers;
		if (num < 0)
		{
			num += numChambers;
		}
		_revolver.CurChamber = num;
		_revolver.UpdateCylinderRot();
	}

	private bool IsHandHoldingGun(FVRViveHand hand)
	{
		if ((Object)(object)hand == (Object)null)
		{
			return false;
		}
		if ((Object)(object)hand.CurrentInteractable == (Object)(object)_revolver)
		{
			return true;
		}
		if ((Object)(object)((FVRPhysicalObject)_revolver).AltGrip != (Object)null && (Object)(object)hand.CurrentInteractable == (Object)(object)((FVRPhysicalObject)_revolver).AltGrip)
		{
			return true;
		}
		return false;
	}

	private void UpdateGateInteraction(FVRViveHand[] hands)
	{
		//IL_0113: 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_011d: 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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_gateHand == (Object)null)
		{
			foreach (FVRViveHand val in hands)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.PalmTransform == (Object)null) && !IsHandHoldingGun(val))
				{
					float num = Vector3.Distance(val.PalmTransform.position, _revolver.LoadingGate.position);
					if (num < 0.04f && val.Input.TriggerPressed)
					{
						_gateHand = val;
						_gateStartLocalY = ((Component)_revolver).transform.InverseTransformPoint(val.PalmTransform.position).y;
						break;
					}
				}
			}
			return;
		}
		if (!_gateHand.Input.TriggerPressed)
		{
			_gateHand = null;
			return;
		}
		float y = ((Component)_revolver).transform.InverseTransformPoint(_gateHand.PalmTransform.position).y;
		float num2 = y - _gateStartLocalY;
		if (num2 < -0.02f && !_revolver.m_isStateToggled)
		{
			if (DebugMode)
			{
				Debug.Log((object)"SingleActionPhysicalEnhancer: Manual gate opening registered.");
			}
			_revolver.ToggleState();
			((FVRFireArm)_revolver).PlayAudioEvent((FirearmAudioEventType)17, 1f);
			_gateHand = null;
		}
		else if (num2 > 0.02f && _revolver.m_isStateToggled)
		{
			if (DebugMode)
			{
				Debug.Log((object)"SingleActionPhysicalEnhancer: Manual gate closing registered.");
			}
			_revolver.ToggleState();
			((FVRFireArm)_revolver).PlayAudioEvent((FirearmAudioEventType)18, 1f);
			_gateHand = null;
		}
	}

	private void UpdateEjectorInteraction(FVRViveHand[] hands)
	{
		//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)
		//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_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		Vector3 ejectorRod_Pos_Forward = _revolver.EjectorRod_Pos_Forward;
		Vector3 ejectorRod_Pos_Rearward = _revolver.EjectorRod_Pos_Rearward;
		if ((Object)(object)_ejectorHand == (Object)null)
		{
			foreach (FVRViveHand val in hands)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.PalmTransform == (Object)null) && !IsHandHoldingGun(val))
				{
					float num = Vector3.Distance(val.PalmTransform.position, _revolver.EjectorRod.position);
					if (num < 0.04f && val.Input.TriggerPressed)
					{
						_ejectorHand = val;
						break;
					}
				}
			}
		}
		else if (!_ejectorHand.Input.TriggerPressed)
		{
			_ejectorHand = null;
		}
		else
		{
			float num2 = Mathf.Clamp(((Component)_revolver).transform.InverseTransformPoint(((HandInput)(ref _ejectorHand.Input)).Pos).z, ejectorRod_Pos_Forward.z, ejectorRod_Pos_Rearward.z);
			_revolver.EjectorRod.localPosition = new Vector3(_revolver.EjectorRod.localPosition.x, _revolver.EjectorRod.localPosition.y, num2);
			float num3 = (num2 - ejectorRod_Pos_Forward.z) / (ejectorRod_Pos_Rearward.z - ejectorRod_Pos_Forward.z);
			if (num3 > 0.9f && !_hasEjectedThisStroke)
			{
				if (DebugMode)
				{
					Debug.Log((object)"SingleActionPhysicalEnhancer: Ejector stroke completed. Clearing chamber.");
				}
				_revolver.EjectPrevCylinder();
				_hasEjectedThisStroke = true;
			}
		}
		if ((Object)(object)_ejectorHand == (Object)null)
		{
			_revolver.EjectorRod.localPosition = Vector3.MoveTowards(_revolver.EjectorRod.localPosition, ejectorRod_Pos_Forward, Time.deltaTime * 2f);
			_hasEjectedThisStroke = false;
		}
	}

	private void UpdateCylinderInteraction(FVRViveHand[] hands)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_cylinderHand == (Object)null)
		{
			foreach (FVRViveHand val in hands)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.PalmTransform == (Object)null) && !IsHandHoldingGun(val))
				{
					float num = Vector3.Distance(val.PalmTransform.position, ((Component)_revolver.Cylinder).transform.position);
					if (num < 0.06f && val.Input.GripPressed && _revolver.m_isStateToggled)
					{
						_cylinderHand = val;
						_hasIndexedThisPress = false;
						break;
					}
				}
			}
		}
		else if (!_cylinderHand.Input.GripPressed || !_revolver.m_isStateToggled)
		{
			_cylinderHand = null;
		}
		else if (_cylinderHand.Input.TouchpadDown || _cylinderHand.Input.TriggerDown || _cylinderHand.Input.AXButtonDown || _cylinderHand.Input.BYButtonDown)
		{
			if (!_hasIndexedThisPress)
			{
				if (DebugMode)
				{
					Debug.Log((object)"SingleActionPhysicalEnhancer: Offhand index input registered.");
				}
				OffsetChamber(1);
				_hasIndexedThisPress = true;
			}
		}
		else
		{
			_hasIndexedThisPress = false;
		}
	}

	private void UpdateCartridgeDetection(FVRViveHand[] hands)
	{
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		if (!_revolver.m_isStateToggled)
		{
			return;
		}
		int num = _revolver.PrevChamber;
		if (_revolver.IsAccessTwoChambersBack)
		{
			num = _revolver.PrevChamber2;
		}
		FVRFireArmChamber val = _revolver.Cylinder.Chambers[num];
		if (val.IsFull)
		{
			return;
		}
		foreach (FVRViveHand val2 in hands)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			FVRInteractiveObject currentInteractable = val2.CurrentInteractable;
			FVRFireArmRound val3 = (FVRFireArmRound)(object)((currentInteractable is FVRFireArmRound) ? currentInteractable : null);
			if (!((Object)(object)val3 != (Object)null))
			{
				continue;
			}
			float num2 = Vector3.Distance(((Component)val3).transform.position, ((Component)val).transform.position);
			if (num2 < 0.05f && !IsRoundAlreadySliding(val3))
			{
				if (DebugMode)
				{
					Debug.Log((object)("SingleActionPhysicalEnhancer: Proximity trigger met. Dropping cartridge and binding round: " + ((Object)val3).name));
				}
				((FVRInteractiveObject)val3).ForceBreakInteraction();
				BindRoundToChamber(val3, val, val2);
			}
		}
	}

	private bool IsRoundAlreadySliding(FVRFireArmRound round)
	{
		for (int i = 0; i < _slidingRounds.Count; i++)
		{
			if ((Object)(object)_slidingRounds[i].Round == (Object)(object)round)
			{
				return true;
			}
		}
		return false;
	}

	private void BindRoundToChamber(FVRFireArmRound round, FVRFireArmChamber chamber, FVRViveHand hand)
	{
		Rigidbody component = ((Component)round).GetComponent<Rigidbody>();
		if ((Object)(object)component != (Object)null)
		{
			component.isKinematic = true;
			component.useGravity = false;
		}
		Collider[] componentsInChildren = ((Component)round).GetComponentsInChildren<Collider>();
		Collider[] array = componentsInChildren;
		foreach (Collider val in array)
		{
			val.enabled = false;
		}
		float num = 0f - CartridgePivotOffset;
		ActiveSlidingRound activeSlidingRound = new ActiveSlidingRound();
		activeSlidingRound.Round = round;
		activeSlidingRound.Chamber = chamber;
		activeSlidingRound.Hand = hand;
		activeSlidingRound.MaxZ = num;
		activeSlidingRound.MinZ = num - CartridgeLength;
		activeSlidingRound.LocalProgress = activeSlidingRound.MinZ;
		_slidingRounds.Add(activeSlidingRound);
	}

	private void UpdateSlidingRounds(FVRViveHand[] hands)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: 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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: 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_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//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_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		for (int num = _slidingRounds.Count - 1; num >= 0; num--)
		{
			ActiveSlidingRound activeSlidingRound = _slidingRounds[num];
			if ((Object)(object)activeSlidingRound.Round == (Object)null || (Object)(object)activeSlidingRound.Chamber == (Object)null)
			{
				_slidingRounds.RemoveAt(num);
			}
			else if (((FVRInteractiveObject)activeSlidingRound.Round).IsHeld)
			{
				if (DebugMode)
				{
					Debug.Log((object)"SingleActionPhysicalEnhancer: Cartridge was grabbed again. Restoring physics.");
				}
				RestoreRoundPhysics(activeSlidingRound.Round);
				_slidingRounds.RemoveAt(num);
			}
			else
			{
				Vector3 forward = ((Component)activeSlidingRound.Chamber).transform.forward;
				Vector3 position = ((Component)activeSlidingRound.Chamber).transform.position;
				foreach (FVRViveHand val in hands)
				{
					if (!((Object)(object)val == (Object)null) && !((Object)(object)val.PalmTransform == (Object)null))
					{
						Vector3 val2 = val.PalmTransform.position - position;
						float num2 = Vector3.Dot(val2, forward);
						Vector3 val3 = val2 - forward * num2;
						if (((Vector3)(ref val3)).magnitude < 0.03f && num2 < activeSlidingRound.MaxZ && num2 > activeSlidingRound.LocalProgress)
						{
							activeSlidingRound.LocalProgress = num2;
						}
					}
				}
				((Component)activeSlidingRound.Round).transform.position = ((Component)activeSlidingRound.Chamber).transform.position + ((Component)activeSlidingRound.Chamber).transform.forward * activeSlidingRound.LocalProgress;
				((Component)activeSlidingRound.Round).transform.rotation = ((Component)activeSlidingRound.Chamber).transform.rotation;
				if (activeSlidingRound.LocalProgress >= activeSlidingRound.MaxZ - 0.002f)
				{
					if (DebugMode)
					{
						Debug.Log((object)"SingleActionPhysicalEnhancer: Cartridge reached seating threshold. Chambering round.");
					}
					activeSlidingRound.Chamber.Autochamber(activeSlidingRound.Round.RoundClass);
					((FVRFireArm)_revolver).PlayAudioEvent((FirearmAudioEventType)42, 1f);
					((Component)activeSlidingRound.Round).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)activeSlidingRound.Round).gameObject);
					_slidingRounds.RemoveAt(num);
				}
			}
		}
	}

	private void RestoreRoundPhysics(FVRFireArmRound round)
	{
		Rigidbody component = ((Component)round).GetComponent<Rigidbody>();
		if ((Object)(object)component != (Object)null)
		{
			component.isKinematic = false;
			component.useGravity = true;
		}
		Collider[] componentsInChildren = ((Component)round).GetComponentsInChildren<Collider>();
		Collider[] array = componentsInChildren;
		foreach (Collider val in array)
		{
			val.enabled = true;
		}
	}
}
public class ActiveSlidingRound
{
	public FVRFireArmRound Round;

	public FVRFireArmChamber Chamber;

	public FVRViveHand Hand;

	public float MinZ;

	public float MaxZ;

	public float LocalProgress;
}
public class AdvanceInternalMagazineLoading : MonoBehaviour
{
	[Header("Debug")]
	[Tooltip("Enables on-screen console logging for push-to-seat loading, sticky bolt velocity, and clip knockout forces.")]
	public bool Debug;

	[Header("Target Components")]
	[Tooltip("Reference to the root BoltActionRifle component.")]
	public BoltActionRifle Rifle;

	[Tooltip("Reference to the internal FVRFireArmMagazine component.")]
	public FVRFireArmMagazine InternalMagazine;

	[Tooltip("Reference to the child FVRFireArmMagazineReloadTrigger component.")]
	public FVRFireArmMagazineReloadTrigger ReloadTrigger;

	[Header("Smooth Push-To-Seat Ingestion")]
	[Tooltip("Downward distance in meters the cartridge must be pressed into the well to seat into the magazine.")]
	public float RequiredInsertionDepth = 0.01f;

	[Tooltip("Maximum depth in meters the visual cartridge is allowed to sink into the receiver well, stopping it from clipping through the bottom of the gun.")]
	public float MaxVisualDepression = 0.012f;

	[Tooltip("Resistance dampening factor applied to hand movement while depressing the cartridge into the loading well.")]
	public float ElasticResistanceRatio = 0.35f;

	[Tooltip("Minimum time delay between successive round seatings to prevent double-feeding palmed stacks in a single frame.")]
	public float SeatingCooldown = 0.2f;

	[Tooltip("Optional audio played when a round is successfully pushed down past the internal magazine feed lips.")]
	public AudioEvent CustomSeatAudio;

	[Header("Stripper Clip Resistance & Physical Stop")]
	[Tooltip("Enforces physical forward bolt momentum to knock out an empty stripper clip rather than automatically dropping it upon touching the handle.")]
	public bool RequireHardBoltSlamForClipKnockout = true;

	[Tooltip("Forward velocity threshold of the bolt stroke required to knock the empty stripper clip out of the guide.")]
	public float ClipKnockoutForwardVelocity = 0.85f;

	[Tooltip("Normalized position along the bolt travel (0 = Forward, 1 = Rear) where the bolt physically stops against a seated empty clip.")]
	public float ClipPhysicalStopNormalized = 0.45f;

	[Header("Velocity-Sensitive Ejection")]
	[Tooltip("Enables dynamic scaling of casing ejection forces based on how fast the player pulls the bolt rearward.")]
	public bool EnableVelocitySensitiveEjection = true;

	[Tooltip("Bolt retraction speed threshold below which the extracted casing drops weakly or sits loose inside the receiver.")]
	public float SlowBoltSpeedThreshold = 0.8f;

	[Tooltip("Multiplier applied to native ejection forces when the bolt is pulled back slower than the SlowBoltSpeedThreshold.")]
	public float SlowEjectionMultiplier = 0.05f;

	[Header("Sticky Bolt Resistance")]
	[Tooltip("Simulates mechanical binding and expanded fired casings by requiring an upward velocity spike (palm slap) to unlock the bolt handle on spent rounds.")]
	public bool EnableStickyBolt = true;

	[Tooltip("Upward linear velocity threshold of the controller required to break the initial extraction camming resistance on a fired cartridge.")]
	public float StickyBreakawayVelocity = 0.75f;

	[Tooltip("Maximum rotation angle the bolt handle can travel upward before static friction halts it if breakaway velocity is not met.")]
	public float StickyMaxStuckAngle = 18f;

	private BoltActionRifle m_rifle;

	private BoltActionRifle_Handle m_handle;

	private FVRFireArmChamber m_chamber;

	private FVRFireArmClip m_heldClip;

	private FVRFireArmRound m_lockedRound;

	private float m_origRightForce;

	private float m_origUpForce;

	private float m_origSpinTorque;

	private float m_prevBoltLerp;

	private float m_strokeSpeed;

	private bool m_isStickyBroken;

	private float m_timeSinceLastSeat;

	private void Awake()
	{
		m_rifle = Rifle;
		if ((Object)(object)m_rifle == (Object)null)
		{
			m_rifle = ((Component)this).GetComponent<BoltActionRifle>();
			Rifle = m_rifle;
		}
		if ((Object)(object)m_rifle != (Object)null)
		{
			m_handle = m_rifle.BoltHandle;
			m_chamber = m_rifle.Chamber;
			if ((Object)(object)InternalMagazine == (Object)null)
			{
				InternalMagazine = ((FVRFireArm)m_rifle).Magazine;
			}
			if ((Object)(object)ReloadTrigger == (Object)null)
			{
				ReloadTrigger = ((Component)m_rifle).GetComponentInChildren<FVRFireArmMagazineReloadTrigger>(true);
			}
			m_origRightForce = m_rifle.RightwardEjectionForce;
			m_origUpForce = m_rifle.UpwardEjectionForce;
			m_origSpinTorque = m_rifle.YSpinEjectionTorque;
		}
		m_heldClip = null;
		m_lockedRound = null;
		m_prevBoltLerp = 0f;
		m_strokeSpeed = 0f;
		m_isStickyBroken = false;
		m_timeSinceLastSeat = 0f;
	}

	private void Start()
	{
		if ((Object)(object)ReloadTrigger != (Object)null)
		{
			((Component)ReloadTrigger).gameObject.tag = "Untagged";
		}
		if ((Object)(object)InternalMagazine != (Object)null)
		{
			InternalMagazine.IsDropInLoadable = false;
			InternalMagazine.IsIntegrated = true;
		}
	}

	private void Update()
	{
		if ((Object)(object)m_rifle == (Object)null)
		{
			return;
		}
		if (m_timeSinceLastSeat < SeatingCooldown)
		{
			m_timeSinceLastSeat += Time.deltaTime;
		}
		float num = m_rifle.BoltLerp - m_prevBoltLerp;
		float num2 = Mathf.Abs(num) / Mathf.Max(Time.deltaTime, 0.0001f);
		if (num > 0.001f)
		{
			m_strokeSpeed = num2;
		}
		if ((Object)(object)m_lockedRound != (Object)null && (!((FVRInteractiveObject)m_lockedRound).IsHeld || (Object)(object)((Component)m_lockedRound).gameObject == (Object)null))
		{
			if ((Object)(object)m_lockedRound != (Object)null)
			{
				((FVRPhysicalObject)m_lockedRound).IsPivotLocked = false;
			}
			m_lockedRound = null;
		}
		if (RequireHardBoltSlamForClipKnockout)
		{
			ProcessStripperClipPhysics(num, num2);
		}
		if (EnableVelocitySensitiveEjection)
		{
			ProcessVelocityEjection();
		}
		if (EnableStickyBolt)
		{
			ProcessStickyBolt();
		}
		m_prevBoltLerp = m_rifle.BoltLerp;
	}

	private void ProcessStripperClipPhysics(float deltaLerp, float currentSpeed)
	{
		//IL_004e: 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_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((FVRFireArm)m_rifle).Clip != (Object)null)
		{
			m_heldClip = ((FVRFireArm)m_rifle).Clip;
			((FVRFireArm)m_rifle).Clip = null;
		}
		if (!((Object)(object)m_heldClip != (Object)null))
		{
			return;
		}
		if ((int)m_heldClip.State == 0 || (Object)(object)m_heldClip.FireArm == (Object)null)
		{
			m_heldClip = null;
		}
		else
		{
			if (m_heldClip.m_numRounds > 0)
			{
				return;
			}
			if (deltaLerp < -0.005f && currentSpeed >= ClipKnockoutForwardVelocity)
			{
				if (Debug)
				{
					Debug.Log((object)$"[AdvanceInternalMag] Hard Bolt Slam Knocked Clip! Speed: {currentSpeed:F2}");
				}
				m_heldClip.Release();
				m_heldClip = null;
			}
			else if ((Object)(object)m_handle != (Object)null && (Object)(object)m_handle.Point_Forward != (Object)null && (Object)(object)m_handle.Point_Rearward != (Object)null && m_rifle.BoltLerp < ClipPhysicalStopNormalized && (int)m_handle.HandleState != 0)
			{
				Vector3 position = Vector3.Lerp(m_handle.Point_Forward.position, m_handle.Point_Rearward.position, ClipPhysicalStopNormalized);
				m_handle.BoltActionHandleRoot.position = position;
			}
		}
	}

	private void ProcessVelocityEjection()
	{
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Invalid comparison between Unknown and I4
		if (m_rifle.BoltLerp > 0.4f)
		{
			if (m_strokeSpeed < SlowBoltSpeedThreshold)
			{
				m_rifle.RightwardEjectionForce = m_origRightForce * SlowEjectionMultiplier;
				m_rifle.UpwardEjectionForce = m_origUpForce * SlowEjectionMultiplier;
				m_rifle.YSpinEjectionTorque = m_origSpinTorque * SlowEjectionMultiplier;
			}
			else
			{
				m_rifle.RightwardEjectionForce = m_origRightForce;
				m_rifle.UpwardEjectionForce = m_origUpForce;
				m_rifle.YSpinEjectionTorque = m_origSpinTorque;
			}
		}
		else
		{
			Rifle.RightwardEjectionForce = m_origRightForce;
			Rifle.UpwardEjectionForce = m_origUpForce;
			Rifle.YSpinEjectionTorque = m_origSpinTorque;
		}
		if (Debug && (int)m_rifle.CurBoltHandleState == 2)
		{
			Debug.Log((object)$"[AdvanceInternalMag] Rear Ejection Speed: {m_strokeSpeed:F2} | Force Mult: {m_rifle.RightwardEjectionForce / Mathf.Max(m_origRightForce, 0.001f):F2}");
		}
	}

	private void ProcessStickyBolt()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		//IL_0049: 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_00c6: 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)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Invalid comparison between Unknown and I4
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_handle == (Object)null || (Object)(object)m_chamber == (Object)null)
		{
			return;
		}
		if ((int)m_handle.HandleRot == 2)
		{
			m_isStickyBroken = false;
		}
		if ((int)m_handle.HandleState != 0 || !m_chamber.IsFull || !m_chamber.IsSpent || m_isStickyBroken || !((FVRInteractiveObject)m_handle).IsHeld || !((Object)(object)((FVRInteractiveObject)m_handle).m_hand != (Object)null))
		{
			return;
		}
		Vector3 velLinearWorld = ((FVRInteractiveObject)m_handle).m_hand.Input.VelLinearWorld;
		float num = Vector3.Dot(velLinearWorld, ((Component)m_rifle).transform.up);
		if (num >= StickyBreakawayVelocity)
		{
			m_isStickyBroken = true;
			((FVRInteractiveObject)m_handle).m_hand.Buzz(((FVRInteractiveObject)m_handle).m_hand.Buzzer.Buzz_BeginInteraction);
			if (Debug)
			{
				Debug.Log((object)$"[AdvanceInternalMag] Sticky Breakaway Overcome! Speed: {num:F2}");
			}
		}
		else if (m_handle.rotAngle > StickyMaxStuckAngle)
		{
			m_handle.rotAngle = StickyMaxStuckAngle;
			m_handle.BoltActionHandle.localEulerAngles = new Vector3(0f, 0f, StickyMaxStuckAngle);
			if (m_handle.UsesExtraRotationPiece && (Object)(object)m_handle.ExtraRotationPiece != (Object)null)
			{
				m_handle.ExtraRotationPiece.localEulerAngles = new Vector3(0f, 0f, StickyMaxStuckAngle);
			}
			m_handle.HandleRot = (BoltActionHandleRot)1;
			if ((int)m_rifle.CockType == 1 && m_rifle.m_isHammerCocked)
			{
				m_rifle.m_isHammerCocked = false;
			}
			((FVRInteractiveObject)m_handle).m_hand.Buzz(((FVRInteractiveObject)m_handle).m_hand.Buzzer.Buzz_OnHoverInteractive);
		}
	}

	private void OnTriggerStay(Collider other)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_rifle == (Object)null || (Object)(object)InternalMagazine == (Object)null || m_timeSinceLastSeat < SeatingCooldown)
		{
			return;
		}
		if ((int)m_rifle.CurBoltHandleState == 0)
		{
			if ((Object)(object)m_lockedRound != (Object)null)
			{
				((FVRPhysicalObject)m_lockedRound).IsPivotLocked = false;
				m_lockedRound = null;
			}
			return;
		}
		if (InternalMagazine.IsFull())
		{
			if ((Object)(object)m_lockedRound != (Object)null)
			{
				((FVRPhysicalObject)m_lockedRound).IsPivotLocked = false;
				m_lockedRound = null;
			}
			return;
		}
		FVRFireArmRound val = null;
		if ((Object)(object)other.attachedRigidbody != (Object)null)
		{
			val = ((Component)other.attachedRigidbody).GetComponent<FVRFireArmRound>();
		}
		if ((Object)(object)val == (Object)null)
		{
			val = ((Component)other).GetComponent<FVRFireArmRound>();
		}
		if (!((Object)(object)val == (Object)null) && !val.IsSpent && val.RoundType == InternalMagazine.RoundType && ((FVRInteractiveObject)val).IsHeld && (Object)(object)((FVRInteractiveObject)val).m_hand != (Object)null)
		{
			Transform val2 = ((!((Object)(object)ReloadTrigger != (Object)null)) ? ((Component)m_rifle).transform : ((Component)ReloadTrigger).transform);
			((FVRPhysicalObject)val).IsPivotLocked = true;
			m_lockedRound = val;
			Vector3 pos = ((HandInput)(ref ((FVRInteractiveObject)val).m_hand.Input)).Pos;
			Vector3 val3 = pos - val2.position;
			float num = Vector3.Dot(val3, -((Component)m_rifle).transform.up);
			float num2 = Mathf.Clamp(num * ElasticResistanceRatio, 0f, MaxVisualDepression);
			((FVRPhysicalObject)val).PivotLockPos = val2.position - ((Component)m_rifle).transform.up * num2;
			((FVRPhysicalObject)val).PivotLockRot = val2.rotation;
			if (num > 0.002f)
			{
				((FVRInteractiveObject)val).m_hand.Buzz(((FVRInteractiveObject)val).m_hand.Buzzer.Buzz_OnHoverInteractive);
			}
			if (num >= RequiredInsertionDepth)
			{
				SeatRoundIntoMagazine(val);
				m_lockedRound = null;
			}
			else if (Debug)
			{
				Debug.Log((object)$"[AdvanceInternalMag] Smooth Depth: {num:F3}m / Required: {RequiredInsertionDepth:F3}m");
			}
		}
	}

	private void OnTriggerExit(Collider other)
	{
		if (!((Object)(object)m_lockedRound != (Object)null))
		{
			return;
		}
		FVRFireArmRound val = null;
		if ((Object)(object)other.attachedRigidbody != (Object)null)
		{
			val = ((Component)other.attachedRigidbody).GetComponent<FVRFireArmRound>();
		}
		if ((Object)(object)val == (Object)null)
		{
			val = ((Component)other).GetComponent<FVRFireArmRound>();
		}
		if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)m_lockedRound)
		{
			((FVRPhysicalObject)m_lockedRound).IsPivotLocked = false;
			m_lockedRound = null;
			if (Debug)
			{
				Debug.Log((object)"[AdvanceInternalMag] Round exited well. Restored free hand tracking.");
			}
		}
	}

	private void SeatRoundIntoMagazine(FVRFireArmRound round)
	{
		//IL_0035: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		m_timeSinceLastSeat = 0f;
		((FVRPhysicalObject)round).IsPivotLocked = false;
		if (round.ProxyRounds.Count > 0)
		{
			round.CycleToProxy(true, false);
		}
		InternalMagazine.AddRound(round.RoundClass, true, true);
		if (CustomSeatAudio != null)
		{
			SM.PlayGenericSound(CustomSeatAudio, ((Component)this).transform.position);
		}
		else if ((Object)(object)InternalMagazine.Profile != (Object)null)
		{
			SM.PlayGenericSound(InternalMagazine.Profile.MagazineInsertRound, ((Component)this).transform.position);
		}
		if ((Object)(object)((FVRInteractiveObject)round).m_hand != (Object)null)
		{
			((FVRInteractiveObject)round).m_hand.Buzz(((FVRInteractiveObject)round).m_hand.Buzzer.Buzz_BeginInteraction);
		}
		((FVRInteractiveObject)round).ForceBreakInteraction();
		Object.Destroy((Object)(object)((Component)round).gameObject);
		if (Debug)
		{
			Debug.Log((object)$"[AdvanceInternalMag] Round seated successfully. Magazine count: {InternalMagazine.m_numRounds}/{InternalMagazine.m_capacity}");
		}
	}
}
public class PushFeedBoltAction : MonoBehaviour
{
	[Header("Rifle Reference")]
	[Tooltip("The bolt-action rifle this script adds push-feed behavior to. If left empty, it will find one on this GameObject.")]
	public BoltActionRifle Rifle;

	[Header("Feed Type")]
	[Tooltip("If true, push-feed failure behavior is disabled and the rifle behaves like a controlled-feed action.")]
	public bool UsesControlledFeed = false;

	[Header("Push-Feed Timing")]
	[Tooltip("Bolt travel threshold (0 = closed, 1 = open). If the bolt reverses direction after passing below this value without closing, the round is left loose in the action.")]
	[Range(0.05f, 0.9f)]
	public float CommitThreshold = 0.4f;

	[Tooltip("Minimum rearward distance the bolt must travel after passing the threshold before a short-stroke is triggered. Prevents VR hand tracking jitter from dropping rounds.")]
	[Range(0.01f, 0.1f)]
	public float ReversalDeadzone = 0.035f;

	[Header("Muzzle Orientation")]
	[Tooltip("Angle between muzzle forward and straight up. If pointing downward past this angle during magazine pickup, the round drops free.")]
	[Range(0f, 180f)]
	public float MuzzleDownFailureAngle = 120f;

	[Header("Jam Ejection (Gravity Drops)")]
	[Tooltip("Velocity applied to a round dropped due to pointing the muzzle down, in local space.")]
	public Vector3 JamEjectionLocalVelocity = new Vector3(0f, -0.05f, 0.05f);

	[Tooltip("Angular velocity applied to a dropped round, in local space.")]
	public Vector3 JamEjectionLocalAngularVelocity = new Vector3(20f, 0f, 0f);

	[Header("Audio")]
	[Tooltip("Sound played when a round is left stuck in the action.")]
	public AudioEvent JamSound;

	[Header("Debugging")]
	public bool DebugMode = true;

	private float m_lastBoltLerp;

	private float m_lowestBoltLerpThisStroke = 1f;

	private bool m_wasProxyFullLastFrame;

	private bool m_hasInitializedLerp;

	private bool m_isCommittedThisStroke;

	private GameObject m_looseCartridgeVisual;

	private float m_looseCartridgeLerp;

	private FireArmRoundType m_looseCartridgeType;

	private FireArmRoundClass m_looseCartridgeClass;

	private bool m_hasLooseCartridgeInBreech;

	private bool m_lastTriggerCycledState;

	private void Awake()
	{
		if ((Object)(object)Rifle == (Object)null)
		{
			Rifle = ((Component)this).GetComponent<BoltActionRifle>();
		}
	}

	private void OnDestroy()
	{
		CleanupLooseCartridgeVisual();
	}

	private void Update()
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Rifle == (Object)null || (Object)(object)Rifle.Chamber == (Object)null || (Object)(object)Rifle.m_proxy == (Object)null || (Object)(object)Rifle.Extraction_ChamberPos == (Object)null || (Object)(object)Rifle.Extraction_MagazinePos == (Object)null)
		{
			return;
		}
		float boltLerp = Rifle.BoltLerp;
		bool isFull = Rifle.m_proxy.IsFull;
		if (!m_hasInitializedLerp)
		{
			m_lastBoltLerp = boltLerp;
			m_lowestBoltLerpThisStroke = boltLerp;
			m_wasProxyFullLastFrame = isFull;
			m_hasInitializedLerp = true;
			return;
		}
		if (!UsesControlledFeed)
		{
			bool flag = boltLerp < m_lastBoltLerp;
			bool flag2 = boltLerp > m_lastBoltLerp;
			if (isFull && !m_wasProxyFullLastFrame)
			{
				float num = Vector3.Angle(((Component)Rifle).transform.forward, Vector3.up);
				if (num >= MuzzleDownFailureAngle)
				{
					if (DebugMode)
					{
						Debug.Log((object)("[PushFeed] Gravity failure: muzzle angled downward (" + num.ToString("F1") + " deg) during feed."));
					}
					TriggerGravityFailure();
					isFull = Rifle.m_proxy.IsFull;
				}
			}
			bool isFull2 = Rifle.Chamber.IsFull;
			if (isFull && !isFull2 && !m_hasLooseCartridgeInBreech)
			{
				if (boltLerp < m_lowestBoltLerpThisStroke)
				{
					m_lowestBoltLerpThisStroke = boltLerp;
					if (m_lowestBoltLerpThisStroke <= CommitThreshold && !m_isCommittedThisStroke)
					{
						m_isCommittedThisStroke = true;
						if (DebugMode)
						{
							Debug.Log((object)("[PushFeed] Round committed past feed lips at lerp " + boltLerp.ToString("F3")));
						}
					}
				}
				if (m_isCommittedThisStroke && boltLerp > m_lowestBoltLerpThisStroke + ReversalDeadzone)
				{
					DetachRoundInBreech(m_lowestBoltLerpThisStroke);
				}
			}
			if (boltLerp >= 0.95f && !m_hasLooseCartridgeInBreech)
			{
				m_lowestBoltLerpThisStroke = 1f;
				m_isCommittedThisStroke = false;
			}
			if (m_hasLooseCartridgeInBreech)
			{
				if (flag && boltLerp <= m_looseCartridgeLerp)
				{
					ReattachRoundToBoltProxy(boltLerp);
				}
				else if (boltLerp > 0.45f && (Object)(object)m_looseCartridgeVisual != (Object)null)
				{
					float num2 = Vector3.Angle(((Component)Rifle).transform.forward, Vector3.up);
					float num3 = Vector3.Angle(((Component)Rifle).transform.up, Vector3.down);
					if (num2 >= MuzzleDownFailureAngle || num3 < 60f)
					{
						DumpLooseCartridgeToWorld();
					}
				}
			}
		}
		if (DebugMode)
		{
			RunFiringDiagnostic();
		}
		m_lastBoltLerp = boltLerp;
		m_wasProxyFullLastFrame = Rifle.m_proxy.IsFull;
	}

	private void RunFiringDiagnostic()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Invalid comparison between Unknown and I4
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Invalid comparison between Unknown and I4
		bool hasTriggerCycled = Rifle.m_hasTriggerCycled;
		if (hasTriggerCycled && !m_lastTriggerCycledState)
		{
			FireSelectorMode firingMode = Rifle.GetFiringMode();
			bool flag = firingMode != null && (int)firingMode.ModeType == 0;
			bool isAltHeld = ((FVRPhysicalObject)Rifle).IsAltHeld;
			bool flag2 = (Object)(object)Rifle.BoltHandle != (Object)null && (int)Rifle.BoltHandle.HandleState == 0;
			bool flag3 = (Object)(object)Rifle.BoltHandle != (Object)null && (int)Rifle.BoltHandle.HandleRot != 0;
			bool isHammerCocked = Rifle.IsHammerCocked;
			bool isFull = Rifle.Chamber.IsFull;
			bool isSpent = Rifle.Chamber.IsSpent;
			FVRFireArmRound round = Rifle.Chamber.GetRound();
			string text = ((!((Object)(object)round != (Object)null)) ? "NULL" : (((object)Unsafe.As<FireArmRoundType, FireArmRoundType>(ref round.RoundType)/*cast due to .constrained prefix*/).ToString() + ":" + ((object)Unsafe.As<FireArmRoundClass, FireArmRoundClass>(ref round.RoundClass)/*cast due to .constrained prefix*/).ToString()));
			Debug.Log((object)("[PushFeed Diagnostic] Trigger Pulled! | Safe: " + flag + " | AltHeld: " + isAltHeld + " | HandleForward: " + flag2 + " | HandleLockedDown: " + flag3 + " | HammerCocked: " + isHammerCocked + " | ChamberFull: " + isFull + " | ChamberSpent: " + isSpent + " | ChamberRound: " + text + " | ProxyFull: " + Rifle.m_proxy.IsFull + " | HasLooseInBreech: " + m_hasLooseCartridgeInBreech));
		}
		m_lastTriggerCycledState = hasTriggerCycled;
	}

	private void TriggerGravityFailure()
	{
		//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_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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: 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_0081: 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_0142: 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_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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		FVRFireArmRound round = Rifle.m_proxy.Round;
		if ((Object)(object)round == (Object)null)
		{
			return;
		}
		FireArmRoundType roundType = round.RoundType;
		FireArmRoundClass roundClass = round.RoundClass;
		Rifle.m_proxy.ClearProxy();
		GameObject gameObject = ((AnvilAsset)AM.GetRoundSelfPrefab(roundType, roundClass)).GetGameObject();
		if ((Object)(object)gameObject != (Object)null)
		{
			Vector3 position = Rifle.Extraction_ChamberPos.position;
			Quaternion rotation = Rifle.Extraction_ChamberPos.rotation;
			GameObject val = Object.Instantiate<GameObject>(gameObject, position, rotation);
			FVRFireArmRound component = val.GetComponent<FVRFireArmRound>();
			if ((Object)(object)component != (Object)null && (Object)(object)((FVRPhysicalObject)component).RootRigidbody != (Object)null)
			{
				Vector3 velocity = ((Component)Rifle).transform.TransformVector(JamEjectionLocalVelocity) + GM.CurrentMovementManager.GetFilteredVel();
				Vector3 angularVelocity = ((Component)Rifle).transform.TransformVector(JamEjectionLocalAngularVelocity);
				((FVRPhysicalObject)component).RootRigidbody.velocity = velocity;
				((FVRPhysicalObject)component).RootRigidbody.maxAngularVelocity = 200f;
				((FVRPhysicalObject)component).RootRigidbody.angularVelocity = angularVelocity;
			}
		}
		if (JamSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)10, JamSound, Rifle.Extraction_ChamberPos.position);
		}
		m_isCommittedThisStroke = false;
		m_lowestBoltLerpThisStroke = 1f;
	}

	private void DetachRoundInBreech(float detachmentLerp)
	{
		//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_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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		FVRFireArmRound round = Rifle.m_proxy.Round;
		if (!((Object)(object)round == (Object)null))
		{
			m_looseCartridgeType = round.RoundType;
			m_looseCartridgeClass = round.RoundClass;
			m_looseCartridgeLerp = detachmentLerp;
			m_hasLooseCartridgeInBreech = true;
			CleanupLooseCartridgeVisual();
			m_looseCartridgeVisual = new GameObject("PushFeed_LooseCartridge");
			m_looseCartridgeVisual.transform.SetParent(((Component)Rifle).transform, true);
			MeshFilter val = m_looseCartridgeVisual.AddComponent<MeshFilter>();
			MeshRenderer val2 = m_looseCartridgeVisual.AddComponent<MeshRenderer>();
			val.mesh = AM.GetRoundMesh(m_looseCartridgeType, m_looseCartridgeClass);
			((Renderer)val2).material = AM.GetRoundMaterial(m_looseCartridgeType, m_looseCartridgeClass);
			Vector3 position = Vector3.Lerp(Rifle.Extraction_ChamberPos.position, Rifle.Extraction_MagazinePos.position, detachmentLerp);
			Quaternion rotation = Quaternion.Slerp(Rifle.Extraction_ChamberPos.rotation, Rifle.Extraction_MagazinePos.rotation, detachmentLerp);
			m_looseCartridgeVisual.transform.position = position;
			m_looseCartridgeVisual.transform.rotation = rotation;
			if ((Object)(object)Rifle.m_proxy.ProxyRenderer != (Object)null)
			{
				((Renderer)Rifle.m_proxy.ProxyRenderer).enabled = false;
			}
			if (JamSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, JamSound, Rifle.Extraction_ChamberPos.position);
			}
			if (DebugMode)
			{
				Debug.Log((object)string.Concat("[PushFeed] Short-stroke: Cartridge left in breech at lerp ", detachmentLerp.ToString("F3"), " (", m_looseCartridgeType, " ", m_looseCartridgeClass, ")"));
			}
			m_isCommittedThisStroke = false;
		}
	}

	private void ReattachRoundToBoltProxy(float currentBoltLerp)
	{
		if ((Object)(object)Rifle.m_proxy.ProxyRenderer != (Object)null)
		{
			((Renderer)Rifle.m_proxy.ProxyRenderer).enabled = true;
		}
		CleanupLooseCartridgeVisual();
		m_hasLooseCartridgeInBreech = false;
		m_isCommittedThisStroke = true;
		m_lowestBoltLerpThisStroke = currentBoltLerp;
		if (DebugMode)
		{
			Debug.Log((object)("[PushFeed] Bolt face contacted loose cartridge at lerp " + currentBoltLerp.ToString("F3") + "; pushing cartridge into battery."));
		}
	}

	private void DumpLooseCartridgeToWorld()
	{
		//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)
		//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_0071: 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_0095: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_looseCartridgeVisual == (Object)null)
		{
			m_hasLooseCartridgeInBreech = false;
			return;
		}
		Vector3 position = m_looseCartridgeVisual.transform.position;
		Quaternion rotation = m_looseCartridgeVisual.transform.rotation;
		CleanupLooseCartridgeVisual();
		m_hasLooseCartridgeInBreech = false;
		m_isCommittedThisStroke = false;
		m_lowestBoltLerpThisStroke = 1f;
		Rifle.m_proxy.ClearProxy();
		GameObject gameObject = ((AnvilAsset)AM.GetRoundSelfPrefab(m_looseCartridgeType, m_looseCartridgeClass)).GetGameObject();
		if ((Object)(object)gameObject != (Object)null)
		{
			GameObject val = Object.Instantiate<GameObject>(gameObject, position, rotation);
			FVRFireArmRound component = val.GetComponent<FVRFireArmRound>();
			if ((Object)(object)component != (Object)null && (Object)(object)((FVRPhysicalObject)component).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)component).RootRigidbody.velocity = GM.CurrentMovementManager.GetFilteredVel();
				((FVRPhysicalObject)component).RootRigidbody.maxAngularVelocity = 200f;
				((FVRPhysicalObject)component).RootRigidbody.angularVelocity = ((Component)Rifle).transform.right * 5f;
			}
		}
		if (DebugMode)
		{
			Debug.Log((object)"[PushFeed] Loose cartridge dumped out of open action.");
		}
	}

	private void CleanupLooseCartridgeVisual()
	{
		if ((Object)(object)m_looseCartridgeVisual != (Object)null)
		{
			Object.Destroy((Object)(object)m_looseCartridgeVisual);
			m_looseCartridgeVisual = null;
		}
	}
}
[DefaultExecutionOrder(-100)]
public class StockControlFMG9 : MonoBehaviour
{
	public ClosedBoltWeapon Gun;

	public MovableObjectPart FoldingPart;

	public List<FVRInteractiveObject> InteractiveObjectsToDisable = new List<FVRInteractiveObject>();

	public List<Collider> CollidersToDisable = new List<Collider>();

	public List<GameObject> GameObjectsToNoCol = new List<GameObject>();

	public float FlickAngularThreshold = 10f;

	public float FlickLinearThreshold = 3f;

	public E_State FoldedState = (E_State)2;

	public bool IsSafeWhenMid = true;

	public bool DebugMode = false;

	private FieldInfo _currentPositionValueField;

	private FieldInfo _lastStateField;

	private Dictionary<Collider, int> _originalColliderLayers = new Dictionary<Collider, int>();

	private Dictionary<GameObject, int> _originalGOLayers = new Dictionary<GameObject, int>();

	private List<Collider> _foldingPartColliders = new List<Collider>();

	private FireSelectorModeType[] _originalModes;

	private bool _wasFolded = false;

	private bool _hasInteractedYet = false;

	private float _flickCooldown = 0f;

	private void Start()
	{
		if ((Object)(object)FoldingPart != (Object)null)
		{
			_currentPositionValueField = typeof(MovableObjectPart).GetField("_currentPositionValue", BindingFlags.Instance | BindingFlags.NonPublic);
			_lastStateField = typeof(MovableObjectPart).GetField("_lastState", BindingFlags.Instance | BindingFlags.NonPublic);
			_foldingPartColliders.AddRange(((Component)FoldingPart).GetComponentsInChildren<Collider>());
		}
		if ((object)_currentPositionValueField == null || (object)_lastStateField == null)
		{
			Debug.LogError((object)"StockControlFMG9: Reflection failed to find required fields! Disabling script.");
			((Behaviour)this).enabled = false;
			return;
		}
		foreach (Collider item in CollidersToDisable)
		{
			if ((Object)(object)item != (Object)null)
			{
				_originalColliderLayers[item] = ((Component)item).gameObject.layer;
			}
		}
		foreach (GameObject item2 in GameObjectsToNoCol)
		{
			if ((Object)(object)item2 != (Object)null)
			{
				_originalGOLayers[item2] = item2.layer;
			}
		}
		_wasFolded = false;
		OnUnfold();
	}

	private void Update()
	{
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: 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_016b: Invalid comparison between Unknown and I4
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: 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_0280: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)FoldingPart == (Object)null || (Object)(object)Gun == (Object)null)
		{
			return;
		}
		if (_flickCooldown > 0f)
		{
			_flickCooldown -= Time.deltaTime;
		}
		if (!_hasInteractedYet)
		{
			if (!((FVRInteractiveObject)FoldingPart).IsHeld)
			{
				_wasFolded = false;
				return;
			}
			_hasInteractedYet = true;
			if (DebugMode)
			{
				Debug.Log((object)"StockControlFMG9: Interaction detected. Activating tracking.");
			}
		}
		bool flag = EvaluateFoldState();
		if (DebugMode)
		{
			Debug.Log((object)string.Concat("StockControlFMG9: State: ", FoldingPart.State, " | isFolded: ", flag, " | FoldedStateConfig: ", FoldedState));
		}
		if (flag)
		{
			if (!_wasFolded)
			{
				_wasFolded = true;
				OnFold();
			}
		}
		else if (_wasFolded)
		{
			_wasFolded = false;
			OnUnfold();
		}
		if ((Object)(object)Gun.Bolt != (Object)null)
		{
			if ((int)Gun.Bolt.CurPos != 0 && !flag)
			{
				if (((FVRInteractiveObject)FoldingPart).IsHeld)
				{
					((FVRInteractiveObject)FoldingPart).ForceBreakInteraction();
					if (DebugMode)
					{
						Debug.Log((object)"StockControlFMG9: Bolt is back! Forcing stock interaction release.");
					}
				}
				SetCollidersActive(_foldingPartColliders, active: false);
			}
			else
			{
				SetCollidersActive(_foldingPartColliders, active: true);
			}
		}
		if (!flag || !(_flickCooldown <= 0f) || ((FVRInteractiveObject)FoldingPart).IsHeld || !((FVRInteractiveObject)Gun).IsHeld || (!((Object)(object)((FVRPhysicalObject)Gun).AltGrip == (Object)null) && ((FVRInteractiveObject)((FVRPhysicalObject)Gun).AltGrip).IsHeld) || !((Object)(object)((FVRPhysicalObject)Gun).RootRigidbody != (Object)null))
		{
			return;
		}
		Vector3 angularVelocity = ((FVRPhysicalObject)Gun).RootRigidbody.angularVelocity;
		float magnitude = ((Vector3)(ref angularVelocity)).magnitude;
		Vector3 velocity = ((FVRPhysicalObject)Gun).RootRigidbody.velocity;
		float magnitude2 = ((Vector3)(ref velocity)).magnitude;
		if (magnitude > FlickAngularThreshold && magnitude2 > FlickLinearThreshold)
		{
			if (DebugMode)
			{
				Debug.Log((object)("StockControlFMG9: Flick detected! Angular: " + magnitude + " Linear: " + magnitude2));
			}
			DeployStock();
		}
	}

	private void DeployStock()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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_008f: 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_009b: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Invalid comparison between Unknown and I4
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Invalid comparison between Unknown and I4
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		_flickCooldown = 0.5f;
		E_State val = (E_State)(((int)FoldedState == 0) ? 2 : 0);
		float num = (((int)val != 0) ? FoldingPart.UpperLimit : FoldingPart.LowerLimit);
		if ((object)_currentPositionValueField != null)
		{
			_currentPositionValueField.SetValue(FoldingPart, num);
		}
		if ((object)_lastStateField != null)
		{
			_lastStateField.SetValue(FoldingPart, val);
		}
		FoldingPart.State = val;
		if ((int)FoldingPart.MovementMode == 0)
		{
			UnityEngineExtensions.ModifyLocalPositionAxisValue(FoldingPart.ObjectToMove, FoldingPart.MovementAxis, num);
		}
		else if ((int)FoldingPart.MovementMode == 1)
		{
			UnityEngineExtensions.ModifyLocalRotationAxisValue(FoldingPart.ObjectToMove, FoldingPart.MovementAxis, num);
		}
		else if ((int)FoldingPart.MovementMode == 2)
		{
			FoldingPart.ObjectToMove.localRotation = OpenScripts2_BasePlugin.GetTargetQuaternionFromAxis(num, FoldingPart.MovementAxis);
		}
		ManipulateTransforms[] componentsInChildren = ((Component)Gun).GetComponentsInChildren<ManipulateTransforms>(true);
		if (componentsInChildren != null)
		{
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					componentsInChildren[i].Awake();
				}
			}
		}
		SM.PlayGenericSound(FoldingPart.OpenSounds, FoldingPart.ObjectToMove.position);
	}

	private bool EvaluateFoldState()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		//IL_0025: 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)
		if ((int)FoldingPart.State == 1)
		{
			return IsSafeWhenMid;
		}
		return FoldingPart.State == FoldedState;
	}

	private void OnFold()
	{
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected I4, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		if (DebugMode)
		{
			Debug.Log((object)"StockControlFMG9: Safety engaged. Disabling target colliders.");
		}
		foreach (FVRInteractiveObject item in InteractiveObjectsToDisable)
		{
			if (!((Object)(object)item != (Object)null))
			{
				continue;
			}
			item.ForceBreakInteraction();
			if (item.m_colliders == null)
			{
				continue;
			}
			for (int i = 0; i < item.m_colliders.Length; i++)
			{
				if ((Object)(object)item.m_colliders[i] != (Object)null)
				{
					item.m_colliders[i].enabled = false;
				}
			}
		}
		if (Gun.FireSelector_Modes != null)
		{
			_originalModes = (FireSelectorModeType[])(object)new FireSelectorModeType[Gun.FireSelector_Modes.Length];
			for (int j = 0; j < Gun.FireSelector_Modes.Length; j++)
			{
				if (Gun.FireSelector_Modes[j] != null)
				{
					_originalModes[j] = (FireSelectorModeType)(int)Gun.FireSelector_Modes[j].ModeType;
					Gun.FireSelector_Modes[j].ModeType = (FireSelectorModeType)0;
				}
			}
		}
		int num = LayerMask.NameToLayer("NoCol");
		if (num == -1)
		{
			return;
		}
		foreach (Collider item2 in CollidersToDisable)
		{
			if ((Object)(object)item2 != (Object)null)
			{
				((Component)item2).gameObject.layer = num;
				item2.enabled = false;
			}
		}
		foreach (GameObject item3 in GameObjectsToNoCol)
		{
			if ((Object)(object)item3 != (Object)null)
			{
				SetLayerRecursive(item3, num);
			}
		}
	}

	private void OnUnfold()
	{
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		if (DebugMode)
		{
			Debug.Log((object)"StockControlFMG9: Safety disengaged. Restoring target colliders.");
		}
		foreach (FVRInteractiveObject item in InteractiveObjectsToDisable)
		{
			if (!((Object)(object)item != (Object)null) || item.m_colliders == null)
			{
				continue;
			}
			for (int i = 0; i < item.m_colliders.Length; i++)
			{
				if ((Object)(object)item.m_colliders[i] != (Object)null)
				{
					item.m_colliders[i].enabled = true;
				}
			}
		}
		if (Gun.FireSelector_Modes != null && _originalModes != null)
		{
			for (int j = 0; j < Gun.FireSelector_Modes.Length; j++)
			{
				if (Gun.FireSelector_Modes[j] != null && j < _originalModes.Length)
				{
					Gun.FireSelector_Modes[j].ModeType = _originalModes[j];
				}
			}
		}
		foreach (Collider item2 in CollidersToDisable)
		{
			if ((Object)(object)item2 != (Object)null && _originalColliderLayers.TryGetValue(item2, out var value))
			{
				((Component)item2).gameObject.layer = value;
				item2.enabled = true;
			}
		}
		foreach (GameObject item3 in GameObjectsToNoCol)
		{
			if ((Object)(object)item3 != (Object)null && _originalGOLayers.TryGetValue(item3, out var value2))
			{
				SetLayerRecursive(item3, value2);
			}
		}
	}

	private FieldInfo GetPrivateField(Type targetType, string fieldName)
	{
		Type type = targetType;
		while ((object)type != null)
		{
			FieldInfo field = type.GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if ((object)field != null)
			{
				return field;
			}
			type = type.BaseType;
		}
		return null;
	}

	private void SetCollidersActive(List<Collider> colliders, bool active)
	{
		for (int i = 0; i < colliders.Count; i++)
		{
			if ((Object)(object)colliders[i] != (Object)null && colliders[i].enabled != active)
			{
				colliders[i].enabled = active;
			}
		}
	}

	private void SetLayerRecursive(GameObject obj, int layer)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		obj.layer = layer;
		foreach (Transform item in obj.transform)
		{
			Transform val = item;
			SetLayerRecursive(((Component)val).gameObject, layer);
		}
	}

	private void OnDestroy()
	{
		_originalColliderLayers.Clear();
		_originalGOLayers.Clear();
		_foldingPartColliders.Clear();
	}
}
public class ITR2Rack : MonoBehaviour
{
	private class StoredItemTransform
	{
		public Vector3 localPosition;

		public Quaternion localRotation;
	}

	[Header("Rack Behavior")]
	[Tooltip("If true, objects already sitting inside the rack when the scene loads will automatically freeze in place.")]
	public bool freezeOnSceneStart = true;

	[Header("Slot Feedback")]
	[Tooltip("Optional placeholder geometry (e.g. a translucent silhouette or box outline) shown while a held item is inside the rack.")]
	public GameObject HoverGeo;

	[Tooltip("If true, the hand carrying an item gets a haptic buzz when the item enters the rack volume.")]
	public bool useHapticBuzzOnApproach = true;

	[Header("Audio Feedback")]
	[Tooltip("Optional audio to play when an item locks onto the rack.")]
	public AudioEvent lockSound;

	[Tooltip("Optional audio to play when an item is pulled off the rack.")]
	public AudioEvent grabSound;

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

	private List<FVRPhysicalObject> _trackedObjects = new List<FVRPhysicalObject>();

	private List<FVRPhysicalObject> _frozenObjects = new List<FVRPhysicalObject>();

	private Dictionary<FVRPhysicalObject, bool> _wasHeldState = new Dictionary<FVRPhysicalObject, bool>();

	private Dictionary<FVRPhysicalObject, StoredItemTransform> _storedItemOffsets = new Dictionary<FVRPhysicalObject, StoredItemTransform>();

	private List<Collider> _rackColliders = new List<Collider>();

	private bool _hasHeldItemInside = false;

	private void Awake()
	{
		CacheRackColliders();
	}

	private void Start()
	{
		if ((Object)(object)HoverGeo != (Object)null)
		{
			HoverGeo.SetActive(false);
		}
	}

	private void CacheRackColliders()
	{
		_rackColliders.Clear();
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if ((Object)(object)componentsInChildren[i] != (Object)null && !componentsInChildren[i].isTrigger)
			{
				_rackColliders.Add(componentsInChildren[i]);
			}
		}
	}

	private void Update()
	{
		bool flag = false;
		FVRViveHand val = null;
		for (int num = _trackedObjects.Count - 1; num >= 0; num--)
		{
			FVRPhysicalObject val2 = _trackedObjects[num];
			if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeInHierarchy)
			{
				_trackedObjects.RemoveAt(num);
				_frozenObjects.Remove(val2);
				_wasHeldState.Remove(val2);
				_storedItemOffsets.Remove(val2);
			}
			else
			{
				bool isHeld = ((FVRInteractiveObject)val2).IsHeld;
				bool value = false;
				_wasHeldState.TryGetValue(val2, out value);
				if (value && !isHeld)
				{
					FreezeObject(val2);
					_wasHeldState[val2] = false;
				}
				else if (!value && isHeld)
				{
					UnfreezeObject(val2);
					_wasHeldState[val2] = true;
				}
				if (isHeld)
				{
					flag = true;
					if ((Object)(object)val == (Object)null)
					{
						val = ((FVRInteractiveObject)val2).m_hand;
					}
				}
			}
		}
		if (flag && !_hasHeldItemInside)
		{
			if ((Object)(object)HoverGeo != (Object)null)
			{
				HoverGeo.SetActive(true);
			}
			if (useHapticBuzzOnApproach && (Object)(object)val != (Object)null)
			{
				val.Buzz(val.Buzzer.Buzz_OnHoverInventorySlot);
			}
			if (debug)
			{
				Debug.Log((object)"ITR2Rack: Held item entered the rack - showing indicator.");
			}
		}
		else if (!flag && _hasHeldItemInside)
		{
			if ((Object)(object)HoverGeo != (Object)null)
			{
				HoverGeo.SetActive(false);
			}
			if (debug)
			{
				Debug.Log((object)"ITR2Rack: No held item inside - hiding indicator.");
			}
		}
		_hasHeldItemInside = flag;
	}

	private void LateUpdate()
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < _frozenObjects.Count; i++)
		{
			FVRPhysicalObject val = _frozenObjects[i];
			if ((Object)(object)val != (Object)null && !((FVRInteractiveObject)val).IsHeld && _storedItemOffsets.ContainsKey(val))
			{
				StoredItemTransform storedItemTransform = _storedItemOffsets[val];
				((Component)val).transform.position = ((Component)this).transform.TransformPoint(storedItemTransform.localPosition);
				((Component)val).transform.rotation = ((Component)this).transform.rotation * storedItemTransform.l