Decompiled source of CARV2 Rifle v1.0.0

CARV2_Rifle.dll

Decompiled a day ago
using System;
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 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]
public class SimplifiedSentryGun : MonoBehaviour, IFVRDamageable
{
	[Serializable]
	public class SentryAnimatedComponent
	{
		[Tooltip("Target transform to animate.")]
		public Transform TargetTransform;

		[Tooltip("If true, interpolates local position between powered down and powered up values.")]
		public bool AnimatePosition;

		[Tooltip("Local position when powered down.")]
		public Vector3 PoweredDownPosition;

		[Tooltip("Local position when powered up.")]
		public Vector3 PoweredUpPosition;

		[Tooltip("If true, interpolates local rotation between powered down and powered up values.")]
		public bool AnimateRotation;

		[Tooltip("Local Euler rotation when powered down.")]
		public Vector3 PoweredDownEuler;

		[Tooltip("Local Euler rotation when powered up.")]
		public Vector3 PoweredUpEuler;
	}

	[Serializable]
	public class SentryFiringActionComponent
	{
		[Tooltip("Target transform that moves or vibrates when firing (bolt, trigger, carry handle, antenna).")]
		public Transform TargetTransform;

		[Tooltip("Local position offset applied at peak recoil/firing impulse.")]
		public Vector3 RecoilPositionOffset;

		[Tooltip("Local rotation (Euler) offset applied at peak recoil/firing impulse.")]
		public Vector3 RecoilEulerOffset;

		[Tooltip("If true, adds random jitter to the offset for loose/vibrating components like handles or antennas.")]
		public bool AddRandomJitter;

		[Tooltip("Speed at which the component snaps back to resting position.")]
		public float ReturnSpeed = 25f;

		[HideInInspector]
		public Vector3 InitialLocalPosition;

		[HideInInspector]
		public Quaternion InitialLocalRotation;

		[HideInInspector]
		public float CurrentImpulse;
	}

	private class SentryMuzzlePSystem
	{
		public ParticleSystem PSystem;

		public Transform OverridePoint;

		public int NumParticlesPerShot;
	}

	public enum SentryState
	{
		Dormant,
		Deploying,
		Scanning,
		Acquiring,
		Engaging,
		TargetLost,
		Dead
	}

	[Tooltip("Enables verbose console logging for debugging.")]
	public bool EnableDebugLogging = false;

	[Header("Faction and Team")]
	[Tooltip("IFF team code for this sentry. 0 is friendly to the player, 1+ is hostile.")]
	public int SentryIFF = 0;

	[Tooltip("Reference to the AIEntity component, typically placed on a dedicated child GameObject on the AIEntity layer.")]
	public AIEntity Entity;

	[Tooltip("H3VR native target priority system.")]
	public AITargetPrioritySystem Priority = new AITargetPrioritySystem();

	[Header("Health and Damage")]
	[Tooltip("Total hit points before destruction.")]
	public float Health = 300f;

	[Tooltip("Optional list of colliders that receive damage. If empty, all colliders on this object receive damage.")]
	public List<Collider> DamageableColliders = new List<Collider>();

	[Tooltip("Prefab spawned when the sentry is destroyed.")]
	public GameObject ExplosionPrefab;

	[Tooltip("Optional debris prefabs spawned upon destruction.")]
	public List<GameObject> DestructionDebris = new List<GameObject>();

	[Header("Lifetime and Ammunition")]
	[Tooltip("If true, the sentry will automatically expire after a set time.")]
	public bool UsesLifetime = true;

	[Tooltip("Operational duration in seconds before powering down or detonating.")]
	public float LifetimeDuration = 90f;

	[Tooltip("Total ammunition capacity.")]
	public int MaxAmmo = 500;

	[Tooltip("Current remaining ammunition.")]
	public int CurrentAmmo = 500;

	[Tooltip("If true, the sentry explodes when out of ammo. If false, it powers down.")]
	public bool ExplodesOnEmpty = false;

	[Header("Transforms and Mechanical Hierarchy")]
	[Tooltip("Root anchor orientation transform. Defaults to this transform if null.")]
	public Transform BaseTransform;

	[Tooltip("Horizontal swivel pivot transform. Rotates yaw left and right.")]
	public Transform YawTransform;

	[Tooltip("Vertical elevation pivot transform. Tilts pitch up and down.")]
	public Transform PitchTransform;

	[Tooltip("Array of muzzle exit points for single, alternating, or multi-barrel firing.")]
	public List<Transform> Muzzles = new List<Transform>();

	[Tooltip("Transform where spent bullet casings are ejected.")]
	public Transform EjectionPort;

	[Tooltip("Optional spinning barrel cluster for miniguns.")]
	public Transform BarrelRotor;

	[Tooltip("Local axis around which the barrel rotor spins.")]
	public Vector3 RotorSpinAxis = new Vector3(0f, 0f, 1f);

	[Tooltip("Maximum rotational speed of the barrel rotor in degrees per second.")]
	public float RotorMaxSpeed = 1440f;

	[Header("Procedural Deployment and Animated Components")]
	[Tooltip("Duration in seconds for the deployment power-up sequence.")]
	public float DeployDuration = 1.5f;

	[Tooltip("If true, procedurally tilts the pitch pivot from a resting droop to level during boot up.")]
	public bool UseProceduralPitchDeploy = true;

	[Tooltip("Resting pitch angle in degrees when dormant, unpowered, or destroyed.")]
	public float PowerDownPitchAngle = -45f;

	[Tooltip("List of individual components that procedurally animate between power-down and power-up states.")]
	public List<SentryAnimatedComponent> AnimatedComponents = new List<SentryAnimatedComponent>();

	[Header("Mechanical Action and Recoil Components")]
	[Tooltip("List of mechanical components (bolt, trigger, carry handle, antenna) that animate upon each shot.")]
	public List<SentryFiringActionComponent> FiringActionComponents = new List<SentryFiringActionComponent>();

	[Header("Aiming and Motor Limits")]
	[Tooltip("Horizontal rotation speed in degrees per second.")]
	public float YawSpeed = 90f;

	[Tooltip("Vertical rotation speed in degrees per second.")]
	public float PitchSpeed = 60f;

	[Tooltip("Smoothing speed applied to incoming target coordinates to prevent jitter from Sosig segment cycling.")]
	public float TargetSmoothingSpeed = 8f;

	[Tooltip("Maximum angular error in degrees between the muzzle forward vector and target before firing is allowed.")]
	public float FiringAngleLimit = 10f;

	[Tooltip("Maximum horizontal scanning sweep angle in degrees relative to the base forward heading.")]
	public float ScanAngle = 50f;

	[Tooltip("Pause duration in seconds at each end of the scanning sweep before reversing direction.")]
	public float ScanPauseDuration = 0.75f;

	[Tooltip("Maximum upward elevation angle in degrees.")]
	public float MaxPitchUp = 35f;

	[Tooltip("Maximum downward depression angle in degrees.")]
	public float MaxPitchDown = 30f;

	[Header("Targeting and Sensing")]
	[Tooltip("Delay in seconds between locking onto a target and firing the first shot.")]
	public float LockOnDelay = 0.35f;

	[Tooltip("Maximum duration in seconds the turret continues firing at a target after losing visual contact.")]
	public float MaxBlindFireTime = 1f;

	[Tooltip("Duration in seconds to linger at the last known target position before resuming scanning.")]
	public float LingerDuration = 1.5f;

	[Tooltip("If true, checks for friendly entities in the line of fire before shooting.")]
	public bool CheckFriendlyFire = true;

	[Tooltip("Layer mask containing detectable AI entities for friendly fire line checks.")]
	public LayerMask FriendlyFireMask;

	[Header("Ammunition Configuration")]
	[Tooltip("If true, resolves projectile and spent casing data from H3VR native round catalogs via AM.")]
	public bool UseAmmoCatalog = true;

	[Tooltip("Native caliber type selected from the game catalog.")]
	public FireArmRoundType RoundType = (FireArmRoundType)13;

	[Tooltip("Specific round class for the selected caliber.")]
	public FireArmRoundClass RoundClass = (FireArmRoundClass)1;

	[Tooltip("Custom ballistic projectile prefab used when UseAmmoCatalog is false.")]
	public GameObject CustomProjectilePrefab;

	[Tooltip("Custom spent casing prefab used when UseAmmoCatalog is false.")]
	public GameObject CustomCasingPrefab;

	[Tooltip("Muzzle velocity override used when firing custom projectiles.")]
	public float CustomMuzzleVelocity = 800f;

	[Header("Weapon Firing Parameters")]
	[Tooltip("Cyclic rate of fire in rounds per minute.")]
	public float FireRateRPM = 600f;

	[Tooltip("If true, fires continuously while tracking. If false, fires in controlled bursts.")]
	public bool IsFullAuto = true;

	[Tooltip("Minimum shots fired in a single burst.")]
	public int BurstCountMin = 3;

	[Tooltip("Maximum shots fired in a single burst.")]
	public int BurstCountMax = 5;

	[Tooltip("Cooldown pause duration in seconds between bursts.")]
	public float BurstCooldown = 0.5f;

	[Tooltip("Delay in seconds for motor spool-up before firing commences.")]
	public float SpoolUpTime = 0f;

	[Tooltip("Shot inaccuracy cone angle in degrees.")]
	public float AccuracySpread = 1.2f;

	[Tooltip("Impulse speed at which spent brass casings are ejected.")]
	public float EjectionSpeed = 3.5f;

	[Tooltip("Random velocity jitter applied to ejected casings.")]
	public float EjectionJitter = 0.5f;

