Decompiled source of GalileanSight v1.0.0

GalileanSight.dll

Decompiled 19 hours 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. If empty, all non-trigger colliders on this object are used.")]
	public Collider[] BladeColliders;

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

	[Header("Velocity Thresholds")]
	[Tooltip("Minimum collision velocity required to trigger clash effects.")]
	public float MinClashVelocity = 1.5f;

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

	[Header("Cooldown")]
	[Tooltip("Cooldown in seconds between clash events to prevent multiple triggers in a single swing.")]
	public float CooldownTime = 0.08f;

	[Header("Spark Configuration")]
	[Tooltip("If true or if no custom prefab is assigned, uses vanilla FXM sparks.")]
	public bool UseVanillaSparks = true;

	[Tooltip("Base visual magnitude when using vanilla sparks.")]
	public ImpactEffectMagnitude LowSparkMagnitude = (ImpactEffectMagnitude)1;

	[Tooltip("High-velocity visual magnitude when using vanilla sparks.")]
	public ImpactEffectMagnitude HighSparkMagnitude = (ImpactEffectMagnitude)2;

	[Tooltip("Tint color applied to vanilla sparks.")]
	public Color VanillaSparkColor = Color.white;

	[Tooltip("Custom particle system prefab to spawn on clash. Overrides vanilla sparks if assigned.")]
	public GameObject CustomSparkPrefab;

	[Tooltip("Lifetime in seconds before destroying the instantiated custom spark object.")]
	public float CustomSparkLifetime = 1f;

	[Header("Audio Configuration")]
	[Tooltip("If true or if no custom clips are provided, uses Anton's native SM impact sounds.")]
	public bool UseVanillaAudio = true;

	[Tooltip("Vanilla impact sound type to play when using native audio.")]
	public ImpactType WeaponImpactType = (ImpactType)130;

	[Tooltip("Vanilla audio pool used for impact playback.")]
	public FVRPooledAudioType AudioPool = (FVRPooledAudioType)41;

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

	[Tooltip("Custom audio clips to play on clash. Overrides vanilla audio if assigned.")]
	public AudioClip[] CustomClashClips;

	[Range(0f, 1f)]
	[Tooltip("Base volume multiplier for custom audio playback.")]
	public float CustomAudioVolume = 0.8f;

	[Range(0.5f, 1.5f)]
	[Tooltip("Minimum random pitch multiplier for custom audio.")]
	public float CustomAudioMinPitch = 0.95f;

	[Range(0.5f, 1.5f)]
	[Tooltip("Maximum random pitch multiplier for custom audio.")]
	public float CustomAudioMaxPitch = 1.05f;

	private float m_cooldownTimer;

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

	private AudioSource m_audioSource;

	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]);
				}
			}
		}
		else
		{
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if (!componentsInChildren[j].isTrigger)
				{
					m_bladeColliderSet.Add(componentsInChildren[j]);
				}
			}
		}
		m_audioSource = ((Component)this).GetComponent<AudioSource>();
		if ((Object)(object)m_audioSource == (Object)null)
		{
			m_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			m_audioSource.spatialBlend = 1f;
			m_audioSource.minDistance = 0.5f;
			m_audioSource.maxDistance = MaxAudioDistance;
			m_audioSource.playOnAwake = false;
		}
	}

	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_00ad: 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_00c2: 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))
		{
			ContactPoint val = col.contacts[0];
			if (m_bladeColliderSet.Contains(((ContactPoint)(ref val)).thisCollider) && IsTargetValidMetal(((ContactPoint)(ref val)).otherCollider, col))
			{
				m_cooldownTimer = CooldownTime;
				TriggerSparks(((ContactPoint)(ref val)).point, ((ContactPoint)(ref val)).normal, magnitude);
				TriggerAudio(((ContactPoint)(ref val)).point, magnitude);
			}
		}
	}

	private void TriggerSparks(Vector3 point, Vector3 normal, float speed)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (!UseVanillaSparks && (Object)(object)CustomSparkPrefab != (Object)null)
		{
			Quaternion val = Quaternion.LookRotation(normal);
			GameObject val2 = Object.Instantiate<GameObject>(CustomSparkPrefab, point, val);
			Object.Destroy((Object)(object)val2, CustomSparkLifetime);
			return;
		}
		ImpactEffectMagnitude val3 = LowSparkMagnitude;
		if (speed >= HighClashVelocity)
		{
			val3 = HighSparkMagnitude;
		}
		bool flag = VanillaSparkColor != Color.white;
		FXM.SpawnImpactEffect(point, normal, 1, val3, false, flag, VanillaSparkColor, (Material)null);
	}

	private void TriggerAudio(Vector3 point, float speed)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		if (!UseVanillaAudio && CustomClashClips != null && CustomClashClips.Length > 0)
		{
			int num = Random.Range(0, CustomClashClips.Length);
			AudioClip val = CustomClashClips[num];
			if ((Object)(object)val != (Object)null)
			{
				float num2 = Mathf.InverseLerp(MinClashVelocity, HighClashVelocity, speed);
				float num3 = Mathf.Lerp(0.4f, 1f, num2) * CustomAudioVolume;
				m_audioSource.pitch = Random.Range(CustomAudioMinPitch, CustomAudioMaxPitch);
				m_audioSource.PlayOneShot(val, num3);
				return;
			}
		}
		AudioImpactIntensity val2 = (AudioImpactIntensity)1;
		if (speed >= HighClashVelocity)
		{
			val2 = (AudioImpactIntensity)2;
		}
		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;
	}
}
public 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)chamber != (Object)null)
		{
			Collider[] componentsInChildren = ((Component)chamber).GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if ((Object)(object)val != (Object)(object)((Component)this).GetComponent<Collider>())
				{
					val.enabled = false;
				}
			}
		}
		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_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		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;
		}
		Vector3 val = ChamberSeatedPoint.InverseTransformPoint(((Component)componentInParent).transform.position);
		if (val.z >= extractThreshold)
		{
			return;
		}
		FVRViveHand hand = ((FVRInteractiveObject)componentInParent).m_hand;
		if ((Object)(object)hand != (Object)null)
		{
			PlaySound(AudEvent_ShellInStart);
			m_loadingRound = componentInParent;
			Vector3 val2 = ChamberSeatedPoint.InverseTransformPoint(((Component)hand).transform.position);
			m_roundHandOffsetZ = val.z - val2.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;
			m_isForwardPlayed = true;
			m_isRearPlayed = false;
		}
	}

	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 ManualTubeLoad : FVRInteractiveObject
{
	public enum Axis
	{
		X,
		Y,
		Z
	}

	[Tooltip("Enable diagnostic logs in the Unity console.")]
	public bool debug = false;

	[Tooltip("Point 1 (BLUE in Scene): The rear gate entrance where shell sliding begins.")]
	public Transform CarrierComparePoint1;

	[Tooltip("Point 2 (GREEN in Scene): The forward point where the shell counts in and seats.")]
	public Transform CarrierComparePoint2;

	[Tooltip("The visual carrier/elevator transform on the shotgun.")]
	public Transform Carrier;

	[Tooltip("The rotational axis of the carrier.")]
	public Axis CarrierAxis = Axis.X;

	[Tooltip("The down/closed (x) and up/open (y) angles for the carrier.")]
	public Vector2 CarrierRots = new Vector2(0f, 30f);

	[Tooltip("Distance from Point 1 or the carrier where the lifter opens.")]
	public float CarrierDetectDistance = 0.12f;

	[Tooltip("Speed in degrees per second at which the carrier rotates.")]
	public float CarrierSpeed = 450f;

	[Tooltip("Optional visual loading gate flap (for lever actions).")]
	public Transform LoadingGateObject;

	[Tooltip("The rotational axis of the loading gate flap.")]
	public Axis LoadingGateAxis = Axis.Y;

	[Tooltip("The closed (x) and open (y) angles for the loading gate flap.")]
	public Vector2 LoadingGateRotRange = new Vector2(0f, -30f);

	public AudioEvent AudEvent_ShellInStart;

	public AudioEvent AudEvent_ShellIn;

	private FVRFireArm m_parentGun;

	private TubeFedShotgun m_parentShotgun;

	private FVRFireArmMagazine m_magazine;

	private FVRFireArmRound m_loadingRound;

	private FVRViveHand m_loadingHand;

	private float m_curCarrierRot;

	private float m_tarCarrierRot;

	private float m_carrierProgress;

	private float m_slideProgress;

	private float m_lastTickProgress;

	private float m_startHandOffset;

	private float m_loadCooldownTimer;

	private float m_cycleHoldTimer;

	public override void Awake()
	{
		((FVRInteractiveObject)this).Awake();
		if (debug)
		{
			Debug.Log((object)("ManualTubeLoad DIAGNOSTIC: Awake initialized on GameObject: " + ((Object)((Component)this).gameObject).name));
		}
		m_parentGun = ((Component)this).GetComponentInParent<FVRFireArm>();
		if ((Object)(object)m_parentGun != (Object)null)
		{
			ref TubeFedShotgun parentShotgun = ref m_parentShotgun;
			FVRFireArm parentGun = m_parentGun;
			parentShotgun = (TubeFedShotgun)(object)((parentGun is TubeFedShotgun) ? parentGun : null);
			m_magazine = m_parentGun.Magazine;
			if ((Object)(object)m_parentShotgun != (Object)null)
			{
				m_parentShotgun.UsesAnimatedCarrier = false;
				if (debug)
				{
					Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Connected to parent TubeFedShotgun. Native animated carrier disabled.");
				}
				if ((Object)(object)m_parentShotgun.ReloadTriggerWell != (Object)null)
				{
					Collider[] componentsInChildren = m_parentShotgun.ReloadTriggerWell.GetComponentsInChildren<Collider>(true);
					Collider[] array = componentsInChildren;
					foreach (Collider val in array)
					{
						val.enabled = false;
						if (debug)
						{
							Debug.Log((object)("ManualTubeLoad DIAGNOSTIC: Disabled collider on shotgun ReloadTriggerWell: " + ((Object)((Component)val).gameObject).name));
						}
					}
				}
			}
		}
		else if (debug)
		{
			Debug.LogError((object)"ManualTubeLoad DIAGNOSTIC ERROR: Could not find parent FVRFireArm component in the hierarchy above this GameObject!");
		}
		FVRFireArmMagazineReloadTrigger componentInChildren = ((Component)this).GetComponentInChildren<FVRFireArmMagazineReloadTrigger>();
		if ((Object)(object)componentInChildren != (Object)null)
		{
			if ((Object)(object)m_magazine == (Object)null)
			{
				m_magazine = componentInChildren.Magazine;
			}
			if (debug)
			{
				Debug.Log((object)("ManualTubeLoad DIAGNOSTIC: Found FVRFireArmMagazineReloadTrigger. Magazine reference is: " + ((!((Object)(object)m_magazine != (Object)null)) ? "NULL!" : ((Object)m_magazine).name)));
			}
			GameObject gameObject = ((Component)componentInChildren).gameObject;
			if ((Object)(object)gameObject != (Object)(object)((Component)this).gameObject)
			{
				Object.Destroy((Object)(object)gameObject);
				if (debug)
				{
					Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Destroyed child native trigger GameObject to permanently silence auto-load.");
				}
			}
			else
			{
				Object.Destroy((Object)(object)componentInChildren);
				if (debug)
				{
					Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Destroyed native trigger component to permanently silence auto-load.");
				}
			}
		}
		if (((Object)(object)CarrierComparePoint1 == (Object)null || (Object)(object)CarrierComparePoint2 == (Object)null) && debug)
		{
			Debug.LogError((object)"ManualTubeLoad DIAGNOSTIC ERROR: CarrierComparePoint1 or CarrierComparePoint2 is not assigned in the Unity Inspector!");
		}
	}

	private void Update()
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: 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_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_044e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0453: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0500: Unknown result type (might be due to invalid IL or missing references)
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_051f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0520: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_072b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0730: Unknown result type (might be due to invalid IL or missing references)
		//IL_07dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0780: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0825: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_magazine == (Object)null || (Object)(object)CarrierComparePoint1 == (Object)null || (Object)(object)CarrierComparePoint2 == (Object)null)
		{
			return;
		}
		if (m_loadCooldownTimer > 0f)
		{
			m_loadCooldownTimer -= Time.deltaTime;
		}
		if (m_cycleHoldTimer > 0f)
		{
			m_cycleHoldTimer -= Time.deltaTime;
		}
		Vector3 val = CarrierComparePoint2.position - CarrierComparePoint1.position;
		float magnitude = ((Vector3)(ref val)).magnitude;
		Vector3 val2 = ((!(magnitude > 0.001f)) ? Vector3.forward : (val / magnitude));
		bool flag = false;
		FVRFireArmRound val3 = null;
		FVRViveHand loadingHand = null;
		if ((Object)(object)GM.CurrentMovementManager != (Object)null)
		{
			for (int i = 0; i < GM.CurrentMovementManager.Hands.Length; i++)
			{
				FVRViveHand val4 = GM.CurrentMovementManager.Hands[i];
				if ((Object)(object)val4 == (Object)null || ((Object)(object)m_parentGun != (Object)null && ((FVRInteractiveObject)m_parentGun).IsHeld && (Object)(object)val4 == (Object)(object)((FVRInteractiveObject)m_parentGun).m_hand))
				{
					continue;
				}
				Vector3 pos = ((HandInput)(ref val4.Input)).Pos;
				if ((Object)(object)Carrier != (Object)null && Vector3.Distance(pos, Carrier.position) < CarrierDetectDistance)
				{
					flag = true;
				}
				else if (Vector3.Distance(pos, CarrierComparePoint1.position) < CarrierDetectDistance)
				{
					flag = true;
				}
				if (!(val4.CurrentInteractable is FVRFireArmRound))
				{
					continue;
				}
				FVRInteractiveObject currentInteractable = val4.CurrentInteractable;
				FVRFireArmRound val5 = (FVRFireArmRound)(object)((currentInteractable is FVRFireArmRound) ? currentInteractable : null);
				if (val5.RoundType == m_magazine.RoundType)
				{
					float num = ((!((Object)(object)Carrier != (Object)null)) ? 999f : Vector3.Distance(((Component)val5).transform.position, Carrier.position));
					float num2 = Vector3.Distance(((Component)val5).transform.position, CarrierComparePoint1.position);
					if (num < CarrierDetectDistance || num2 < CarrierDetectDistance)
					{
						flag = true;
					}
					if (num2 < CarrierDetectDistance)
					{
						val3 = val5;
						loadingHand = val4;
					}
				}
			}
		}
		if ((Object)(object)m_loadingRound == (Object)null && m_loadCooldownTimer <= 0f && (Object)(object)val3 != (Object)null && !m_magazine.IsFull())
		{
			m_loadingRound = val3;
			m_loadingHand = loadingHand;
			((FVRInteractiveObject)m_loadingRound).SetAllCollidersToLayer(false, "NoCol");
			float startHandOffset = Vector3.Dot(((HandInput)(ref m_loadingHand.Input)).Pos - CarrierComparePoint1.position, val2);
			m_startHandOffset = startHandOffset;
			m_slideProgress = 0f;
			m_lastTickProgress = 0f;
			PlaySound(AudEvent_ShellInStart);
			if (debug)
			{
				Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Shell engaged on sliding rail. Slide initiated!");
			}
		}
		if ((Object)(object)m_loadingRound != (Object)null)
		{
			if ((Object)(object)m_loadingHand == (Object)null || !((FVRInteractiveObject)m_loadingRound).IsHeld || (Object)(object)m_loadingHand.CurrentInteractable != (Object)(object)m_loadingRound)
			{
				((FVRInteractiveObject)m_loadingRound).SetAllCollidersToLayer(false, "Default");
				if ((Object)(object)((FVRPhysicalObject)m_loadingRound).RootRigidbody != (Object)null)
				{
					((FVRPhysicalObject)m_loadingRound).RootRigidbody.velocity = -val2 * 1.2f + GM.CurrentMovementManager.GetFilteredVel();
				}
				m_loadingRound = null;
				m_loadingHand = null;
				m_slideProgress = 0f;
				m_carrierProgress = 0f;
				if (debug)
				{
					Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Shell released mid-slide. Ejected via backward impulse.");
				}
			}
			else
			{
				float num3 = Vector3.Dot(((HandInput)(ref m_loadingHand.Input)).Pos - CarrierComparePoint1.position, val2);
				float num4 = num3 - m_startHandOffset;
				if (num4 < -0.04f)
				{
					((FVRInteractiveObject)m_loadingRound).SetAllCollidersToLayer(false, "Default");
					m_loadingRound = null;
					m_loadingHand = null;
					m_slideProgress = 0f;
					m_carrierProgress = 0f;
					if (debug)
					{
						Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Hand pulled backward past entrance. Shell disengaged back to hand.");
					}
				}
				else
				{
					m_slideProgress = Mathf.Clamp01(num4 / Mathf.Max(0.01f, magnitude));
					Vector3 position = CarrierComparePoint1.position + val2 * (m_slideProgress * magnitude);
					((Component)m_loadingRound).transform.position = position;
					((Component)m_loadingRound).transform.rotation = Quaternion.LookRotation(val2);
					m_carrierProgress = Mathf.Clamp01(m_slideProgress * 1.5f);
					if (Mathf.Abs(m_slideProgress - m_lastTickProgress) > 0.15f)
					{
						m_lastTickProgress = m_slideProgress;
						if ((Object)(object)m_loadingHand.Buzzer != (Object)null)
						{
							m_loadingHand.Buzz(m_loadingHand.Buzzer.Buzz_OnHoverInteractive);
						}
					}
					if (m_slideProgress >= 0.9f)
					{
						PlaySound(AudEvent_ShellIn);
						m_magazine.AddRound(m_loadingRound, true, true, false);
						if (m_loadingRound.ProxyRounds != null && m_loadingRound.ProxyRounds.Count > 0)
						{
							m_loadingRound.CycleToProxy(true, false);
						}
						Object.Destroy((Object)(object)((Component)m_loadingRound).gameObject);
						m_loadingRound = null;
						m_loadingHand = null;
						m_loadCooldownTimer = 0.15f;
						m_slideProgress = 0f;
						m_carrierProgress = 0f;
						if (debug)
						{
							Debug.Log((object)"ManualTubeLoad DIAGNOSTIC: Shell successfully seated into magazine.");
						}
					}
				}
			}
		}
		if ((Object)(object)m_parentShotgun != (Object)null && m_parentShotgun.HasExtractedRound() && !m_parentShotgun.m_isExtractedRoundOnLowerPath)
		{
			m_cycleHoldTimer = 0.15f;
		}
		if ((Object)(object)m_loadingRound != (Object)null || flag || m_cycleHoldTimer > 0f)
		{
			m_tarCarrierRot = CarrierRots.y;
		}
		else
		{
			m_tarCarrierRot = CarrierRots.x;
		}
		m_curCarrierRot = Mathf.MoveTowards(m_curCarrierRot, m_tarCarrierRot, CarrierSpeed * Time.deltaTime);
		if ((Object)(object)Carrier != (Object)null)
		{
			Vector3 zero = Vector3.zero;
			if (CarrierAxis == Axis.X)
			{
				zero.x = m_curCarrierRot;
			}
			else if (CarrierAxis == Axis.Y)
			{
				zero.y = m_curCarrierRot;
			}
			else
			{
				zero.z = m_curCarrierRot;
			}
			Carrier.localEulerAngles = zero;
		}
		if ((Object)(object)LoadingGateObject != (Object)null)
		{
			float num5 = Mathf.InverseLerp(CarrierRots.x, CarrierRots.y, m_curCarrierRot);
			float num6 = Mathf.Lerp(LoadingGateRotRange.x, LoadingGateRotRange.y, num5);
			Vector3 zero2 = Vector3.zero;
			if (LoadingGateAxis == Axis.X)
			{
				zero2.x = num6;
			}
			else if (LoadingGateAxis == Axis.Y)
			{
				zero2.y = num6;
			}
			else
			{
				zero2.z = num6;
			}
			LoadingGateObject.localEulerAngles = zero2;
		}
		if (debug && Time.frameCount % 90 == 0)
		{
			Debug.Log((object)("ManualTubeLoad DIAGNOSTIC STATUS: CarrierAngle: " + m_curCarrierRot + " | TargetAngle: " + m_tarCarrierRot + " | IsLiftTriggered: " + flag + " | IsLoading: " + ((Object)(object)m_loadingRound != (Object)null)));
		}
	}

	private void LateUpdate()
	{
		if ((Object)(object)m_magazine != (Object)null)
		{
			m_magazine.IsDropInLoadable = false;
		}
	}

	public override bool IsInteractable()
	{
		return false;
	}

	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)m_magazine != (Object)null && (Object)(object)m_magazine.FireArm != (Object)null)
			{
				m_magazine.FireArm.PlayAudioAsHandling(aud, ((Component)this).transform.position);
			}
			else
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, aud, ((Component)this).transform.position);
			}
		}
	}

	private void OnDrawGizmosSelected()
	{
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)CarrierComparePoint1 != (Object)null && (Object)(object)CarrierComparePoint2 != (Object)null)
		{
			Gizmos.color = Color.yellow;
			Gizmos.DrawLine(CarrierComparePoint1.position, CarrierComparePoint2.position);
			Gizmos.color = Color.blue;
			Gizmos.DrawSphere(CarrierComparePoint1.position, 0.008f);
			Gizmos.color = Color.green;
			Gizmos.DrawSphere(CarrierComparePoint2.position, 0.008f);
			Gizmos.color = Color.cyan;
			Gizmos.DrawWireSphere(CarrierComparePoint1.position, CarrierDetectDistance);
		}
		if ((Object)(object)Carrier != (Object)null)
		{
			Gizmos.color = Color.magenta;
			Gizmos.DrawWireSphere(Carrier.position, CarrierDetectDistance);
		}
	}
}
public class AdvanceInternalMagazineLoading : MonoBehaviour
{
	[Header("Debug")]
	[Tooltip("Enables on-screen console logging for push-to-seat loading, sticky bolt velocity, and ejection 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("Dynamic Push-To-Seat Ingestion")]
	[Tooltip("Baseline downward distance in meters the controller must press into the receiver well to seat the first round into an empty magazine.")]
	public float RequiredInsertionDepth = 0.007f;

	[Tooltip("Multiplier applied to the required insertion depth when the magazine is nearly full, simulating increasing spring stiffness.")]
	public float FullMagDepthMultiplier = 1.6f;

	[Tooltip("Minimum time delay between successive round seatings.")]
	public float SeatingCooldown = 0.15f;

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

	[Tooltip("Audio played when the player tries to push a round into an already full internal magazine.")]
	public AudioEvent FullMagAttemptAudio;

	[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 float m_origRightForce;

	private float m_origUpForce;

	private float m_origSpinTorque;

	private float m_prevBoltLerp;

	private float m_strokeSpeed;

	private bool m_isStickyBroken;

	private bool m_requiresStrokeReset;

	private float m_timeSinceLastSeat;

	private float m_timeSinceFullWarning;

	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_prevBoltLerp = 0f;
		m_strokeSpeed = 0f;
		m_isStickyBroken = false;
		m_requiresStrokeReset = false;
		m_timeSinceLastSeat = 0f;
		m_timeSinceFullWarning = 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))
		{
			if (m_timeSinceLastSeat < SeatingCooldown)
			{
				m_timeSinceLastSeat += Time.deltaTime;
			}
			if (m_timeSinceFullWarning < 0.5f)
			{
				m_timeSinceFullWarning += Time.deltaTime;
			}
			float num = m_rifle.BoltLerp - m_prevBoltLerp;
			float strokeSpeed = Mathf.Abs(num) / Mathf.Max(Time.deltaTime, 0.0001f);
			if (num > 0.001f)
			{
				m_strokeSpeed = strokeSpeed;
			}
			if (EnableVelocitySensitiveEjection)
			{
				ProcessVelocityEjection();
			}
			if (EnableStickyBolt)
			{
				ProcessStickyBolt();
			}
			m_prevBoltLerp = m_rifle.BoltLerp;
		}
	}

	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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: 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_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_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_rifle == (Object)null || (Object)(object)InternalMagazine == (Object)null || m_timeSinceLastSeat < SeatingCooldown || (int)m_rifle.CurBoltHandleState == 0)
		{
			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))
		{
			return;
		}
		Transform val2 = ((!((Object)(object)ReloadTrigger != (Object)null)) ? ((Component)m_rifle).transform : ((Component)ReloadTrigger).transform);
		Vector3 val3 = ((HandInput)(ref ((FVRInteractiveObject)val).m_hand.Input)).Pos - val2.position;
		float num = Vector3.Dot(val3, -((Component)m_rifle).transform.up);
		if (InternalMagazine.IsFull())
		{
			if (num > 0.004f && m_timeSinceFullWarning >= 0.4f)
			{
				m_timeSinceFullWarning = 0f;
				((FVRInteractiveObject)val).m_hand.Buzz(((FVRInteractiveObject)val).m_hand.Buzzer.Buzz_OnHoverInventorySlot);
				if (FullMagAttemptAudio != null)
				{
					SM.PlayGenericSound(FullMagAttemptAudio, ((Component)this).transform.position);
				}
				else if ((Object)(object)InternalMagazine.Profile != (Object)null)
				{
					SM.PlayGenericSound(InternalMagazine.Profile.MagazineInsertRound, ((Component)this).transform.position);
				}
				if (Debug)
				{
					Debug.Log((object)"[AdvanceInternalMag] Magazine is full! Rejection feedback played.");
				}
			}
		}
		else if (m_requiresStrokeReset)
		{
			if (num < 0.003f)
			{
				m_requiresStrokeReset = false;
				if (Debug)
				{
					Debug.Log((object)"[AdvanceInternalMag] Stroke reset. Ready for next palmed round.");
				}
			}
		}
		else
		{
			if (num > 0.002f)
			{
				((FVRInteractiveObject)val).m_hand.Buzz(((FVRInteractiveObject)val).m_hand.Buzzer.Buzz_OnHoverInteractive);
			}
			float num2 = (float)InternalMagazine.m_numRounds / (float)Mathf.Max(InternalMagazine.m_capacity, 1);
			float num3 = Mathf.Lerp(RequiredInsertionDepth, RequiredInsertionDepth * FullMagDepthMultiplier, num2);
			if (num >= num3)
			{
				SeatRoundIntoMagazine(val);
			}
		}
	}

	private void OnTriggerExit(Collider other)
	{
		m_requiresStrokeReset = false;
	}

	private void SeatRoundIntoMagazine(FVRFireArmRound round)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		m_timeSinceLastSeat = 0f;
		m_requiresStrokeReset = true;
		FVRViveHand hand = ((FVRInteractiveObject)round).m_hand;
		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)hand != (Object)null)
		{
			hand.Buzz(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 FVRFireArmRound m_looseCartridgeRound;

	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()
	{
		CleanupLooseCartridge();
	}

	private void Update()
	{
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_031b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: 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 && !m_hasLooseCartridgeInBreech)
			{
				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 ((Object)(object)m_looseCartridgeRound != (Object)null && ((FVRInteractiveObject)m_looseCartridgeRound).IsHeld)
				{
					if (DebugMode)
					{
						Debug.Log((object)"[PushFeed] Loose cartridge grabbed by hand from breech.");
					}
					SetRifleRoundCollisionsIgnored(m_looseCartridgeRound, ignore: false);
					m_looseCartridgeRound = null;
					m_hasLooseCartridgeInBreech = false;
					m_isCommittedThisStroke = false;
					m_lowestBoltLerpThisStroke = 1f;
					Rifle.m_proxy.ClearProxy();
				}
				else if (flag && boltLerp <= m_looseCartridgeLerp)
				{
					ReattachRoundToBoltProxy(boltLerp);
				}
				else if (boltLerp > 0.45f && (Object)(object)m_looseCartridgeRound != (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 LateUpdate()
	{
		if ((Object)(object)Rifle != (Object)null && (Object)(object)Rifle.Chamber != (Object)null && m_hasLooseCartridgeInBreech)
		{
			Rifle.Chamber.IsAccessible = false;
		}
	}

	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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: 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)
		FVRFireArmRound round = Rifle.m_proxy.Round;
		if ((Object)(object)round == (Object)null)
		{
			return;
		}
		m_looseCartridgeType = round.RoundType;
		m_looseCartridgeClass = round.RoundClass;
		m_looseCartridgeLerp = detachmentLerp;
		m_hasLooseCartridgeInBreech = true;
		CleanupLooseCartridge();
		GameObject gameObject = ((AnvilAsset)AM.GetRoundSelfPrefab(m_looseCartridgeType, m_looseCartridgeClass)).GetGameObject();
		if ((Object)(object)gameObject != (Object)null)
		{
			Vector3 val = Vector3.Lerp(Rifle.Extraction_ChamberPos.position, Rifle.Extraction_MagazinePos.position, detachmentLerp);
			Quaternion val2 = Quaternion.Slerp(Rifle.Extraction_ChamberPos.rotation, Rifle.Extraction_MagazinePos.rotation, detachmentLerp);
			GameObject val3 = Object.Instantiate<GameObject>(gameObject, val, val2);
			m_looseCartridgeRound = val3.GetComponent<FVRFireArmRound>();
			if ((Object)(object)m_looseCartridgeRound != (Object)null)
			{
				SetRifleRoundCollisionsIgnored(m_looseCartridgeRound, ignore: true);
				((Component)m_looseCartridgeRound).transform.SetParent(((Component)Rifle).transform, true);
				if ((Object)(object)((FVRPhysicalObject)m_looseCartridgeRound).RootRigidbody != (Object)null)
				{
					((FVRPhysicalObject)m_looseCartridgeRound).RootRigidbody.isKinematic = true;
				}
			}
		}
		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 detached 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;
		}
		CleanupLooseCartridge();
		m_hasLooseCartridgeInBreech = false;
		m_isCommittedThisStroke = true;
		m_lowestBoltLerpThisStroke = currentBoltLerp;
		if (DebugMode)
		{
			D