	[Header("Native Muzzle Effects")]
	[Tooltip("Default size category for native H3VR muzzle effects.")]
	public MuzzleEffectSize DefaultMuzzleEffectSize = (MuzzleEffectSize)1;

	[Tooltip("Array of native H3VR muzzle effect configurations (flashes, smoke, sparks). No custom particle assets required.")]
	public MuzzleEffect[] MuzzleEffects;

	[Tooltip("Optional custom particle system override for non-standard weapons like plasma or lasers.")]
	public ParticleSystem CustomMuzzleFlash;

	[Tooltip("Optional targeting laser or spotlight GameObject.")]
	public GameObject TargetingLaser;

	[Tooltip("Array of native H3VR gas out effects that vent smoke from muzzles, ejection ports, and chambers.")]
	public GasOutEffect[] GasOutEffects;

	[Header("Audio Events")]
	[Tooltip("Sound played during the initial power-up boot sequence.")]
	public AudioEvent AudEvent_BootUp;

	[Tooltip("Warning tone played upon locking onto an enemy.")]
	public AudioEvent AudEvent_Acquired;

	[Tooltip("Sound played on each round discharged.")]
	public AudioEvent AudEvent_Fire;

	[Tooltip("Sound played when attempting to fire with zero ammunition.")]
	public AudioEvent AudEvent_DryFire;

	[Tooltip("Sound played when the turret shuts down or powers off.")]
	public AudioEvent AudEvent_Shutdown;

	[Tooltip("Sound played when the turret is destroyed.")]
	public AudioEvent AudEvent_Destroyed;

	private FVRPhysicalObject m_physObj;

	private GameObject m_cachedProjectilePrefab;

	private GameObject m_cachedRoundPrefab;

	private int m_cachedNumProjectiles;

	private float m_cachedSpread;

	private SentryState m_state;

	private float m_stateTimer;

	private float m_lifetimeTimer;

	private float m_scanPauseTimer;

	private float m_refireTimer;

	private float m_burstCooldownTimer;

	private int m_burstsRemaining;

	private float m_spoolTimer;

	private float m_currentRotorSpeed;

	private Vector3 m_lastKnownTargetPos;

	private Vector3 m_smoothedTargetPos;

	private float m_scanDirection;

	private float m_currentScanAngle;

	private float m_deployProgress;

	private bool m_isDead;

	private int m_muzzleIndex;

	private RaycastHit[] m_friendlyFireHits;

	private List<SentryMuzzlePSystem> m_muzzleSystems;

	private void Awake()
	{
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: 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_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
		m_physObj = ((Component)this).GetComponent<FVRPhysicalObject>();
		if ((Object)(object)Entity == (Object)null)
		{
			Entity = ((Component)this).GetComponentInChildren<AIEntity>();
		}
		if ((Object)(object)Entity != (Object)null)
		{
			Entity.IFFCode = SentryIFF;
			if ((Object)(object)Entity.SensoryFrame == (Object)null)
			{
				Entity.SensoryFrame = ((!((Object)(object)PitchTransform != (Object)null)) ? ((Component)this).transform : PitchTransform);
			}
		}
		if (Priority == null)
		{
			Priority = new AITargetPrioritySystem();
		}
		if (((LayerMask)(ref FriendlyFireMask)).value == 0)
		{
			FriendlyFireMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[2] { "AgentBody", "AIEntity" }));
			if (((LayerMask)(ref FriendlyFireMask)).value == 0)
			{
				FriendlyFireMask = LayerMask.op_Implicit(-1);
			}
		}
		m_friendlyFireHits = (RaycastHit[])(object)new RaycastHit[8];
		m_scanDirection = 1f;
		m_currentScanAngle = 0f;
		m_scanPauseTimer = 0f;
		m_deployProgress = 0f;
		m_cachedNumProjectiles = 1;
		m_cachedSpread = 0f;
		if ((Object)(object)BaseTransform == (Object)null)
		{
			BaseTransform = ((Component)this).transform;
		}
		if ((Object)(object)YawTransform == (Object)null)
		{
			YawTransform = BaseTransform;
		}
		if ((Object)(object)PitchTransform == (Object)null)
		{
			PitchTransform = YawTransform;
		}
		if (UseAmmoCatalog)
		{
			if ((Object)(object)ManagerSingleton<AM>.Instance != (Object)null)
			{
				FVRObject roundSelfPrefab = AM.GetRoundSelfPrefab(RoundType, RoundClass);
				if ((Object)(object)roundSelfPrefab != (Object)null)
				{
					GameObject gameObject = ((AnvilAsset)roundSelfPrefab).GetGameObject();
					if ((Object)(object)gameObject != (Object)null)
					{
						m_cachedRoundPrefab = gameObject;
						FVRFireArmRound component = gameObject.GetComponent<FVRFireArmRound>();
						if ((Object)(object)component != (Object)null)
						{
							m_cachedProjectilePrefab = component.BallisticProjectilePrefab;
							m_cachedNumProjectiles = Mathf.Max(1, component.NumProjectiles);
							m_cachedSpread = component.ProjectileSpread;
						}
					}
				}
			}
			else
			{
				m_cachedProjectilePrefab = CustomProjectilePrefab;
				m_cachedRoundPrefab = CustomCasingPrefab;
			}
		}
		else
		{
			m_cachedProjectilePrefab = CustomProjectilePrefab;
			m_cachedRoundPrefab = CustomCasingPrefab;
		}
		UpdateAnimatedComponents(0f);
		if (UseProceduralPitchDeploy && (Object)(object)PitchTransform != (Object)null)
		{
			PitchTransform.localRotation = Quaternion.Euler(PowerDownPitchAngle, 0f, 0f);
		}
		for (int i = 0; i < FiringActionComponents.Count; i++)
		{
			SentryFiringActionComponent sentryFiringActionComponent = FiringActionComponents[i];
			if (sentryFiringActionComponent != null && (Object)(object)sentryFiringActionComponent.TargetTransform != (Object)null)
			{
				sentryFiringActionComponent.InitialLocalPosition = sentryFiringActionComponent.TargetTransform.localPosition;
				sentryFiringActionComponent.InitialLocalRotation = sentryFiringActionComponent.TargetTransform.localRotation;
				sentryFiringActionComponent.CurrentImpulse = 0f;
			}
		}
		InitMuzzleEffects();
		if (GasOutEffects != null)
		{
			for (int j = 0; j < GasOutEffects.Length; j++)
			{
				GasOutEffect val = GasOutEffects[j];
				if (val != null && (Object)(object)val.EffectPrefab != (Object)null && (Object)(object)val.Parent != (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(val.EffectPrefab, val.Parent.position, val.Parent.rotation);
					val2.transform.SetParent(val.Parent);
					val.PSystem = val2.GetComponent<ParticleSystem>();
				}
			}
		}
		m_lifetimeTimer = LifetimeDuration;
		m_state = SentryState.Deploying;
		m_stateTimer = 0f;
		if (EnableDebugLogging)
		{
			Debug.Log((object)("[SimplifiedSentryGun] Initialized on object: " + ((Object)((Component)this).gameObject).name));
		}
	}

	private void Start()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Entity != (Object)null)
		{
			Entity.AIEventReceiveEvent += new AIEventReceive(EventReceive);
			if (Priority != null)
			{
				Priority.Init(Entity, 5, 5f, 3f);
				Priority.SetDefaultIFFChart(SentryIFF);
			}
		}
		if (AudEvent_BootUp != null)
		{
			SM.PlayGenericSound(AudEvent_BootUp, ((Component)this).transform.position);
		}
		if ((Object)(object)TargetingLaser != (Object)null)
		{
			TargetingLaser.SetActive(false);
		}
	}

	private void OnDestroy()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		if ((Object)(object)Entity != (Object)null)
		{
			Entity.AIEventReceiveEvent -= new AIEventReceive(EventReceive);
		}
	}

	public void EventReceive(AIEvent e)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Invalid comparison between Unknown and I4
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		if (m_state == SentryState.Dead || m_state == SentryState.Dormant || (e.IsEntity && Priority != null && Priority.IsFriend(e.Entity.IFFCode)) || (int)e.Type != 1 || Priority == null)
		{
			return;
		}
		Priority.ProcessEvent(e);
		if (m_state != SentryState.Scanning)
		{
			return;
		}
		Priority.Compute();
		if (Priority.HasFreshTarget() && Priority.GetTimeSinceTopTargetSeen() <= MaxBlindFireTime)
		{
			m_smoothedTargetPos = Priority.GetTargetPoint();
			m_lastKnownTargetPos = m_smoothedTargetPos;
			m_state = SentryState.Acquiring;
			m_stateTimer = 0f;
			if (AudEvent_Acquired != null)
			{
				SM.PlayGenericSound(AudEvent_Acquired, ((Component)this).transform.position);
			}
			if (EnableDebugLogging)
			{
				Debug.Log((object)"[SimplifiedSentryGun] Visual contact acquired. Entering Acquiring state.");
			}
		}
	}

	private void Update()
	{
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		if (m_isDead)
		{
			return;
		}
		if ((Object)(object)m_physObj != (Object)null && ((FVRInteractiveObject)m_physObj).IsHeld)
		{
			m_state = SentryState.Dormant;
			m_physObj.SetIsKinematicLocked(false);
			m_deployProgress = Mathf.MoveTowards(m_deployProgress, 0f, 1f / Mathf.Max(0.01f, DeployDuration) * Time.deltaTime);
			UpdateAnimatedComponents(m_deployProgress);
			if ((Object)(object)TargetingLaser != (Object)null)
			{
				TargetingLaser.SetActive(false);
			}
			if ((Object)(object)PitchTransform != (Object)null && UseProceduralPitchDeploy)
			{
				PitchTransform.localRotation = Quaternion.RotateTowards(PitchTransform.localRotation, Quaternion.Euler(PowerDownPitchAngle, 0f, 0f), PitchSpeed * Time.deltaTime);
			}
			return;
		}
		if (UsesLifetime)
		{
			m_lifetimeTimer -= Time.deltaTime;
			if (m_lifetimeTimer <= 0f)
			{
				Decommission();
				return;
			}
		}
		UpdateStateMachine();
		UpdateRotorAnimation();
		UpdateFiringActionComponents();
		UpdateGasOutEffects();
	}

	private void UpdateStateMachine()
	{
		switch (m_state)
		{
		case SentryState.Dormant:
			m_state = SentryState.Deploying;
			m_stateTimer = 0f;
			break;
		case SentryState.Deploying:
			UpdateDeploying();
			break;
		case SentryState.Scanning:
			UpdateScanning();
			break;
		case SentryState.Acquiring:
			UpdateAcquiring();
			break;
		case SentryState.Engaging:
			UpdateEngaging();
			break;
		case SentryState.TargetLost:
			UpdateTargetLost();
			break;
		case SentryState.Dead:
			break;
		}
	}

	private void UpdateDeploying()
	{
		//IL_006d: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		m_stateTimer += Time.deltaTime;
		m_deployProgress = Mathf.Clamp01(m_stateTimer / Mathf.Max(0.01f, DeployDuration));
		UpdateAnimatedComponents(m_deployProgress);
		if (UseProceduralPitchDeploy && (Object)(object)PitchTransform != (Object)null)
		{
			Quaternion val = Quaternion.Euler(0f, 0f, 0f);
			PitchTransform.localRotation = Quaternion.RotateTowards(PitchTransform.localRotation, val, Mathf.Abs(PowerDownPitchAngle) / Mathf.Max(0.01f, DeployDuration) * Time.deltaTime);
		}
		if (m_deployProgress >= 1f)
		{
			if ((Object)(object)m_physObj != (Object)null)
			{
				m_physObj.SetIsKinematicLocked(true);
			}
			m_state = SentryState.Scanning;
			m_stateTimer = 0f;
			if ((Object)(object)TargetingLaser != (Object)null)
			{
				TargetingLaser.SetActive(true);
			}
			if (EnableDebugLogging)
			{
				Debug.Log((object)"[SimplifiedSentryGun] Deployment complete. Entering Scanning state.");
			}
		}
	}

	private void UpdateScanning()
	{
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		if (Priority != null)
		{
			Priority.Compute();
			if (Priority.HasFreshTarget() && Priority.GetTimeSinceTopTargetSeen() <= MaxBlindFireTime)
			{
				m_smoothedTargetPos = Priority.GetTargetPoint();
				m_lastKnownTargetPos = m_smoothedTargetPos;
				m_state = SentryState.Acquiring;
				m_stateTimer = 0f;
				if (AudEvent_Acquired != null)
				{
					SM.PlayGenericSound(AudEvent_Acquired, ((Component)this).transform.position);
				}
				if (EnableDebugLogging)
				{
					Debug.Log((object)"[SimplifiedSentryGun] Visual contact acquired. Entering Acquiring state.");
				}
				return;
			}
		}
		if (m_scanPauseTimer > 0f)
		{
			m_scanPauseTimer -= Time.deltaTime;
		}
		else
		{
			m_currentScanAngle += m_scanDirection * YawSpeed * Time.deltaTime;
			if (Mathf.Abs(m_currentScanAngle) >= ScanAngle)
			{
				m_currentScanAngle = Mathf.Clamp(m_currentScanAngle, 0f - ScanAngle, ScanAngle);
				m_scanDirection = 0f - m_scanDirection;
				m_scanPauseTimer = ScanPauseDuration;
			}
		}
		Quaternion val = Quaternion.Euler(0f, m_currentScanAngle, 0f);
		YawTransform.localRotation = Quaternion.RotateTowards(YawTransform.localRotation, val, YawSpeed * Time.deltaTime);
		if ((Object)(object)PitchTransform != (Object)null && (Object)(object)PitchTransform != (Object)(object)YawTransform)
		{
			PitchTransform.localRotation = Quaternion.RotateTowards(PitchTransform.localRotation, Quaternion.identity, PitchSpeed * Time.deltaTime);
		}
	}

	private void UpdateAcquiring()
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		if (Priority == null)
		{
			m_state = SentryState.Scanning;
			return;
		}
		Priority.Compute();
		if (!Priority.HasFreshTarget() || Priority.GetTimeSinceTopTargetSeen() > MaxBlindFireTime)
		{
			m_state = SentryState.Scanning;
			return;
		}
		Vector3 targetPoint = Priority.GetTargetPoint();
		if (TargetSmoothingSpeed > 0f)
		{
			m_smoothedTargetPos = Vector3.Lerp(m_smoothedTargetPos, targetPoint, Time.deltaTime * TargetSmoothingSpeed);
		}
		else
		{
			m_smoothedTargetPos = targetPoint;
		}
		m_lastKnownTargetPos = m_smoothedTargetPos;
		AimTowardPoint(m_lastKnownTargetPos);
		m_stateTimer += Time.deltaTime;
		if (m_stateTimer >= LockOnDelay)
		{
			m_state = SentryState.Engaging;
			m_refireTimer = 0f;
			m_burstCooldownTimer = 0f;
			m_burstsRemaining = Random.Range(BurstCountMin, BurstCountMax + 1);
			m_spoolTimer = 0f;
			if (EnableDebugLogging)
			{
				Debug.Log((object)"[SimplifiedSentryGun] Lock-on established. Entering Engaging state.");
			}
		}
	}

	private void UpdateEngaging()
	{
		//IL_008a: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		if (Priority == null)
		{
			m_state = SentryState.TargetLost;
			m_stateTimer = 0f;
			return;
		}
		Priority.Compute();
		if (!Priority.HasFreshTarget() || Priority.GetTimeSinceTopTargetSeen() > MaxBlindFireTime)
		{
			m_state = SentryState.TargetLost;
			m_stateTimer = 0f;
			if (EnableDebugLogging)
			{
				Debug.Log((object)"[SimplifiedSentryGun] Target lost or eliminated. Entering TargetLost state.");
			}
			return;
		}
		Vector3 targetPoint = Priority.GetTargetPoint();
		if (TargetSmoothingSpeed > 0f)
		{
			m_smoothedTargetPos = Vector3.Lerp(m_smoothedTargetPos, targetPoint, Time.deltaTime * TargetSmoothingSpeed);
		}
		else
		{
			m_smoothedTargetPos = targetPoint;
		}
		m_lastKnownTargetPos = m_smoothedTargetPos;
		AimTowardPoint(m_lastKnownTargetPos);
		if (SpoolUpTime > 0f && m_spoolTimer < SpoolUpTime)
		{
			m_spoolTimer += Time.deltaTime;
		}
		else
		{
			if (!IsAimedAtTarget(m_lastKnownTargetPos))
			{
				return;
			}
			float num = 60f / Mathf.Max(1f, FireRateRPM);
			if (IsFullAuto)
			{
				m_refireTimer += Time.deltaTime;
				if (m_refireTimer >= num)
				{
					m_refireTimer = 0f;
					ExecuteShot();
				}
				return;
			}
			if (m_burstCooldownTimer > 0f)
			{
				m_burstCooldownTimer -= Time.deltaTime;
				return;
			}
			m_refireTimer += Time.deltaTime;
			if (m_refireTimer >= num)
			{
				m_refireTimer = 0f;
				ExecuteShot();
				m_burstsRemaining--;
				if (m_burstsRemaining <= 0)
				{
					m_burstCooldownTimer = BurstCooldown;
					m_burstsRemaining = Random.Range(BurstCountMin, BurstCountMax + 1);
				}
			}
		}
	}

	private void UpdateTargetLost()
	{
		//IL_0003: 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_00b1: 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)
		AimTowardPoint(m_lastKnownTargetPos);
		m_stateTimer += Time.deltaTime;
		if (m_stateTimer >= LingerDuration)
		{
			m_state = SentryState.Scanning;
			m_stateTimer = 0f;
			if (EnableDebugLogging)
			{
				Debug.Log((object)"[SimplifiedSentryGun] Target lost timeout expired. Resuming scanning.");
			}
		}
		else
		{
			if (Priority == null)
			{
				return;
			}
			Priority.Compute();
			if (Priority.HasFreshTarget() && Priority.GetTimeSinceTopTargetSeen() <= MaxBlindFireTime)
			{
				m_smoothedTargetPos = Priority.GetTargetPoint();
				m_lastKnownTargetPos = m_smoothedTargetPos;
				m_state = SentryState.Engaging;
				m_spoolTimer = 0f;
				if (EnableDebugLogging)
				{
					Debug.Log((object)"[SimplifiedSentryGun] Target reacquired. Entering Engaging state.");
				}
			}
		}
	}

	private void AimTowardPoint(Vector3 worldPoint)
	{
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: 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_018d: 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_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: 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)
		if ((Object)(object)PitchTransform != (Object)null && (Object)(object)PitchTransform == (Object)(object)YawTransform)
		{
			Transform val = ((!((Object)(object)YawTransform.parent != (Object)null)) ? BaseTransform : YawTransform.parent);
			Vector3 val2 = val.InverseTransformDirection(worldPoint - YawTransform.position);
			if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
			{
				Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up);
				Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles;
				float num = ((!(eulerAngles.x > 180f)) ? eulerAngles.x : (eulerAngles.x - 360f));
				num = Mathf.Clamp(num, 0f - MaxPitchUp, MaxPitchDown);
				val3 = Quaternion.Euler(num, eulerAngles.y, 0f);
				YawTransform.localRotation = Quaternion.RotateTowards(YawTransform.localRotation, val3, Mathf.Max(YawSpeed, PitchSpeed) * Time.deltaTime);
			}
			return;
		}
		Transform val4 = ((!((Object)(object)YawTransform.parent != (Object)null)) ? BaseTransform : YawTransform.parent);
		Vector3 val5 = val4.InverseTransformPoint(worldPoint);
		Vector3 val6 = default(Vector3);
		((Vector3)(ref val6))..ctor(val5.x, 0f, val5.z);
		if (((Vector3)(ref val6)).sqrMagnitude > 0.001f)
		{
			Quaternion val7 = Quaternion.LookRotation(val6, Vector3.up);
			YawTransform.localRotation = Quaternion.RotateTowards(YawTransform.localRotation, val7, YawSpeed * Time.deltaTime);
		}
		if ((Object)(object)PitchTransform != (Object)null)
		{
			Transform val8 = ((!((Object)(object)PitchTransform.parent != (Object)null)) ? YawTransform : PitchTransform.parent);
			Vector3 val9 = worldPoint - PitchTransform.position;
			Vector3 val10 = val8.InverseTransformDirection(val9);
			float num2 = (0f - Mathf.Atan2(val10.y, Mathf.Sqrt(val10.x * val10.x + val10.z * val10.z))) * 57.29578f;
			num2 = Mathf.Clamp(num2, 0f - MaxPitchUp, MaxPitchDown);
			Quaternion val11 = Quaternion.Euler(num2, 0f, 0f);
			PitchTransform.localRotation = Quaternion.RotateTowards(PitchTransform.localRotation, val11, PitchSpeed * Time.deltaTime);
		}
	}

	private bool IsAimedAtTarget(Vector3 targetPoint)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		Transform aimReferenceTransform = GetAimReferenceTransform();
		Vector3 val = targetPoint - aimReferenceTransform.position;
		if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
		{
			return true;
		}
		float num = Vector3.Angle(aimReferenceTransform.forward, ((Vector3)(ref val)).normalized);
		return num <= FiringAngleLimit;
	}

	private Transform GetAimReferenceTransform()
	{
		if (Muzzles.Count > 0 && (Object)(object)Muzzles[0] != (Object)null)
		{
			return Muzzles[0];
		}
		if ((Object)(object)PitchTransform != (Object)null)
		{
			return PitchTransform;
		}
		if ((Object)(object)YawTransform != (Object)null)
		{
			return YawTransform;
		}
		return BaseTransform;
	}

	private void ExecuteShot()
	{
		//IL_0026: 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_00ab: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: 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_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		if (CurrentAmmo <= 0)
		{
			if (AudEvent_DryFire != null)
			{
				SM.PlayGenericSound(AudEvent_DryFire, ((Component)this).transform.position);
			}
			if (ExplodesOnEmpty)
			{
				Decommission();
			}
		}
		else
		{
			if (CheckFriendlyFire && IsFriendlyInLineOfFire())
			{
				return;
			}
			Transform activeMuzzle = GetActiveMuzzle();
			if ((Object)(object)activeMuzzle == (Object)null || (Object)(object)m_cachedProjectilePrefab == (Object)null)
			{
				return;
			}
			CurrentAmmo--;
			for (int i = 0; i < m_cachedNumProjectiles; i++)
			{
				Quaternion val = activeMuzzle.rotation;
				float num = AccuracySpread + m_cachedSpread;
				if (num > 0.01f)
				{
					Vector2 val2 = Random.insideUnitCircle * num;
					val *= Quaternion.Euler(val2.x, val2.y, 0f);
				}
				GameObject val3 = Object.Instantiate<GameObject>(m_cachedProjectilePrefab, activeMuzzle.position, val);
				BallisticProjectile component = val3.GetComponent<BallisticProjectile>();
				if ((Object)(object)component != (Object)null)
				{
					component.SetSource_IFF(SentryIFF);
					float num2 = component.MuzzleVelocityBase;
					if (!UseAmmoCatalog && CustomMuzzleVelocity > 0f)
					{
						num2 = CustomMuzzleVelocity;
					}
					component.Fire(num2, val3.transform.forward, (FVRFireArm)null, true);
				}
			}
			EjectCasing();
			if ((Object)(object)CustomMuzzleFlash != (Object)null)
			{
				CustomMuzzleFlash.Play();
			}
			if (m_muzzleSystems != null)
			{
				for (int j = 0; j < m_muzzleSystems.Count; j++)
				{
					SentryMuzzlePSystem sentryMuzzlePSystem = m_muzzleSystems[j];
					if (sentryMuzzlePSystem != null && (Object)(object)sentryMuzzlePSystem.PSystem != (Object)null)
					{
						if ((Object)(object)sentryMuzzlePSystem.OverridePoint == (Object)null)
						{
							((Component)sentryMuzzlePSystem.PSystem).transform.position = activeMuzzle.position;
							((Component)sentryMuzzlePSystem.PSystem).transform.rotation = activeMuzzle.rotation;
						}
						sentryMuzzlePSystem.PSystem.Emit(sentryMuzzlePSystem.NumParticlesPerShot);
					}
				}
			}
			FXM.InitiateMuzzleFlash(activeMuzzle.position, activeMuzzle.forward, 0.65f, new Color(1f, 0.9f, 0.77f), 1f);
			if (GasOutEffects != null)
			{
				for (int k = 0; k < GasOutEffects.Length; k++)
				{
					if (GasOutEffects[k] != null)
					{
						GasOutEffects[k].AddGas(false);
					}
				}
			}
			for (int l = 0; l < FiringActionComponents.Count; l++)
			{
				SentryFiringActionComponent sentryFiringActionComponent = FiringActionComponents[l];
				if (sentryFiringActionComponent != null)
				{
					sentryFiringActionComponent.CurrentImpulse = 1f;
				}
			}
			if (AudEvent_Fire != null)
			{
				SM.PlayGenericSound(AudEvent_Fire, activeMuzzle.position);
			}
			if (CurrentAmmo <= 0 && ExplodesOnEmpty)
			{
				Decommission();
			}
		}
	}

	private void EjectCasing()
	{
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_009d: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)EjectionPort == (Object)null)
		{
			return;
		}
		if (UseAmmoCatalog && (Object)(object)m_cachedRoundPrefab != (Object)null)
		{
			GameObject val = Object.Instantiate<GameObject>(m_cachedRoundPrefab, EjectionPort.position, EjectionPort.rotation);
			FVRFireArmRound component = val.GetComponent<FVRFireArmRound>();
			if ((Object)(object)component != (Object)null)
			{
				component.Fire();
				Vector3 val2 = EjectionPort.right * EjectionSpeed + Random.insideUnitSphere * EjectionJitter;
				Vector3 val3 = Random.insideUnitSphere * 20f;
				component.Eject(EjectionPort.position, val2, val3);
			}
		}
		else if ((Object)(object)CustomCasingPrefab != (Object)null)
		{
			GameObject val4 = Object.Instantiate<GameObject>(CustomCasingPrefab, EjectionPort.position, EjectionPort.rotation);
			Rigidbody component2 = val4.GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.velocity = EjectionPort.right * EjectionSpeed + Random.insideUnitSphere * EjectionJitter;
				component2.angularVelocity = Random.insideUnitSphere * 20f;
			}
		}
	}

	private Transform GetActiveMuzzle()
	{
		if (Muzzles.Count == 0)
		{
			return null;
		}
		Transform result = Muzzles[m_muzzleIndex];
		m_muzzleIndex = (m_muzzleIndex + 1) % Muzzles.Count;
		return result;
	}

	private void UpdateRotorAnimation()
	{
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)BarrelRotor == (Object)null))
		{
			float num = ((m_state != SentryState.Engaging && (m_state != SentryState.Acquiring || !(SpoolUpTime > 0f))) ? 0f : RotorMaxSpeed);
			m_currentRotorSpeed = Mathf.MoveTowards(m_currentRotorSpeed, num, RotorMaxSpeed * 2f * Time.deltaTime);
			if (m_currentRotorSpeed > 0.1f)
			{
				BarrelRotor.Rotate(RotorSpinAxis, m_currentRotorSpeed * Time.deltaTime, (Space)1);
			}
		}
	}

	private void UpdateAnimatedComponents(float progress)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp01(progress);
		for (int i = 0; i < AnimatedComponents.Count; i++)
		{
			SentryAnimatedComponent sentryAnimatedComponent = AnimatedComponents[i];
			if (sentryAnimatedComponent != null && (Object)(object)sentryAnimatedComponent.TargetTransform != (Object)null)
			{
				if (sentryAnimatedComponent.AnimatePosition)
				{
					sentryAnimatedComponent.TargetTransform.localPosition = Vector3.Lerp(sentryAnimatedComponent.PoweredDownPosition, sentryAnimatedComponent.PoweredUpPosition, num);
				}
				if (sentryAnimatedComponent.AnimateRotation)
				{
					sentryAnimatedComponent.TargetTransform.localRotation = Quaternion.Slerp(Quaternion.Euler(sentryAnimatedComponent.PoweredDownEuler), Quaternion.Euler(sentryAnimatedComponent.PoweredUpEuler), num);
				}
			}
		}
	}

	private void UpdateFiringActionComponents()
	{
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: 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_009b: 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)
		//IL_00b2: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < FiringActionComponents.Count; i++)
		{
			SentryFiringActionComponent sentryFiringActionComponent = FiringActionComponents[i];
			if (sentryFiringActionComponent == null || !((Object)(object)sentryFiringActionComponent.TargetTransform != (Object)null))
			{
				continue;
			}
			if (sentryFiringActionComponent.CurrentImpulse > 0.001f)
			{
				sentryFiringActionComponent.CurrentImpulse = Mathf.MoveTowards(sentryFiringActionComponent.CurrentImpulse, 0f, sentryFiringActionComponent.ReturnSpeed * Time.deltaTime);
				float currentImpulse = sentryFiringActionComponent.CurrentImpulse;
				Vector3 val = sentryFiringActionComponent.RecoilPositionOffset * currentImpulse;
				Vector3 val2 = sentryFiringActionComponent.RecoilEulerOffset * currentImpulse;
				if (sentryFiringActionComponent.AddRandomJitter && currentImpulse > 0.01f)
				{
					val += Random.insideUnitSphere * (0.005f * currentImpulse);
					val2 += Random.insideUnitSphere * (5f * currentImpulse);
				}
				sentryFiringActionComponent.TargetTransform.localPosition = sentryFiringActionComponent.InitialLocalPosition + val;
				sentryFiringActionComponent.TargetTransform.localRotation = sentryFiringActionComponent.InitialLocalRotation * Quaternion.Euler(val2);
			}
			else
			{
				sentryFiringActionComponent.TargetTransform.localPosition = sentryFiringActionComponent.InitialLocalPosition;
				sentryFiringActionComponent.TargetTransform.localRotation = sentryFiringActionComponent.InitialLocalRotation;
			}
		}
	}

	private void UpdateGasOutEffects()
	{
		if (GasOutEffects == null)
		{
			return;
		}
		for (int i = 0; i < GasOutEffects.Length; i++)
		{
			GasOutEffect val = GasOutEffects[i];
			if (val != null && (Object)(object)val.PSystem != (Object)null)
			{
				val.GasUpdate(true);
			}
		}
	}

	private void InitMuzzleEffects()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Invalid comparison between Unknown and I4
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: 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_00aa: Expected I4, but got Unknown
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		m_muzzleSystems = new List<SentryMuzzlePSystem>();
		if (MuzzleEffects == null || MuzzleEffects.Length == 0)
		{
			return;
		}
		Transform aimReferenceTransform = GetAimReferenceTransform();
		bool flag = (Object)(object)GM.CurrentSceneSettings != (Object)null && GM.CurrentSceneSettings.IsSceneLowLight;
		for (int i = 0; i < MuzzleEffects.Length; i++)
		{
			MuzzleEffect val = MuzzleEffects[i];
			if ((int)val.Entry == 0)
			{
				continue;
			}
			MuzzleEffectConfig muzzleConfig = FXM.GetMuzzleConfig(val.Entry);
			if ((Object)(object)muzzleConfig != (Object)null)
			{
				MuzzleEffectSize val2 = (((int)val.Size == 1) ? DefaultMuzzleEffectSize : val.Size);
				int index = (int)val2;
				GameObject val3 = ((!flag) ? muzzleConfig.Prefabs_Highlight[index] : muzzleConfig.Prefabs_Lowlight[index]);
				if ((Object)(object)val3 != (Object)null)
				{
					Transform val4 = ((!((Object)(object)val.OverridePoint != (Object)null)) ? aimReferenceTransform : val.OverridePoint);
					GameObject val5 = Object.Instantiate<GameObject>(val3, val4.position, val4.rotation);
					val5.transform.SetParent(val4);
					val5.transform.localPosition = Vector3.zero;
					val5.transform.localEulerAngles = Vector3.zero;
					SentryMuzzlePSystem sentryMuzzlePSystem = new SentryMuzzlePSystem();
					sentryMuzzlePSystem.PSystem = val5.GetComponent<ParticleSystem>();
					sentryMuzzlePSystem.OverridePoint = val.OverridePoint;
					sentryMuzzlePSystem.NumParticlesPerShot = ((!flag) ? muzzleConfig.NumParticles_Highlight[index] : muzzleConfig.NumParticles_Lowlight[index]);
					m_muzzleSystems.Add(sentryMuzzlePSystem);
				}
			}
		}
	}

	private bool IsFriendlyInLineOfFire()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: 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_0023: 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_0025: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		Transform aimReferenceTransform = GetAimReferenceTransform();
		Vector3 position = aimReferenceTransform.position;
		Vector3 forward = aimReferenceTransform.forward;
		float num = Vector3.Distance(position, m_lastKnownTargetPos);
		int num2 = Physics.RaycastNonAlloc(new Ray(position, forward), m_friendlyFireHits, num, LayerMask.op_Implicit(FriendlyFireMask), (QueryTriggerInteraction)1);
		for (int i = 0; i < num2; i++)
		{
			RaycastHit val = m_friendlyFireHits[i];
			if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).transform.root == (Object)(object)((Component)this).transform.root))
			{
				AIEntity val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponent<AIEntity>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<AIEntity>();
				}
				if ((Object)(object)val2 != (Object)null && val2.IFFCode == SentryIFF)
				{
					return true;
				}
				if (SentryIFF == 0 && (Object)(object)GM.CurrentPlayerBody != (Object)null && (Object)(object)((RaycastHit)(ref val)).transform.root == (Object)(object)((Component)GM.CurrentPlayerBody).transform.root)
				{
					return true;
				}
			}
		}
		return false;
	}

	public void Damage(Damage d)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if (m_isDead)
		{
			return;
		}
		if (DamageableColliders.Count > 0)
		{
			bool flag = false;
			for (int i = 0; i < DamageableColliders.Count; i++)
			{
				Collider val = DamageableColliders[i];
				if ((Object)(object)val != (Object)null)
				{
					Vector3 val2 = val.ClosestPointOnBounds(d.point);
					Vector3 val3 = val2 - d.point;
					if (((Vector3)(ref val3)).sqrMagnitude < 0.0225f)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				return;
			}
		}
		Health -= d.Dam_TotalKinetic;
		if (EnableDebugLogging)
		{
			Debug.Log((object)("[SimplifiedSentryGun] Took damage: " + d.Dam_TotalKinetic + ". Remaining Health: " + Health));
		}
		if (Health <= 0f)
		{
			Decommission();
		}
	}

	public void Decommission()
	{
		//IL_00d7: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: 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_0208: 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_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		if (m_isDead)
		{
			return;
		}
		m_isDead = true;
		m_state = SentryState.Dead;
		if (Priority != null)
		{
			Priority.DestroySystem();
		}
		if ((Object)(object)m_physObj != (Object)null)
		{
			m_physObj.SetIsKinematicLocked(false);
		}
		if ((Object)(object)TargetingLaser != (Object)null)
		{
			TargetingLaser.SetActive(false);
		}
		UpdateAnimatedComponents(0f);
		if ((Object)(object)PitchTransform != (Object)null && UseProceduralPitchDeploy)
		{
			PitchTransform.localRotation = Quaternion.Euler(PowerDownPitchAngle, 0f, 0f);
		}
		if (AudEvent_Destroyed != null)
		{
			SM.PlayGenericSound(AudEvent_Destroyed, ((Component)this).transform.position);
		}
		else if (AudEvent_Shutdown != null)
		{
			SM.PlayGenericSound(AudEvent_Shutdown, ((Component)this).transform.position);
		}
		if (m_muzzleSystems != null)
		{
			for (int i = 0; i < m_muzzleSystems.Count; i++)
			{
				if (m_muzzleSystems[i] != null && (Object)(object)m_muzzleSystems[i].PSystem != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)m_muzzleSystems[i].PSystem).gameObject);
				}
			}
			m_muzzleSystems.Clear();
		}
		if ((Object)(object)ExplosionPrefab != (Object)null)
		{
			Object.Instantiate<GameObject>(ExplosionPrefab, ((Component)this).transform.position, ((Component)this).transform.rotation);
		}
		if (DestructionDebris.Count > 0)
		{
			for (int j = 0; j < DestructionDebris.Count; j++)
			{
				if ((Object)(object)DestructionDebris[j] != (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(DestructionDebris[j], ((Component)this).transform.position, Random.rotation);
					Rigidbody component = val.GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null)
					{
						component.velocity = Random.insideUnitSphere * 4f + Vector3.up * 2f;
						component.angularVelocity = Random.insideUnitSphere * 15f;
					}
				}
			}
		}
		if (EnableDebugLogging)
		{
			Debug.Log((object)"[SimplifiedSentryGun] Sentry destroyed/decommissioned.");
		}
		Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f);
	}

	private void OnDrawGizmosSelected()
	{
		//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_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: 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_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: 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_0060: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		Transform val = ((!((Object)(object)BaseTransform != (Object)null)) ? ((Component)this).transform : BaseTransform);
		Vector3 position = val.position;
		Vector3 forward = val.forward;
		Vector3 up = val.up;
		Gizmos.color = Color.cyan;
		Quaternion val2 = Quaternion.AngleAxis(0f - ScanAngle, up);
		Quaternion val3 = Quaternion.AngleAxis(ScanAngle, up);
		Gizmos.DrawLine(position, position + val2 * forward * 40f);
		Gizmos.DrawLine(position, position + val3 * forward * 40f);
	}
}
public class AdvanceFeedTrayControl : FVRInteractiveObject
{
	public enum HingeAxis
	{
		X,
		Y,
		Z
	}

	[Header("Axis and Angle Configuration")]
	[Tooltip("Local axis around which the feed tray rotates.")]
	public HingeAxis RotationHingeAxis = HingeAxis.X;

	[Tooltip("Maximum angle in degrees the feed tray can be lifted.")]
	public float MaxFeedTrayAngle = 45f;

	[Tooltip("Optional static reference transform on the receiver. If empty or self, uses firearm root.")]
	public Transform BaseVector;

	[Header("Connections")]
	[Tooltip("Reference to the Top Cover script.")]
	public AdvanceTopCoverControl TopCover;

	[Header("Audio")]
	public AudioEvent TrayOpenSound;

	public AudioEvent TrayCloseSound;

	private float m_currentAngle;

	private bool m_wasUp;

	private bool m_wasOpenInGrab;

	private bool m_wasClosedInGrab;

	private Vector3 m_initialLocalEuler;

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

	public override void Start()
	{
		((FVRInteractiveObject)this).Start();
		if ((Object)(object)TopCover == (Object)null)
		{
			FVRFireArm componentInParent = ((Component)this).GetComponentInParent<FVRFireArm>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				TopCover = ((Component)componentInParent).GetComponentInChildren<AdvanceTopCoverControl>();
			}
		}
		if ((Object)(object)TopCover != (Object)null && (Object)(object)TopCover.TargetFeedTray == (Object)null)
		{
			TopCover.TargetFeedTray = this;
		}
		SetAngle(0f);
	}

	public override bool IsInteractable()
	{
		if ((Object)(object)TopCover == (Object)null)
		{
			FVRFireArm componentInParent = ((Component)this).GetComponentInParent<FVRFireArm>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				TopCover = ((Component)componentInParent).GetComponentInChildren<AdvanceTopCoverControl>();
			}
		}
		if ((Object)(object)TopCover == (Object)null || TopCover.GetAngle() < 25f)
		{
			return false;
		}
		FVRFireArm val = ((!((Object)(object)TopCover != (Object)null)) ? ((Component)this).GetComponentInParent<FVRFireArm>() : ((FVRFireArmTopCoverAdvanced)TopCover).FireArm);
		if ((Object)(object)val != (Object)null)
		{
			if (val.HasBelt || (Object)(object)val.Magazine != (Object)null)
			{
				return false;
			}
			if ((Object)(object)val.BeltDD != (Object)null && val.BeltDD.BeltRounds.Count > 0)
			{
				return false;
			}
		}
		return ((FVRInteractiveObject)this).IsInteractable();
	}

	public override void Poke(FVRViveHand hand)
	{
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Poke(hand);
		if ((Object)(object)hand == (Object)null || ((FVRInteractiveObject)this).IsHeld || (Object)(object)TopCover == (Object)null || !TopCover.HasRetainedSpentLink() || !(TopCover.GetAngle() > 15f) || !TopCover.CanClearLink())
		{
			return;
		}
		float magnitude = ((Vector3)(ref hand.Input.VelLinearWorld)).magnitude;
		float requiredLinkClearSpeed = TopCover.GetRequiredLinkClearSpeed();
		if (magnitude >= requiredLinkClearSpeed)
		{
			Vector3 ejectVelocity = ((Vector3)(ref hand.Input.VelLinearWorld)).normalized * (TopCover.LinkEjectForce * 1.5f) + Vector3.up * 0.6f;
			TopCover.ClearSpentLink(ejectVelocity);
			if ((Object)(object)hand.Buzzer != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
			}
		}
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).BeginInteraction(hand);
		m_wasOpenInGrab = m_currentAngle > 15f;
		m_wasClosedInGrab = m_currentAngle < 5f;
		if (m_currentAngle < 5f && TrayOpenSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)10, TrayOpenSound, ((Component)this).transform.position);
			m_wasOpenInGrab = true;
			m_wasClosedInGrab = false;
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hand == (Object)null)
		{
			return;
		}
		Transform stableReferenceTransform = GetStableReferenceTransform();
		Vector3 val = ((HandInput)(ref hand.Input)).Pos - ((Component)this).transform.position;
		Vector3 worldHingeAxis = GetWorldHingeAxis(stableReferenceTransform);
		Vector3 val2 = Vector3.ProjectOnPlane(val, worldHingeAxis);
		Vector3 normalized = ((Vector3)(ref val2)).normalized;
		Vector3 val3 = Vector3.Cross(worldHingeAxis, -stableReferenceTransform.forward);
		float num = Mathf.Sign(Vector3.Dot(normalized, val3));
		float num2 = Vector3.Angle(normalized, -stableReferenceTransform.forward) * num;
		float num3 = Mathf.Clamp(num2, 0f, MaxFeedTrayAngle);
		if ((Object)(object)TopCover != (Object)null)
		{
			num3 = Mathf.Min(num3, TopCover.GetAngle());
		}
		if (num3 > 15f && !m_wasOpenInGrab)
		{
			if (TrayOpenSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, TrayOpenSound, ((Component)this).transform.position);
			}
			m_wasOpenInGrab = true;
			m_wasClosedInGrab = false;
		}
		else if (num3 < 5f && !m_wasClosedInGrab && m_wasOpenInGrab)
		{
			if (TrayCloseSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, TrayCloseSound, ((Component)this).transform.position);
			}
			m_wasClosedInGrab = true;
			m_wasOpenInGrab = false;
		}
		SetAngle(num3);
		if (num3 > 15f && (Object)(object)TopCover != (Object)null)
		{
			Vector3 ejectVelocity = ((Component)this).transform.up * (TopCover.LinkEjectForce * 1.2f) + ((Component)this).transform.right * TopCover.LinkEjectForce;
			TopCover.ClearSpentLink(ejectVelocity);
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).EndInteraction(hand);
		if (m_currentAngle < 15f)
		{
			SetAngle(0f);
			if (m_wasUp && !m_wasClosedInGrab && TrayCloseSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, TrayCloseSound, ((Component)this).transform.position);
			}
			m_wasUp = false;
		}
		else if (m_currentAngle > MaxFeedTrayAngle - 10f)
		{
			float angle = ((!((Object)(object)TopCover != (Object)null)) ? MaxFeedTrayAngle : Mathf.Min(MaxFeedTrayAngle, TopCover.GetAngle()));
			SetAngle(angle);
			m_wasUp = true;
		}
		else
		{
			m_wasUp = m_currentAngle > 5f;
		}
		m_wasOpenInGrab = false;
		m_wasClosedInGrab = false;
	}

	public float GetAngle()
	{
		return m_currentAngle;
	}

	public void SetAngle(float angle)
	{
		//IL_0019: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		m_currentAngle = Mathf.Clamp(angle, 0f, MaxFeedTrayAngle);
		Vector3 initialLocalEuler = m_initialLocalEuler;
		switch (RotationHingeAxis)
		{
		case HingeAxis.X:
			initialLocalEuler.x = m_currentAngle;
			break;
		case HingeAxis.Y:
			initialLocalEuler.y = m_currentAngle;
			break;
		case HingeAxis.Z:
			initialLocalEuler.z = m_currentAngle;
			break;
		}
		((Component)this).transform.localEulerAngles = initialLocalEuler;
	}

	private Transform GetStableReferenceTransform()
	{
		if ((Object)(object)BaseVector != (Object)null && (Object)(object)BaseVector != (Object)(object)((Component)this).transform && !BaseVector.IsChildOf(((Component)this).transform))
		{
			return BaseVector;
		}
		if ((Object)(object)TopCover != (Object)null && (Object)(object)((FVRFireArmTopCoverAdvanced)TopCover).FireArm != (Object)null)
		{
			return ((Component)((FVRFireArmTopCoverAdvanced)TopCover).FireArm).transform;
		}
		FVRFireArm componentInParent = ((Component)this).GetComponentInParent<FVRFireArm>();
		if ((Object)(object)componentInParent != (Object)null)
		{
			return ((Component)componentInParent).transform;
		}
		return (!((Object)(object)((Component)this).transform.parent != (Object)null)) ? ((Component)this).transform : ((Component)this).transform.parent;
	}

	private Vector3 GetWorldHingeAxis(Transform refTransform)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		return (Vector3)(RotationHingeAxis switch
		{
			HingeAxis.X => refTransform.right, 
			HingeAxis.Y => refTransform.up, 
			HingeAxis.Z => refTransform.forward, 
			_ => refTransform.right, 
		});
	}
}
public class AdvanceTopCoverControl : FVRFireArmTopCoverAdvanced
{
	public enum HingeAxis
	{
		X,
		Y,
		Z
	}

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

	public enum LinkReloadEnforcementMode
	{
		Disabled,
		LatchGate,
		HardBeltLockout
	}

	[Header("Master Jam Toggle")]
	[Tooltip("If false, disables all jams, misfeeds, handle lockouts, and mislatches.")]
	public bool EnableAllJamsAndMisfeeds = true;

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

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

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

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

	[Header("Non-Reciprocating Charging Handle")]
	[Tooltip("If true, the charging handle will not auto-return forward when released.")]
	public bool EnableManualChargingHandle = true;

	[Tooltip("If true, firing with the handle rearward slingshots the handle forward.")]
	public bool SlingshotHandleOnFire = true;

	[Tooltip("Speed at which the handle slams forward when slingshotted.")]
	public float SlingshotSpeed = 3.5f;

	[Range(0f, 1f)]
	[Tooltip("Chance that firing with the handle rearward pops the top cover latch ajar.")]
	public float SlingshotPopCoverChance = 0.65f;

	[Range(0f, 1f)]
	[Tooltip("Chance that firing with the handle rearward wastes a belt round.")]
	public float SlingshotWasteAmmoChance = 0.35f;

	[Tooltip("Optional sound played when the bolt slams the charging handle forward.")]
	public AudioEvent HandleSlingshotSound;

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

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

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

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

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

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

	[Tooltip("Minimum angle in degrees above which a bump slams the cover shut.")]
	public float BumpMinAngle = 0f;

	[Tooltip("Maximum angle in degrees below which a bump slams the cover shut.")]
	public float BumpMaxAngle = 125f;

	[Tooltip("Maximum allowed angle in degrees between the hand velocity and straight down.")]
	public float BumpMaxDownwardAngle = 65f;

	[Tooltip("Minimum hand speed in meters per second required to slam the cover shut.")]
	public float BumpSlamVelocityThreshold = 0.25f;

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

	[Header("Spent Link Retention and Clearing")]
	[Tooltip("If true, firing the last round of a belt leaves an empty link on the feed tray.")]
	public bool EnableSpentLinkRetention = true;

	[Tooltip("Minimum hand velocity in meters per second required to swipe the spent link off the tray.")]
	public float LinkSwipeVelocityThreshold = 0.6f;

	[Tooltip("If true, some spent links stick in the feed pawls, requiring a harder swipe or lifting the feed tray.")]
	public bool EnableStubbornLinkChance = true;

	[Range(0f, 1f)]
	[Tooltip("Probability that an emptied belt leaves a stubborn link.")]
	public float StubbornLinkChance = 0.35f;

	[Tooltip("Force multiplier required to swipe away a stubborn link.")]
	public float StubbornLinkSwipeMultiplier = 2f;

	[Tooltip("How an uncleared spent link impacts reloading.")]
	public LinkReloadEnforcementMode LinkReloadEnforcement = LinkReloadEnforcementMode.LatchGate;

	[Tooltip("Visual GameObject representing the empty link on the feed tray.")]
	public GameObject SpentLinkObject;

	[Tooltip("Optional physics prefab of the link spawned into the world when cleared.")]
	public GameObject PhysicalLinkPrefab;

	[Tooltip("Impulse force applied to the physical link when cleared.")]
	public float LinkEjectForce = 1.6f;

	[Tooltip("Time in seconds before the spawned physical link despawns.")]
	public float LinkDebrisLifetime = 10f;

	[Tooltip("Optional sound played when clearing the spent link.")]
	public AudioEvent LinkFlickSound;

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

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

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

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

	[Tooltip("Speed in degrees per second the cover swings under gravity.")]
	public float GravitySettleSpeed = 60f;

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

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

	[Tooltip("Resting angle offset in degrees above MinMaxAngle.x when imperfectly latched.")]
	public float MislatchRestAngle = 8f;

	[Header("Component References")]
	public OpenBoltChargingHandle TargetChargingHandle;

	public OpenBoltReceiverBolt TargetBolt;

	public AdvanceFeedTrayControl TargetFeedTray;

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

	private float m_currentAngle;

	private bool m_isBeingHeld;

	private bool m_isImperfectlyLatched;

	private bool m_isLatchUnlocked;

	private bool m_hasPlayedInterlockRattle;

	private bool m_hasPlayedLatchRattle;

	private bool m_hasRetainedSpentLink;

	private bool m_isLinkStubborn;

	private bool m_hasSlingshottedThisCycle;

	private bool m_isSlingshotMoving;

	private bool m_startedGrabFromClosed;

	private bool m_wasBeltLoadedLastFrame;

	private float m_linkClearCooldown;

	private float m_origHandleForwardSpeed = 1f;

	private Vector3 m_initialLocalEuler;

	private Vector3 m_spentLinkInitialLocalPos;

	private Quaternion m_spentLinkInitialLocalRot;

	public override void Awake()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Awake();
		m_initialLocalEuler = ((Component)this).transform.localEulerAngles;
		if ((Object)(object)base.BaseVector == (Object)null || (Object)(object)base.BaseVector == (Object)(object)((Component)this).transform || base.BaseVector.IsChildOf(((Component)this).transform))
		{
			FVRFireArm componentInParent = ((Component)this).GetComponentInParent<FVRFireArm>();
			base.BaseVector = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : ((!((Object)(object)((Component)this).transform.parent != (Object)null)) ? ((Component)this).transform : ((Component)this).transform.parent));
		}
		if ((Object)(object)SpentLinkObject != (Object)null)
		{
			m_spentLinkInitialLocalPos = SpentLinkObject.transform.localPosition;
			m_spentLinkInitialLocalRot = SpentLinkObject.transform.localRotation;
		}
	}

	public override void Start()
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		((FVRInteractiveObject)this).Start();
		if ((Object)(object)base.FireArm != (Object)null)
		{
			if ((Object)(object)TargetChargingHandle == (Object)null)
			{
				TargetChargingHandle = ((Component)base.FireArm).GetComponentInChildren<OpenBoltChargingHandle>();
			}
			if ((Object)(object)TargetBolt == (Object)null && base.FireArm is OpenBoltReceiver)
			{
				OpenBoltReceiver val = (OpenBoltReceiver)base.FireArm;
				TargetBolt = val.Bolt;
			}
			if ((Object)(object)TargetFeedTray == (Object)null)
			{
				TargetFeedTray = ((Component)base.FireArm).GetComponentInChildren<AdvanceFeedTrayControl>();
			}
		}
		if ((Object)(object)TargetFeedTray != (Object)null && (Object)(object)TargetFeedTray.TopCover == (Object)null)
		{
			TargetFeedTray.TopCover = this;
		}
		if ((Object)(object)TargetChargingHandle != (Object)null)
		{
			m_origHandleForwardSpeed = TargetChargingHandle.ForwardSpeed;
			if (EnableManualChargingHandle)
			{
				TargetChargingHandle.ForwardSpeed = 0f;
			}
		}
		if ((Object)(object)SpentLinkObject != (Object)null)
		{
			SpentLinkObject.SetActive(false);
		}
		float angle = ((!((Object)(object)base.FireArm != (Object)null) || !base.FireArm.IsTopCoverUp) ? base.MinMaxAngle.x : base.MinMaxAngle.y);
		SetAngle(angle);
		m_wasBeltLoadedLastFrame = IsBeltFeedActive() && GetBeltRoundCount() > 0;
	}

	public override void OnDestroy()
	{
		((FVRInteractiveObject)this).OnDestroy();
		if ((Object)(object)TargetChargingHandle != (Object)null)
		{
			TargetChargingHandle.ForwardSpeed = m_origHandleForwardSpeed;
		}
	}

	private void Update()
	{
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c4: Invalid comparison between Unknown and I4
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Invalid comparison between Unknown and I4
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_030c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e6: Invalid comparison between Unknown and I4
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: 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_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0385: Unknown result type (might be due to invalid IL or missing references)
		//IL_0388: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0489: Unknown result type (might be due to invalid IL or missing references)
		//IL_049a: Unknown result type (might be due to invalid IL or missing references)
		//IL_053f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0544: Unknown result type (might be due to invalid IL or missing references)
		//IL_0548: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_055b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0560: Unknown result type (might be due to invalid IL or missing references)
		//IL_056e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0573: Unknown result type (might be due to invalid IL or missing references)
		//IL_0575: Unknown result type (might be due to invalid IL or missing references)
		//IL_0577: Unknown result type (might be due to invalid IL or missing references)
		//IL_0580: Unknown result type (might be due to invalid IL or missing references)
		//IL_0582: Unknown result type (might be due to invalid IL or missing references)
		//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b0: Invalid comparison between Unknown and I4
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: 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)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)TargetFeedTray != (Object)null)
		{
			if (m_currentAngle < TargetFeedTray.GetAngle())
			{
				TargetFeedTray.SetAngle(m_currentAngle);
			}
			if (TargetFeedTray.GetAngle() > 5f && (Object)(object)base.FireArm != (Object)null && (base.FireArm.HasBelt || (Object)(object)base.FireArm.Magazine != (Object)null))
			{
				base.FireArm.EjectMag(false);
				if (debug)
				{
					Debug.Log((object)"AdvanceTopCoverControl: Magazine rejected - feed tray is currently lifted.");
				}
			}
		}
		if (m_linkClearCooldown > 0f)
		{
			m_linkClearCooldown -= Time.deltaTime;
		}
		if ((Object)(object)base.FireArm != (Object)null && EnableSpentLinkRetention)
		{
			bool flag = IsBeltFeedActive();
			bool flag2 = (Object)(object)base.FireArm.Magazine != (Object)null && ((FVRInteractiveObject)base.FireArm.Magazine).IsHeld;
			if (flag && !flag2)
			{
				int beltRoundCount = GetBeltRoundCount();
				if (m_wasBeltLoadedLastFrame && beltRoundCount == 0 && !m_hasRetainedSpentLink)
				{
					m_hasRetainedSpentLink = true;
					m_linkClearCooldown = 0.25f;
					m_isLinkStubborn = EnableStubbornLinkChance && Random.value < StubbornLinkChance;
					if ((Object)(object)SpentLinkObject != (Object)null)
					{
						SpentLinkObject.transform.localPosition = m_spentLinkInitialLocalPos + new Vector3(Random.Range(-0.0015f, 0.0015f), 0f, Random.Range(-0.002f, 0.002f));
						SpentLinkObject.transform.localRotation = m_spentLinkInitialLocalRot * Quaternion.Euler(Random.Range(-4f, 4f), Random.Range(-8f, 8f), Random.Range(-4f, 4f));
						SpentLinkObject.SetActive(true);
					}
					if (debug)
					{
						Debug.Log((object)"AdvanceTopCoverControl: Belt emptied. Single link retained on feed tray.");
					}
				}
				if (EnableAllJamsAndMisfeeds && LinkReloadEnforcement == LinkReloadEnforcementMode.HardBeltLockout && m_hasRetainedSpentLink && !m_wasBeltLoadedLastFrame && beltRoundCount > 0)
				{
					base.FireArm.EjectMag(false);
					if (debug)
					{
						Debug.Log((object)"AdvanceTopCoverControl: Belt rejected - spent link must be cleared first.");
					}
				}
				m_wasBeltLoadedLastFrame = beltRoundCount > 0;
			}
			else
			{
				m_wasBeltLoadedLastFrame = false;
			}
		}
		if (m_hasRetainedSpentLink && m_currentAngle > base.MinMaxAngle.x + 15f && (Object)(object)base.FireArm != (Object)null)
		{
			float num = Mathf.Abs(((Component)base.FireArm).transform.localEulerAngles.z);
			if (num > 180f)
			{
				num = Mathf.Abs(num - 360f);
			}
			if (num > 55f)
			{
				Vector3 val = ((Component)base.FireArm).transform.right * Mathf.Sign(((Component)base.FireArm).transform.localEulerAngles.z) * (LinkEjectForce * 1.5f);
				ClearSpentLink(val + Vector3.down * 0.8f);
			}
		}
		if ((Object)(object)TargetBolt != (Object)null && ((int)TargetBolt.CurPos == 4 || (int)TargetBolt.CurPos == 2 || (int)TargetBolt.CurPos == 3))
		{
			m_hasSlingshottedThisCycle = false;
		}
		if (SlingshotHandleOnFire && (Object)(object)TargetChargingHandle != (Object)null && (Object)(object)TargetBolt != (Object)null)
		{
			if (m_isSlingshotMoving)
			{
				if ((int)TargetChargingHandle.CurPos == 0)
				{
					TargetChargingHandle.ForwardSpeed = 0f;
					m_isSlingshotMoving = false;
				}
			}
			else if (!m_hasSlingshottedThisCycle && !((FVRInteractiveObject)TargetChargingHandle).IsHeld && (int)TargetChargingHandle.CurPos != 0 && ((int)TargetBolt.CurPos == 0 || (int)TargetBolt.CurPos == 1))
			{
				ExecuteHandleSlingshotSlam();
			}
		}
		if (!((Object)(object)base.FireArm == (Object)null) && !m_isBeingHeld && UseGravityPhysics && !m_isImperfectlyLatched && m_currentAngle > base.MinMaxAngle.x + 0.5f && m_currentAngle < base.MinMaxAngle.y - 0.5f)
		{
			Vector3 gravity = Physics.gravity;
			Vector3 normalized = ((Vector3)(ref gravity)).normalized;
			Vector3 val2 = TransformMassOffsetAtAngle(base.MinMaxAngle.x);
			Vector3 val3 = TransformMassOffsetAtAngle(base.MinMaxAngle.y);
			float num2 = Vector3.Dot(val2, normalized);
			float num3 = Vector3.Dot(val3, normalized);
			float num4 = ((!(num2 > num3)) ? base.MinMaxAngle.y : base.MinMaxAngle.x);
			float num5 = Mathf.MoveTowards(m_currentAngle, num4, GravitySettleSpeed * Time.deltaTime);
			if (num5 <= base.MinMaxAngle.x + 0.01f)
			{
				SetAngle(base.MinMaxAngle.x);
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
				base.FireArm.IsTopCoverUp = false;
				m_isLatchUnlocked = false;
				RollForMislatch();
			}
			else if (num5 >= base.MinMaxAngle.y - 0.01f)
			{
				SetAngle(base.MinMaxAngle.y);
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)23, 1f);
				base.FireArm.IsTopCoverUp = true;
			}
			else
			{
				SetAngle(num5);
			}
		}
	}

	private bool IsBeltFeedActive()
	{
		if ((Object)(object)base.FireArm == (Object)null)
		{
			return false;
		}
		if (base.FireArm.HasBelt && (Object)(object)base.FireArm.BeltDD != (Object)null)
		{
			return true;
		}
		if ((Object)(object)base.FireArm.Magazine != (Object)null && base.FireArm.Magazine.IsBeltBox)
		{
			return true;
		}
		return false;
	}

	private int GetBeltRoundCount()
	{
		if ((Object)(object)base.FireArm == (Object)null)
		{
			return 0;
		}
		if (base.FireArm.HasBelt && (Object)(object)base.FireArm.BeltDD != (Object)null)
		{
			return base.FireArm.BeltDD.BeltRounds.Count;
		}
		if ((Object)(object)base.FireArm.Magazine != (Object)null && base.FireArm.Magazine.IsBeltBox)
		{
			return base.FireArm.Magazine.m_numRounds;
		}
		return 0;
	}

	private void ExecuteHandleSlingshotSlam()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		m_hasSlingshottedThisCycle = true;
		m_isSlingshotMoving = true;
		TargetChargingHandle.ForwardSpeed = SlingshotSpeed;
		if (HandleSlingshotSound != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)10, HandleSlingshotSound, ((Component)TargetChargingHandle).transform.position);
		}
		else if ((Object)(object)base.FireArm != (Object)null)
		{
			base.FireArm.PlayAudioEvent((FirearmAudioEventType)11, 1f);
		}
		if (EnableAllJamsAndMisfeeds && !m_isImperfectlyLatched && Random.value < SlingshotPopCoverChance)
		{
			m_isImperfectlyLatched = true;
			SetAngle(base.MinMaxAngle.x + MislatchRestAngle);
			if ((Object)(object)base.FireArm != (Object)null)
			{
				base.FireArm.IsTopCoverUp = true;
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)23, 1f);
			}
			if (debug)
			{
				Debug.Log((object)"AdvanceTopCoverControl: Bolt slammed charging handle forward, popping top cover ajar.");
			}
		}
		if (EnableAllJamsAndMisfeeds && Random.value < SlingshotWasteAmmoChance)
		{
			TryTriggerSlamMisfeed(SlamVelocityThreshold);
		}
	}

	public bool HasRetainedSpentLink()
	{
		return m_hasRetainedSpentLink;
	}

	public bool CanClearLink()
	{
		return m_linkClearCooldown <= 0f;
	}

	public float GetRequiredLinkClearSpeed()
	{
		return LinkSwipeVelocityThreshold * ((!m_isLinkStubborn) ? 1f : StubbornLinkSwipeMultiplier);
	}

	public override void Poke(FVRViveHand hand)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		((FVRInteractiveObject)this).Poke(hand);
		if ((Object)(object)hand == (Object)null || m_isBeingHeld)
		{
			return;
		}
		Vector3 velLinearWorld = hand.Input.VelLinearWorld;
		float magnitude = ((Vector3)(ref velLinearWorld)).magnitude;
		if (m_hasRetainedSpentLink && m_currentAngle > 15f && CanClearLink())
		{
			float requiredLinkClearSpeed = GetRequiredLinkClearSpeed();
			if (magnitude >= requiredLinkClearSpeed)
			{
				Vector3 ejectVelocity = ((Vector3)(ref velLinearWorld)).normalized * (LinkEjectForce * 1.5f) + Vector3.up * 0.6f;
				ClearSpentLink(ejectVelocity);
				if ((Object)(object)hand.Buzzer != (Object)null)
				{
					hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
				}
				return;
			}
		}
		if (!AllowBumpToSlam)
		{
			return;
		}
		Transform stableReferenceTransform = GetStableReferenceTransform();
		float num = Vector3.Angle(((Vector3)(ref velLinearWorld)).normalized, -stableReferenceTransform.up);
		if (m_currentAngle <= base.MinMaxAngle.x + 1f && !m_isImperfectlyLatched)
		{
			if (magnitude >= BumpSlamVelocityThreshold && num <= BumpMaxDownwardAngle)
			{
				if (BumpSlamSound != null)
				{
					SM.PlayCoreSound((FVRPooledAudioType)10, BumpSlamSound, ((Component)this).transform.position);
				}
				else if ((Object)(object)base.FireArm != (Object)null)
				{
					base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
				}
				if ((Object)(object)hand.Buzzer != (Object)null)
				{
					hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
				}
			}
		}
		else if (((m_currentAngle >= BumpMinAngle && m_currentAngle <= BumpMaxAngle) || m_isImperfectlyLatched) && !(magnitude < BumpSlamVelocityThreshold) && !(num > BumpMaxDownwardAngle))
		{
			m_isImperfectlyLatched = false;
			SetAngle(base.MinMaxAngle.x);
			if ((Object)(object)base.FireArm != (Object)null)
			{
				base.FireArm.IsTopCoverUp = false;
				base.FireArm.PlayAudioEvent((FirearmAudioEventType)24, 1f);
			}
			if (BumpSlamSound != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, BumpSlamSound, ((Component)this).transform.position);
			}
			if ((Object)(object)hand.Buzzer != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_BeginInteraction);
			}
			TryTriggerSlamMisfeed(magnitude);
			RollForMislatch();
			if (!m_isImperfectlyLatched)
			{
				m_isLatchUnlocked = false;
			}
			if (debug)
			{
				Debug.Log((object)("AdvanceTopCoverControl: Bump slammed cover shut at speed " + magnitude + " m/s."));
			}
		}
	}

	public void ClearSpentLink(Vector3 ejectVelocity = default(Vector3))
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: 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_006e: 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_00bb: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: 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_0122: 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_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing refe