Decompiled source of WesternCowboyKit v1.4.0

WesternCowboyKit.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using OpenScripts2;
using OtherLoader;
using UnityEngine;
using UnityEngine.UI;
using VolksScripts;

[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]
namespace VolksScripts
{
	public class Remington1858 : FVRFireArm
	{
		public enum ComparisonType
		{
			GreaterThan,
			LessThan,
			EqualTo
		}

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

		[Header("Latch Configuration")]
		[Tooltip("The Transform representing the latch's moving mesh.")]
		public Transform LatchTransform;

		public bool LatchUsesRotation = true;

		public Axis LatchAxis = (Axis)0;

		public ComparisonType LatchOpenComparison = ComparisonType.GreaterThan;

		public float LatchOpenThreshold = 15f;

		public float LatchTolerance = 5f;

		[Header("Rod Configuration")]
		[Tooltip("The Transform representing the rod/pin's moving mesh.")]
		public Transform RodTransform;

		public bool RodUsesRotation = false;

		public Axis RodAxis = (Axis)2;

		public ComparisonType RodOpenComparison = ComparisonType.GreaterThan;

		public float RodOpenThreshold = 0.08f;

		public ComparisonType RodClosedComparison = ComparisonType.LessThan;

		public float RodClosedThreshold = 0.02f;

		public float RodTolerance = 0.01f;

		[Header("Colliders to Control")]
		[Tooltip("The grab collider on the loading rod. Locked until the Latch is pulled open.")]
		public Collider RodCollider;

		[Tooltip("The trigger collider on the gun frame that detects the physical cylinder (Speedloader). Enabled only when the Rod is open.")]
		public Collider CylinderReloadTrigger;

		[Header("Cylinder Configuration")]
		public bool CylinderLoaded = true;

		public Transform ProxyCylinder;

		public bool DoesCylinderRotate = true;

		public bool IsCylinderRotClockwise = true;

		public int NumChambers = 6;

		public FVRFireArmChamber[] Chambers;

		public GameObject CylinderPrefab;

		public Transform CylinderMountPoint;

		[Header("Single Action Components")]
		public Transform Hammer;

		public Transform Trigger;

		public Transform HammerFanDir;

		[Header("Component Rotation Values")]
		public float Hammer_Rot_Uncocked = 0f;

		public float Hammer_Rot_Cocked = -49f;

		public float Trigger_Rot_Forward = 0f;

		public float Trigger_Rot_Rearward = 30f;

		public float TriggerThreshold = 0.9f;

		private float m_triggerFloat;

		private bool m_hasTriggerReset = true;

		private bool m_isHammerCocked = false;

		private bool m_isHammerCocking = false;

		private float m_hammerCockLerp;

		private float m_hammerCockSpeed = 10f;

		private bool m_hasTriggerCycled;

		private bool m_shouldRecock;

		private float m_triggerCurrentRot;

		private float lastTriggerRot;

		private int m_curChamber;

		private float m_tarChamberLerp;

		private float m_curChamberLerp;

		private bool m_lastLatchOpen;

		private bool m_lastRodOpen;

		private bool m_lastRodAtHome;

		private bool m_hasEjectedThisPull = false;

		public override void Awake()
		{
			((FVRFireArm)this).Awake();
			if (Chambers != null)
			{
				for (int i = 0; i < Chambers.Length; i++)
				{
					if ((Object)(object)Chambers[i] != (Object)null)
					{
						base.FChambers.Add(Chambers[i]);
					}
				}
			}
			if ((Object)(object)ProxyCylinder != (Object)null)
			{
				((Component)ProxyCylinder).gameObject.SetActive(CylinderLoaded);
			}
		}

		public override void FVRUpdate()
		{
			//IL_003c: 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)
			((FVRFireArm)this).FVRUpdate();
			if ((Object)(object)LatchTransform == (Object)null || (Object)(object)RodTransform == (Object)null)
			{
				return;
			}
			float value = GetValue(LatchTransform, LatchUsesRotation, LatchAxis);
			float value2 = GetValue(RodTransform, RodUsesRotation, RodAxis);
			bool flag = EvaluateState(value, LatchOpenThreshold, LatchOpenComparison);
			bool flag2 = EvaluateState(value2, RodOpenThreshold, RodOpenComparison);
			bool flag3 = EvaluateState(value2, RodClosedThreshold, RodClosedComparison);
			if (DebugLogging)
			{
				if (flag != m_lastLatchOpen)
				{
					m_lastLatchOpen = flag;
					Debug.Log((object)("Remington1858: Latch Open State Changed to: " + flag + " (Value: " + value + ")"));
				}
				if (flag2 != m_lastRodOpen)
				{
					m_lastRodOpen = flag2;
					Debug.Log((object)("Remington1858: Rod Open State Changed to: " + flag2 + " (Value: " + value2 + ")"));
				}
				if (flag3 != m_lastRodAtHome)
				{
					m_lastRodAtHome = flag3;
					Debug.Log((object)("Remington1858: Rod At Home State Changed to: " + flag3 + " (Value: " + value2 + ")"));
				}
			}
			if (flag)
			{
				if ((Object)(object)RodCollider != (Object)null && !RodCollider.enabled)
				{
					RodCollider.enabled = true;
					LogDebug("Latch is open. Rod is now unlocked.");
				}
			}
			else if (flag3 && (Object)(object)RodCollider != (Object)null && RodCollider.enabled)
			{
				RodCollider.enabled = false;
				LogDebug("Latch is closed. Rod is now locked.");
			}
			if ((Object)(object)CylinderReloadTrigger != (Object)null && CylinderReloadTrigger.enabled != flag2)
			{
				CylinderReloadTrigger.enabled = flag2;
			}
			if (flag2)
			{
				if (CylinderLoaded && !m_hasEjectedThisPull)
				{
					PerformCylinderEjection();
					m_hasEjectedThisPull = true;
				}
			}
			else
			{
				m_hasEjectedThisPull = false;
			}
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			//IL_001e: 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_007a: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			((FVRPhysicalObject)this).UpdateInteraction(hand);
			if (((FVRPhysicalObject)this).IsAltHeld)
			{
				return;
			}
			Vector2 touchpadAxes = hand.Input.TouchpadAxes;
			if (hand.IsInStreamlinedMode)
			{
				if (hand.Input.AXButtonDown && !m_isHammerCocked && !m_isHammerCocking)
				{
					CockHammer(10f);
				}
			}
			else if (hand.Input.TouchpadDown && Vector2.Angle(touchpadAxes, Vector2.down) < 45f && !m_isHammerCocked && !m_isHammerCocking)
			{
				CockHammer(5f);
			}
			if (((FVRInteractiveObject)this).IsHeld && !m_isHammerCocked && !m_isHammerCocking && (Object)(object)hand.OtherHand != (Object)null)
			{
				Vector3 velLinearWorld = hand.OtherHand.Input.VelLinearWorld;
				float num = Vector3.Distance(hand.OtherHand.PalmTransform.position, HammerFanDir.position);
				if (num < 0.15f && Vector3.Angle(velLinearWorld, HammerFanDir.forward) < 60f && ((Vector3)(ref velLinearWorld)).magnitude > 1f)
				{
					CockHammer(10f);
				}
			}
			UpdateTriggerHammer();
			UpdateCylinderRot();
		}

		private void CockHammer(float speed)
		{
			if (!m_isHammerCocked && !m_isHammerCocking)
			{
				m_hammerCockSpeed = speed;
				m_isHammerCocking = true;
				((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)7, 1f);
			}
		}

		private void DropHammer()
		{
			if (m_isHammerCocked)
			{
				m_isHammerCocked = false;
				m_isHammerCocking = false;
				m_hammerCockLerp = 0f;
				((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)6, 1f);
				TryFireActiveChamber();
			}
		}

		private void TryFireActiveChamber()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (CylinderLoaded && Chambers[m_curChamber].IsFull && !Chambers[m_curChamber].IsSpent)
			{
				Chambers[m_curChamber].Fire();
				FVRFireArmChamber val = Chambers[m_curChamber];
				Transform muzzle = ((FVRFireArm)this).GetMuzzle();
				((FVRFireArm)this).Fire(val, muzzle, true, 1f, -1f);
				((FVRFireArm)this).FireMuzzleSmoke();
				bool flag = ((FVRFireArm)this).IsTwoHandStabilized();
				bool flag2 = (Object)(object)((FVRPhysicalObject)this).AltGrip != (Object)null;
				bool flag3 = ((FVRFireArm)this).IsShoulderStabilized();
				((FVRFireArm)this).Recoil(flag, flag2, flag3, (FVRFireArmRecoilProfile)null, 1f);
				((FVRFireArm)this).PlayAudioGunShot(val.GetRound(), GM.CurrentPlayerBody.GetCurrentSoundEnvironment(), 1f);
				if (GM.CurrentSceneSettings.IsAmmoInfinite || GM.CurrentPlayerBody.IsInfiniteAmmo)
				{
					val.IsSpent = false;
					val.UpdateProxyDisplay();
				}
				else
				{
					val.SetRound((FVRFireArmRound)null, false);
				}
			}
		}

		private void UpdateTriggerHammer()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if (m_isHammerCocking)
			{
				if (m_hammerCockLerp < 1f)
				{
					m_hammerCockLerp += Time.deltaTime * m_hammerCockSpeed;
				}
				else
				{
					m_hammerCockLerp = 1f;
					m_isHammerCocking = false;
					m_isHammerCocked = true;
					if (IsCylinderRotClockwise)
					{
						m_curChamber = (m_curChamber + 1) % NumChambers;
					}
					else
					{
						m_curChamber--;
						if (m_curChamber < 0)
						{
							m_curChamber = NumChambers - 1;
						}
					}
					m_curChamberLerp = 0f;
					m_tarChamberLerp = 0f;
				}
			}
			if ((Object)(object)Hammer != (Object)null)
			{
				Hammer.localEulerAngles = new Vector3(Mathf.Lerp(Hammer_Rot_Uncocked, Hammer_Rot_Cocked, m_hammerCockLerp), 0f, 0f);
			}
			m_triggerFloat = 0f;
			if (((FVRInteractiveObject)this).m_hasTriggeredUpSinceBegin)
			{
				m_triggerFloat = ((FVRInteractiveObject)this).m_hand.Input.TriggerFloat;
			}
			if ((Object)(object)Trigger != (Object)null)
			{
				Trigger.localEulerAngles = new Vector3(Mathf.Lerp(Trigger_Rot_Forward, Trigger_Rot_Rearward, m_triggerFloat), 0f, 0f);
			}
			if (m_triggerFloat > TriggerThreshold)
			{
				DropHammer();
			}
		}

		private void UpdateCylinderRot()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (m_isHammerCocking)
			{
				m_tarChamberLerp = m_hammerCockLerp;
			}
			else
			{
				m_tarChamberLerp = 0f;
			}
			m_curChamberLerp = Mathf.Lerp(m_curChamberLerp, m_tarChamberLerp, Time.deltaTime * 16f);
			int cylinder = ((!IsCylinderRotClockwise) ? ((m_curChamber - 1) % NumChambers) : ((m_curChamber + 1) % NumChambers));
			if (DoesCylinderRotate && (Object)(object)ProxyCylinder != (Object)null)
			{
				ProxyCylinder.localRotation = Quaternion.Slerp(GetLocalRotationFromCylinder(m_curChamber), GetLocalRotationFromCylinder(cylinder), m_curChamberLerp);
			}
		}

		public bool LoadCylinder(Speedloader s)
		{
			//IL_0056: 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)
			if (CylinderLoaded || (Object)(object)s == (Object)null)
			{
				return false;
			}
			CylinderLoaded = true;
			if ((Object)(object)ProxyCylinder != (Object)null)
			{
				((Component)ProxyCylinder).gameObject.SetActive(true);
				ProxyCylinder.localRotation = GetLocalRotationFromCylinder(m_curChamber);
			}
			((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)20, 1f);
			m_curChamber = 0;
			for (int i = 0; i < Chambers.Length; i++)
			{
				if (i < s.Chambers.Count && s.Chambers[i].IsLoaded)
				{
					Chambers[i].Autochamber(s.Chambers[i].LoadedClass);
					Chambers[i].IsSpent = s.Chambers[i].IsSpent;
				}
				else
				{
					Chambers[i].Unload();
				}
				Chambers[i].UpdateProxyDisplay();
			}
			return true;
		}

		public void PerformCylinderEjection()
		{
			//IL_003f: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)CylinderPrefab == (Object)null || (Object)(object)CylinderMountPoint == (Object)null)
			{
				return;
			}
			LogDebug("Auto-ejecting cylinder...");
			GameObject val = Object.Instantiate<GameObject>(CylinderPrefab, CylinderMountPoint.position, CylinderMountPoint.rotation);
			Speedloader component = val.GetComponent<Speedloader>();
			((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)21, 1f);
			Rigidbody component2 = val.GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.velocity = -((Component)this).transform.forward * 0.5f;
			}
			for (int i = 0; i < component.Chambers.Count; i++)
			{
				if (i < Chambers.Length)
				{
					if (!Chambers[i].IsFull)
					{
						component.Chambers[i].Unload();
					}
					else
					{
						component.Chambers[i].Load(Chambers[i].GetRound().RoundClass, false);
						component.Chambers[i].IsSpent = Chambers[i].IsSpent;
					}
					Chambers[i].SetRound((FVRFireArmRound)null, false);
					Chambers[i].UpdateProxyDisplay();
				}
				component.Chambers[i].UpdateViz();
			}
			CylinderLoaded = false;
			if ((Object)(object)ProxyCylinder != (Object)null)
			{
				((Component)ProxyCylinder).gameObject.SetActive(false);
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			float value = GetValue(RodTransform, RodUsesRotation, RodAxis);
			bool flag = EvaluateState(value, RodOpenThreshold, RodOpenComparison);
			if (CylinderLoaded || !flag)
			{
				return;
			}
			Speedloader component = ((Component)other).GetComponent<Speedloader>();
			if ((Object)(object)component == (Object)null && (Object)(object)other.attachedRigidbody != (Object)null)
			{
				component = ((Component)other.attachedRigidbody).GetComponent<Speedloader>();
			}
			if ((Object)(object)component != (Object)null && component.Chambers[0].Type == base.RoundType)
			{
				if (((FVRInteractiveObject)component).IsHeld)
				{
					((FVRInteractiveObject)component).EndInteraction(((FVRInteractiveObject)component).m_hand);
				}
				LoadCylinder(component);
				Object.Destroy((Object)(object)((Component)component).gameObject);
			}
		}

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

		public override void SetLoadedChambers(List<FireArmRoundClass> rounds)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (rounds.Count <= 0)
			{
				return;
			}
			for (int i = 0; i < Chambers.Length; i++)
			{
				if (i < rounds.Count)
				{
					Chambers[i].Autochamber(rounds[i]);
				}
			}
		}

		public Quaternion GetLocalRotationFromCylinder(int cylinder)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)cylinder * (360f / (float)NumChambers) * -1f;
			num = Mathf.Repeat(num, 360f);
			return Quaternion.Euler(new Vector3(0f, 0f, num));
		}

		private float GetValue(Transform t, bool usesRotation, Axis axis)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			if ((Object)(object)t == (Object)null)
			{
				return 0f;
			}
			Vector3 val = ((!usesRotation) ? t.localPosition : t.localEulerAngles);
			float num = 0f;
			if ((int)axis != 0)
			{
				if ((int)axis != 1)
				{
					if ((int)axis == 2)
					{
						num = val.z;
					}
				}
				else
				{
					num = val.y;
				}
			}
			else
			{
				num = val.x;
			}
			if (usesRotation && num > 180f)
			{
				num -= 360f;
			}
			return num;
		}

		private bool EvaluateState(float value, float threshold, ComparisonType comp)
		{
			return comp switch
			{
				ComparisonType.GreaterThan => value > threshold, 
				ComparisonType.LessThan => value < threshold, 
				ComparisonType.EqualTo => Mathf.Abs(value - threshold) <= 0.01f, 
				_ => false, 
			};
		}

		private void LogDebug(string message)
		{
			if (DebugLogging)
			{
				Debug.Log((object)("Remington1858: " + message));
			}
		}
	}
}
public class RemingtonCylinderController : MonoBehaviour
{
	public enum ComparisonType
	{
		GreaterThan,
		LessThan,
		EqualTo
	}

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

	[Header("Core Weapon Reference")]
	public Revolver Weapon;

	[Header("Latch Configuration")]
	[Tooltip("The Transform representing the latch's moving mesh.")]
	public Transform LatchTransform;

	public bool LatchUsesRotation = true;

	public Axis LatchAxis = (Axis)0;

	public ComparisonType LatchOpenComparison = ComparisonType.GreaterThan;

	public float LatchOpenThreshold = 15f;

	[Header("Rod Configuration")]
	[Tooltip("The Transform representing the rod/pin's moving mesh.")]
	public Transform RodTransform;

	public bool RodUsesRotation = false;

	public Axis RodAxis = (Axis)2;

	public ComparisonType RodOpenComparison = ComparisonType.GreaterThan;

	public float RodOpenThreshold = 0.08f;

	public ComparisonType RodClosedComparison = ComparisonType.LessThan;

	public float RodClosedThreshold = 0.02f;

	[Header("Colliders to Control")]
	[Tooltip("The grab collider on the loading rod. Locked until the Latch is pulled open.")]
	public Collider RodCollider;

	[Header("Cylinder Spawn Configuration")]
	[Tooltip("The Item ID of your spare cylinder in the item database (IM.OD).")]
	public string DefaultCylinderPrefabID;

	[Header("Current State Tracker")]
	public bool IsCylinderLoaded = true;

	private FieldInfo m_isCylinderArmLockedField;

	private FieldInfo m_wasCylinderArmLockedField;

	private FieldInfo m_hasEjectedSinceOpeningField;

	private FieldInfo m_isCylinderReleasePressedField;

	private bool m_lastLatchOpen;

	private bool m_lastRodOpen;

	private bool m_lastRodAtHome;

	private bool m_hasEjectedThisPull = false;

	private void Start()
	{
		if ((Object)(object)Weapon == (Object)null)
		{
			Weapon = ((Component)this).GetComponent<Revolver>();
		}
		if ((Object)(object)Weapon != (Object)null)
		{
			try
			{
				m_isCylinderArmLockedField = typeof(Revolver).GetField("m_isCylinderArmLocked", BindingFlags.Instance | BindingFlags.NonPublic);
				m_wasCylinderArmLockedField = typeof(Revolver).GetField("m_wasCylinderArmLocked", BindingFlags.Instance | BindingFlags.NonPublic);
				m_hasEjectedSinceOpeningField = typeof(Revolver).GetField("m_hasEjectedSinceOpening", BindingFlags.Instance | BindingFlags.NonPublic);
				m_isCylinderReleasePressedField = typeof(Revolver).GetField("m_isCylinderReleasePressed", BindingFlags.Instance | BindingFlags.NonPublic);
				LogDebug("Successfully bound reflection fields for Revolver states.");
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("RemingtonCylinderController: Failed to bind reflection fields! " + ex.Message));
			}
		}
	}

	private void Update()
	{
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Weapon == (Object)null || (Object)(object)LatchTransform == (Object)null || (Object)(object)RodTransform == (Object)null)
		{
			return;
		}
		if ((object)m_isCylinderReleasePressedField != null)
		{
			m_isCylinderReleasePressedField.SetValue(Weapon, false);
		}
		if (!IsCylinderLoaded && (Object)(object)Weapon.Cylinder != (Object)null && Weapon.Cylinder.HasSpeedLoadedIn)
		{
			IsCylinderLoaded = true;
			if ((object)m_isCylinderArmLockedField != null && (object)m_wasCylinderArmLockedField != null && (object)m_hasEjectedSinceOpeningField != null)
			{
				m_isCylinderArmLockedField.SetValue(Weapon, true);
				m_wasCylinderArmLockedField.SetValue(Weapon, true);
				m_hasEjectedSinceOpeningField.SetValue(Weapon, false);
				if ((Object)(object)Weapon.CylinderArm != (Object)null)
				{
					Weapon.CylinderArm.localEulerAngles = Vector3.zero;
				}
				((Component)Weapon.Cylinder).transform.localRotation = Quaternion.identity;
				SetChambersAccessible(accessible: false);
				LogDebug("Cylinder inserted. Instantly locked and aligned.");
			}
		}
		float value = GetValue(LatchTransform, LatchUsesRotation, LatchAxis);
		float value2 = GetValue(RodTransform, RodUsesRotation, RodAxis);
		bool flag = EvaluateState(value, LatchOpenThreshold, LatchOpenComparison);
		bool flag2 = EvaluateState(value2, RodOpenThreshold, RodOpenComparison);
		bool flag3 = EvaluateState(value2, RodClosedThreshold, RodClosedComparison);
		if (DebugLogging)
		{
			if (flag != m_lastLatchOpen)
			{
				m_lastLatchOpen = flag;
				Debug.Log((object)("RemingtonCylinderController: Latch Open State Changed to: " + flag + " (Value: " + value + ")"));
			}
			if (flag2 != m_lastRodOpen)
			{
				m_lastRodOpen = flag2;
				Debug.Log((object)("RemingtonCylinderController: Rod Open State Changed to: " + flag2 + " (Value: " + value2 + ")"));
			}
			if (flag3 != m_lastRodAtHome)
			{
				m_lastRodAtHome = flag3;
				Debug.Log((object)("RemingtonCylinderController: Rod At Home State Changed to: " + flag3 + " (Value: " + value2 + ")"));
			}
		}
		if (flag)
		{
			if ((Object)(object)RodCollider != (Object)null && !RodCollider.enabled)
			{
				RodCollider.enabled = true;
				LogDebug("Latch is open. Rod is now unlocked.");
			}
		}
		else if (flag3 && (Object)(object)RodCollider != (Object)null && RodCollider.enabled)
		{
			RodCollider.enabled = false;
			LogDebug("Latch is closed. Rod is now locked.");
		}
		if (flag2)
		{
			if (IsCylinderLoaded && !m_hasEjectedThisPull)
			{
				PerformCylinderEjection();
				m_hasEjectedThisPull = true;
			}
		}
		else
		{
			m_hasEjectedThisPull = false;
		}
	}

	private void PerformCylinderEjection()
	{
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Weapon == (Object)null || (Object)(object)Weapon.Cylinder == (Object)null)
		{
			return;
		}
		LogDebug("Rod opened. Auto-ejecting cylinder...");
		if (string.IsNullOrEmpty(Weapon.Cylinder.SpeedLoaderID))
		{
			Weapon.Cylinder.SpeedLoaderID = DefaultCylinderPrefabID;
		}
		if ((object)m_isCylinderArmLockedField != null && (object)m_wasCylinderArmLockedField != null && (object)m_hasEjectedSinceOpeningField != null)
		{
			m_isCylinderArmLockedField.SetValue(Weapon, false);
			m_wasCylinderArmLockedField.SetValue(Weapon, false);
			m_hasEjectedSinceOpeningField.SetValue(Weapon, true);
			if ((Object)(object)Weapon.CylinderArm != (Object)null)
			{
				Weapon.CylinderArm.localEulerAngles = new Vector3(0f, 0f, 45f);
			}
			SetChambersAccessible(accessible: true);
		}
		Weapon.EjectChambers();
		IsCylinderLoaded = false;
	}

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

	private float GetValue(Transform t, bool usesRotation, Axis axis)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Invalid comparison between Unknown and I4
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Invalid comparison between Unknown and I4
		if ((Object)(object)t == (Object)null)
		{
			return 0f;
		}
		Vector3 val = ((!usesRotation) ? t.localPosition : t.localEulerAngles);
		float num = 0f;
		if ((int)axis != 0)
		{
			if ((int)axis != 1)
			{
				if ((int)axis == 2)
				{
					num = val.z;
				}
			}
			else
			{
				num = val.y;
			}
		}
		else
		{
			num = val.x;
		}
		if (usesRotation && num > 180f)
		{
			num -= 360f;
		}
		return num;
	}

	private bool EvaluateState(float value, float threshold, ComparisonType comp)
	{
		return comp switch
		{
			ComparisonType.GreaterThan => value > threshold, 
			ComparisonType.LessThan => value < threshold, 
			ComparisonType.EqualTo => Mathf.Abs(value - threshold) <= 0.01f, 
			_ => false, 
		};
	}

	private void LogDebug(string message)
	{
		if (DebugLogging)
		{
			Debug.Log((object)("RemingtonCylinderController: " + message));
		}
	}
}
public class SARevolverWithCylinderChange : RevolvingShotgun
{
	[Header("Debug Settings")]
	[Tooltip("Enables diagnostic telemetry logging in the Unity console.")]
	public bool EnableDebugLogging = false;

	[Header("Physical Transforms")]
	[Tooltip("The loading lever or cylinder pin transform that slides forward and rearward.")]
	public Transform EjectorRod;

	[Tooltip("The grab collider on the ejector rod. If unassigned, will be searched automatically.")]
	public Collider EjectorRodCollider;

	[Tooltip("The locking latch transform that rotates open and closed.")]
	public Transform CylinderLatch;

	[Tooltip("The grab collider on the cylinder latch. If unassigned, will be searched automatically.")]
	public Collider CylinderLatchCollider;

	[Tooltip("The GameObject or RevolvingShotgunTrigger collider that the player grabs to eject the cylinder.")]
	public GameObject CylinderEjectTrigger;

	[Tooltip("Optional explicit reload well trigger GameObject tagged FVRFireArmReloadTriggerWell.")]
	public GameObject CylinderLoadTrigger;

	[Header("Single Action Configuration")]
	[Tooltip("Transform representing the hammer component.")]
	public Transform Hammer;

	[Tooltip("Transform used for offhand palm fanning detection. Palm must move across this forward vector.")]
	public Transform HammerFanDir;

	[Tooltip("Pivot transform used when spinning the revolver around the trigger guard.")]
	public Transform PoseSpinHolder;

	[Tooltip("Allows the weapon to be spun around the trigger finger.")]
	public bool CanSpin = true;

	[Tooltip("Time in seconds the trigger must be held while uncocked to initiate a gun spin.")]
	public float TriggerSpinHoldTime = 0.5f;

	[Tooltip("Rotation angle of the hammer when fully uncocked and resting on a chamber.")]
	public float Hammer_Rot_Uncocked = 0f;

	[Tooltip("Rotation angle of the hammer when held at half-cock for safety and loading.")]
	public float Hammer_Rot_Halfcocked = -35f;

	[Tooltip("Rotation angle of the hammer when fully cocked and ready to fire.")]
	public float Hammer_Rot_Cocked = -75f;

	[Tooltip("Trigger pull threshold required to drop the hammer.")]
	public float TriggerThreshold = 0.9f;

	[Tooltip("If true, the hammer must be strictly at half-cock to eject or insert a cylinder.")]
	public bool RequireHalfCockToReload = true;

	[Header("Decocking Settings")]
	[Tooltip("Time in seconds the decock input must be held to ease the hammer down to uncocked.")]
	public float DecockHoldTime = 0.4f;

	[Tooltip("Speed in degrees per second at which the hammer visually lowers when eased down.")]
	public float DecockEaseSpeed = 120f;

	[Header("Spinning Audio Configuration")]
	[Tooltip("Custom audio clip played once per full revolution while spinning (whoosh sound).")]
	public AudioClip SpinAudioClip;

	[Tooltip("Volume multiplier for the spinning whoosh sound.")]
	public float SpinAudioMaxVolume = 0.8f;

	[Header("Percussion Cap Sparks")]
	[Tooltip("Particle system emitted at the hammer/nipple recess when the hammer strikes.")]
	public ParticleSystem PSystem_CapSparks;

	[Tooltip("Number of spark particles emitted per cap strike.")]
	public int CapSparksEmitCount = 15;

	[Header("Fallback Thresholds")]
	[Tooltip("Fallback local position of the ejector rod when forward.")]
	public Vector3 EjectorRod_Pos_Forward;

	[Tooltip("Fallback local position of the ejector rod when rearward.")]
	public Vector3 EjectorRod_Pos_Rearward;

	[Tooltip("Allowed distance tolerance in meters for fallback rod position checks.")]
	public float RodDistanceTolerance = 0.02f;

	[Tooltip("Fallback local X Euler angle of the latch when locked shut.")]
	public float Latch_Rot_Closed = 0f;

	[Tooltip("Fallback local X Euler angle of the latch when rotated open.")]
	public float Latch_Rot_Open = 75f;

	[Tooltip("Allowed angle tolerance in degrees for fallback latch angle checks.")]
	public float LatchAngleTolerance = 10f;

	[Tooltip("Angular velocity required on controller flick to pop the cylinder out when unlatched.")]
	public float FlickEjectThreshold = 12f;

	[Tooltip("If true, the revolver cannot discharge from being dropped on an uncocked hammer.")]
	public bool HasTransferBarSafety = false;

	[Header("Real-Time Status Indicators")]
	[Tooltip("Displays whether the script detects the latch as open.")]
	public bool Status_IsLatchOpen;

	[Tooltip("Displays whether the script detects the latch as closed.")]
	public bool Status_IsLatchClosed;

	[Tooltip("Displays whether the script detects the rod as forward.")]
	public bool Status_IsRodForward;

	[Tooltip("Displays whether the script permits reloading and ejecting.")]
	public bool Status_CanReload;

	private Quaternion m_storedSpinHolderRot;

	private bool m_isSpinning;

	private bool m_isHammerCocking;

	private bool m_isHammerCocked;

	private bool m_isHalfCocked;

	private bool m_isEasingDown;

	private bool m_isTriggerSpinning;

	private float m_hammerCurrentAngle;

	private float m_hammerCockLerp;

	private float m_hammerCockSpeed = 10f;

	private float m_decockHoldTimer;

	private float m_triggerSpinHoldTimer;

	private float m_triggerFloat;

	private float m_xSpinRot;

	private float m_xSpinVel;

	private float m_timeSinceColFire = 3f;

	private float m_debugLogTimer;

	private bool m_spinAudioTriggeredThisRev;

	private FVRFoldingStockXAxis m_latchStockScript;

	private MovableObjectPart m_rodMovablePart;

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

	private AudioSource m_spinAudioSource;

	public override void Awake()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		((RevolvingShotgun)this).Awake();
		base.DoesCylinderRotate = false;
		base.m_isHammerLocked = false;
		base.m_shouldRecock = false;
		base.DoesFiringRecock = false;
		FireSelectorMode val = new FireSelectorMode();
		val.ModeType = (FireSelectorModeType)0;
		val.SelectorPosition = 0f;
		base.FireSelector_Modes = (FireSelectorMode[])(object)new FireSelectorMode[1] { val };
		base.m_fireSelectorMode = 0;
		if ((Object)(object)CylinderLatch != (Object)null)
		{
			m_latchStockScript = ((Component)CylinderLatch).GetComponent<FVRFoldingStockXAxis>();
			if ((Object)(object)m_latchStockScript == (Object)null)
			{
				m_latchStockScript = ((Component)CylinderLatch).GetComponentInParent<FVRFoldingStockXAxis>();
			}
			if ((Object)(object)m_latchStockScript == (Object)null)
			{
				m_latchStockScript = ((Component)CylinderLatch).GetComponentInChildren<FVRFoldingStockXAxis>();
			}
			if ((Object)(object)CylinderLatchCollider == (Object)null)
			{
				CylinderLatchCollider = ((Component)CylinderLatch).GetComponent<Collider>();
				if ((Object)(object)CylinderLatchCollider == (Object)null)
				{
					CylinderLatchCollider = ((Component)CylinderLatch).GetComponentInChildren<Collider>();
				}
			}
		}
		if ((Object)(object)EjectorRod != (Object)null)
		{
			m_rodMovablePart = ((Component)EjectorRod).GetComponent<MovableObjectPart>();
			if ((Object)(object)m_rodMovablePart == (Object)null)
			{
				m_rodMovablePart = ((Component)EjectorRod).GetComponentInParent<MovableObjectPart>();
			}
			if ((Object)(object)m_rodMovablePart == (Object)null)
			{
				m_rodMovablePart = ((Component)EjectorRod).GetComponentInChildren<MovableObjectPart>();
			}
			if ((Object)(object)EjectorRodCollider == (Object)null)
			{
				EjectorRodCollider = ((Component)EjectorRod).GetComponent<Collider>();
				if ((Object)(object)EjectorRodCollider == (Object)null)
				{
					EjectorRodCollider = ((Component)EjectorRod).GetComponentInChildren<Collider>();
				}
			}
		}
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if (((Component)componentsInChildren[i]).CompareTag("FVRFireArmReloadTriggerWell"))
			{
				m_cachedReloadWellColliders.Add(componentsInChildren[i]);
				if ((Object)(object)CylinderLoadTrigger == (Object)null)
				{
					CylinderLoadTrigger = ((Component)componentsInChildren[i]).gameObject;
				}
			}
		}
		if ((Object)(object)PoseSpinHolder != (Object)null)
		{
			m_storedSpinHolderRot = PoseSpinHolder.localRotation;
			m_spinAudioSource = ((Component)PoseSpinHolder).gameObject.AddComponent<AudioSource>();
			m_spinAudioSource.playOnAwake = false;
			m_spinAudioSource.loop = false;
			m_spinAudioSource.spatialBlend = 1f;
			m_spinAudioSource.minDistance = 0.5f;
			m_spinAudioSource.maxDistance = 15f;
			m_spinAudioSource.clip = SpinAudioClip;
		}
		m_hammerCurrentAngle = Hammer_Rot_Uncocked;
	}

	public override void FVRUpdate()
	{
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		((RevolvingShotgun)this).FVRUpdate();
		bool flag = IsLatchOpen();
		bool flag2 = IsLatchClosed();
		bool flag3 = IsRodForward();
		bool flag4 = IsRodRearward();
		bool flag5 = CheckReloadConditions();
		bool flag6 = !flag2 || flag3;
		bool flag7 = flag4;
		Status_IsLatchOpen = flag;
		Status_IsLatchClosed = flag2;
		Status_IsRodForward = flag3;
		Status_CanReload = flag5;
		if (!flag5)
		{
			((FVRFireArm)this).EjectDelay = 0.5f;
		}
		if ((Object)(object)CylinderLatchCollider != (Object)null && CylinderLatchCollider.enabled != flag7)
		{
			CylinderLatchCollider.enabled = flag7;
		}
		if ((Object)(object)EjectorRodCollider != (Object)null && EjectorRodCollider.enabled != flag6)
		{
			EjectorRodCollider.enabled = flag6;
		}
		if (!base.CylinderLoaded && base.Chambers != null)
		{
			for (int i = 0; i < base.Chambers.Length; i++)
			{
				if ((Object)(object)base.Chambers[i] != (Object)null && base.Chambers[i].IsFull)
				{
					base.Chambers[i].Unload();
					base.Chambers[i].UpdateProxyDisplay();
				}
			}
		}
		for (int j = 0; j < m_cachedReloadWellColliders.Count; j++)
		{
			if ((Object)(object)m_cachedReloadWellColliders[j] != (Object)null && m_cachedReloadWellColliders[j].enabled != flag5)
			{
				m_cachedReloadWellColliders[j].enabled = flag5;
			}
		}
		if ((Object)(object)CylinderLoadTrigger != (Object)null && CylinderLoadTrigger.activeSelf != flag5)
		{
			CylinderLoadTrigger.SetActive(flag5);
		}
		if ((Object)(object)CylinderEjectTrigger != (Object)null && CylinderEjectTrigger.activeSelf != flag5)
		{
			CylinderEjectTrigger.SetActive(flag5);
		}
		if (EnableDebugLogging)
		{
			m_debugLogTimer += Time.deltaTime;
			if (m_debugLogTimer >= 0.75f)
			{
				m_debugLogTimer = 0f;
				string text = ((!((Object)(object)m_latchStockScript != (Object)null)) ? "NoScript" : ((object)Unsafe.As<StockPos, StockPos>(ref m_latchStockScript.m_curPos)/*cast due to .constrained prefix*/).ToString());
				float num = ((!((Object)(object)CylinderLatch != (Object)null)) ? (-999f) : CylinderLatch.localEulerAngles.x);
				string text2 = ((!((Object)(object)m_rodMovablePart != (Object)null)) ? "NoScript" : ((object)Unsafe.As<E_State, E_State>(ref m_rodMovablePart.State)/*cast due to .constrained prefix*/).ToString());
				bool flag8 = (Object)(object)EjectorRodCollider != (Object)null && EjectorRodCollider.enabled;
				bool flag9 = (Object)(object)CylinderLatchCollider != (Object)null && CylinderLatchCollider.enabled;
				Debug.Log((object)$"[SARevolver] LatchClosed:{flag2} | LatchOpen:{flag} | StockPos:{text} | LatchX:{num:F1} | LatchCol:{flag9} | RodUnlocked:{flag6} | RodCol:{flag8} | RodForward:{flag3} | RodState:{text2} | HalfCock:{m_isHalfCocked} | CanReload:{flag5}");
			}
		}
	}

	public override void FVRFixedUpdate()
	{
		((FVRFireArm)this).FVRFixedUpdate();
		UpdateSpinning();
		if (m_timeSinceColFire < 3f)
		{
			m_timeSinceColFire += Time.deltaTime;
		}
	}

	public override void UpdateInteraction(FVRViveHand hand)
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0366: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		base.m_isHammerLocked = false;
		base.m_shouldRecock = false;
		((RevolvingShotgun)this).UpdateInteraction(hand);
		bool flag = false;
		if (!((FVRPhysicalObject)this).IsAltHeld)
		{
			bool flag2 = false;
			bool flag3 = false;
			if (hand.IsInStreamlinedMode)
			{
				if (hand.Input.AXButtonDown)
				{
					CockHammer(5f);
				}
				if (hand.Input.TouchpadPressed)
				{
					flag = true;
				}
				flag2 = hand.Input.BYButtonPressed;
				flag3 = hand.Input.BYButtonDown;
			}
			else
			{
				if (hand.Input.TouchpadPressed && Vector2.Angle(hand.Input.TouchpadAxes, Vector2.up) < 45f)
				{
					flag = true;
				}
				if (hand.Input.TouchpadDown && Vector2.Angle(hand.Input.TouchpadAxes, Vector2.down) < 45f)
				{
					CockHammer(5f);
				}
				flag2 = hand.Input.TouchpadPressed && Vector2.Angle(hand.Input.TouchpadAxes, Vector2.left) < 45f;
				flag3 = hand.Input.TouchpadDown && Vector2.Angle(hand.Input.TouchpadAxes, Vector2.left) < 45f;
			}
			if (!m_isHalfCocked && !m_isHammerCocked && !m_isHammerCocking && !m_isEasingDown)
			{
				if (hand.Input.TriggerFloat > 0.5f)
				{
					m_triggerSpinHoldTimer += Time.deltaTime;
					if (m_triggerSpinHoldTimer >= TriggerSpinHoldTime)
					{
						m_isTriggerSpinning = true;
					}
				}
				else
				{
					m_triggerSpinHoldTimer = 0f;
					m_isTriggerSpinning = false;
				}
			}
			else
			{
				m_triggerSpinHoldTimer = 0f;
				m_isTriggerSpinning = false;
			}
			m_isSpinning = (flag || m_isTriggerSpinning) && CanSpin;
			if (m_isSpinning)
			{
				SetHandControllerVisibility(hand, visible: false);
			}
			else
			{
				SetHandControllerVisibility(hand, visible: true);
			}
			if (!m_isHalfCocked && !m_isHammerCocked && !m_isEasingDown)
			{
				if (flag3)
				{
					EngageHalfCock();
				}
				m_decockHoldTimer = 0f;
			}
			else if (m_isHalfCocked || m_isHammerCocked)
			{
				if (flag2)
				{
					m_decockHoldTimer += Time.deltaTime;
					if (m_decockHoldTimer >= DecockHoldTime)
					{
						InitiateEaseDown();
					}
				}
				else
				{
					if (DecockHoldTime <= 0.05f && flag3)
					{
						InitiateEaseDown();
					}
					m_decockHoldTimer = 0f;
				}
			}
			if (base.CylinderLoaded && CheckReloadConditions() && ((Vector3)(ref hand.Input.VelAngularLocal)).magnitude > FlickEjectThreshold)
			{
				Speedloader val = ((RevolvingShotgun)this).EjectCylinder();
				if ((Object)(object)val != (Object)null && (Object)(object)((FVRPhysicalObject)val).RootRigidbody != (Object)null)
				{
					((FVRPhysicalObject)val).RootRigidbody.velocity = hand.Input.VelLinearWorld + ((Component)this).transform.right * 0.5f;
				}
			}
		}
		UpdateSAHammerAndTrigger();
		UpdateCylinderVisuals();
		if (!((FVRInteractiveObject)this).IsHeld)
		{
			m_isSpinning = false;
		}
	}

	public override void EndInteraction(FVRViveHand hand)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		m_triggerFloat = 0f;
		m_decockHoldTimer = 0f;
		m_triggerSpinHoldTimer = 0f;
		m_isTriggerSpinning = false;
		if (m_isHammerCocking && !m_isHammerCocked)
		{
			m_isHammerCocking = false;
			m_hammerCockLerp = 0f;
		}
		m_isSpinning = false;
		SetHandControllerVisibility(hand, visible: true);
		((FVRFireArm)this).EndInteraction(hand);
		if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
		{
			((FVRPhysicalObject)this).RootRigidbody.AddRelativeTorque(new Vector3(m_xSpinVel, 0f, 0f), (ForceMode)1);
		}
	}

	private void SetHandControllerVisibility(FVRViveHand hand, bool visible)
	{
		if ((Object)(object)hand == (Object)null)
		{
			return;
		}
		if (!visible)
		{
			if ((Object)(object)hand.Display_Controller != (Object)null)
			{
				hand.Display_Controller.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Quest2 != (Object)null)
			{
				hand.Display_Controller_Quest2.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Quest3 != (Object)null)
			{
				hand.Display_Controller_Quest3.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Touch != (Object)null)
			{
				hand.Display_Controller_Touch.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Index != (Object)null)
			{
				hand.Display_Controller_Index.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Vive != (Object)null)
			{
				hand.Display_Controller_Vive.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_WMR != (Object)null)
			{
				hand.Display_Controller_WMR.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_RiftS != (Object)null)
			{
				hand.Display_Controller_RiftS.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_Cosmos != (Object)null)
			{
				hand.Display_Controller_Cosmos.SetActive(false);
			}
			if ((Object)(object)hand.Display_Controller_HPR2 != (Object)null)
			{
				hand.Display_Controller_HPR2.SetActive(false);
			}
		}
		else
		{
			hand.UpdateControllerDefinition();
		}
	}

	private void UpdateSAHammerAndTrigger()
	{
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: 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_0081: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		if (((FVRInteractiveObject)this).IsHeld && !m_isHalfCocked && !m_isHammerCocked && !m_isHammerCocking && !m_isEasingDown && (Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null && (Object)(object)((FVRInteractiveObject)this).m_hand.OtherHand != (Object)null && (Object)(object)HammerFanDir != (Object)null)
		{
			Vector3 velLinearWorld = ((FVRInteractiveObject)this).m_hand.OtherHand.Input.VelLinearWorld;
			float num = Vector3.Distance(((FVRInteractiveObject)this).m_hand.OtherHand.PalmTransform.position, HammerFanDir.position);
			if (num < 0.15f && Vector3.Angle(velLinearWorld, HammerFanDir.forward) < 60f && ((Vector3)(ref velLinearWorld)).magnitude > 1f)
			{
				CockHammer(12f);
			}
		}
		if (m_isHammerCocking)
		{
			if (m_hammerCockLerp < 1f)
			{
				m_hammerCockLerp += Time.deltaTime * m_hammerCockSpeed;
			}
			else
			{
				m_hammerCockLerp = 1f;
				m_isHammerCocking = false;
				m_isHammerCocked = true;
				if (base.IsCylinderRotClockwise)
				{
					((RevolvingShotgun)this).CurChamber = ((RevolvingShotgun)this).CurChamber + 1;
				}
				else
				{
					((RevolvingShotgun)this).CurChamber = ((RevolvingShotgun)this).CurChamber - 1;
				}
			}
		}
		if ((Object)(object)Hammer != (Object)null)
		{
			if (m_isEasingDown)
			{
				m_hammerCurrentAngle = Mathf.MoveTowards(m_hammerCurrentAngle, Hammer_Rot_Uncocked, Time.deltaTime * DecockEaseSpeed);
				Hammer.localEulerAngles = new Vector3(m_hammerCurrentAngle, 0f, 0f);
				if (Mathf.Abs(m_hammerCurrentAngle - Hammer_Rot_Uncocked) < 0.5f)
				{
					m_hammerCurrentAngle = Hammer_Rot_Uncocked;
					Hammer.localEulerAngles = new Vector3(Hammer_Rot_Uncocked, 0f, 0f);
					m_isEasingDown = false;
					((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)6, 0.6f);
				}
			}
			else if (m_isHalfCocked)
			{
				m_hammerCurrentAngle = Hammer_Rot_Halfcocked;
				Hammer.localEulerAngles = new Vector3(Hammer_Rot_Halfcocked, 0f, 0f);
			}
			else
			{
				m_hammerCurrentAngle = Mathf.Lerp(Hammer_Rot_Uncocked, Hammer_Rot_Cocked, m_hammerCockLerp);
				Hammer.localEulerAngles = new Vector3(m_hammerCurrentAngle, 0f, 0f);
			}
		}
		m_triggerFloat = 0f;
		if (((FVRInteractiveObject)this).m_hasTriggeredUpSinceBegin && !m_isSpinning && !m_isHalfCocked && !m_isEasingDown && (Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
		{
			m_triggerFloat = ((FVRInteractiveObject)this).m_hand.Input.TriggerFloat;
		}
		if ((Object)(object)base.Trigger != (Object)null)
		{
			float num2 = Mathf.Lerp(base.Trigger_ForwardValue, base.Trigger_RearwardValue, m_triggerFloat);
			base.Trigger.localEulerAngles = new Vector3(num2, 0f, 0f);
		}
		if (m_triggerFloat > TriggerThreshold && m_isHammerCocked)
		{
			DropHammer();
		}
	}

	private void UpdateCylinderVisuals()
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		float num = ((!m_isHammerCocking) ? 0f : m_hammerCockLerp);
		int num2 = ((!base.IsCylinderRotClockwise) ? ((((RevolvingShotgun)this).CurChamber - 1 + base.NumChambers) % base.NumChambers) : ((((RevolvingShotgun)this).CurChamber + 1) % base.NumChambers));
		if ((Object)(object)base.ProxyCylinder != (Object)null && base.CylinderLoaded)
		{
			base.ProxyCylinder.localRotation = Quaternion.Slerp(((RevolvingShotgun)this).GetLocalRotationFromCylinder(((RevolvingShotgun)this).CurChamber), ((RevolvingShotgun)this).GetLocalRotationFromCylinder(num2), num);
		}
	}

	public void DropHammer()
	{
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		if (!m_isHammerCocked || !CheckFiringConditions())
		{
			return;
		}
		m_isHammerCocked = false;
		m_isHammerCocking = false;
		m_hammerCockLerp = 0f;
		((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)6, 1f);
		if (base.CylinderLoaded && base.Chambers != null && ((RevolvingShotgun)this).CurChamber >= 0 && ((RevolvingShotgun)this).CurChamber < base.Chambers.Length && base.Chambers[((RevolvingShotgun)this).CurChamber].Fire())
		{
			if ((Object)(object)PSystem_CapSparks != (Object)null && CapSparksEmitCount > 0)
			{
				PSystem_CapSparks.Emit(CapSparksEmitCount);
			}
			FVRFireArmChamber val = base.Chambers[((RevolvingShotgun)this).CurChamber];
			Transform val2 = ((!base.UsesMultipleMuzzles || base.Muzzles == null || ((RevolvingShotgun)this).CurChamber >= base.Muzzles.Count) ? ((FVRFireArm)this).GetMuzzle() : base.Muzzles[((RevolvingShotgun)this).CurChamber]);
			((FVRFireArm)this).Fire(val, val2, true, 1f, -1f);
			((FVRFireArm)this).FireMuzzleSmoke();
			bool flag = ((FVRFireArm)this).IsTwoHandStabilized();
			bool flag2 = (Object)(object)((FVRPhysicalObject)this).AltGrip != (Object)null;
			bool flag3 = ((FVRFireArm)this).IsShoulderStabilized();
			((FVRFireArm)this).Recoil(flag, flag2, flag3, (FVRFireArmRecoilProfile)null, 1f);
			((FVRFireArm)this).PlayAudioGunShot(val.GetRound(), GM.CurrentPlayerBody.GetCurrentSoundEnvironment(), 1f);
			if (GM.CurrentSceneSettings.IsAmmoInfinite || GM.CurrentPlayerBody.IsInfiniteAmmo)
			{
				val.IsSpent = false;
				val.UpdateProxyDisplay();
			}
			else if ((Object)(object)val.GetRound() != (Object)null && (val.GetRound().IsCaseless || (Object)(object)val.GetRound().FiredRenderer == (Object)null))
			{
				val.SetRound((FVRFireArmRound)null, false);
			}
		}
	}

	public void CockHammer(float speed)
	{
		if (!m_isHammerCocked && !m_isHammerCocking)
		{
			m_isHalfCocked = false;
			m_isEasingDown = false;
			m_decockHoldTimer = 0f;
			m_hammerCockLerp = 0f;
			m_hammerCockSpeed = Mathf.Max(0.1f, speed);
			m_isHammerCocking = true;
			((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)7, 1f);
		}
	}

	public void EngageHalfCock()
	{
		m_isHalfCocked = true;
		m_isHammerCocking = false;
		m_isHammerCocked = false;
		m_isEasingDown = false;
		m_hammerCockLerp = 0f;
		m_decockHoldTimer = 0f;
		((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)7, 1.2f);
	}

	public void InitiateEaseDown()
	{
		m_decockHoldTimer = 0f;
		m_isHalfCocked = false;
		m_isHammerCocked = false;
		m_isHammerCocking = false;
		m_hammerCockLerp = 0f;
		m_isEasingDown = true;
		((FVRFireArm)this).PlayAudioEvent((FirearmAudioEventType)16, 1f);
	}

	public void UpdateSpinning()
	{
		//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_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0363: 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_0063: 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_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_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		if (!((FVRInteractiveObject)this).IsHeld || !CanSpin)
		{
			m_isSpinning = false;
		}
		if (m_isSpinning)
		{
			Vector3 val = Vector3.zero;
			if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
			{
				val = ((FVRInteractiveObject)this).m_hand.Input.VelLinearWorld;
			}
			float num = Vector3.Dot(((Vector3)(ref val)).normalized, ((Component)this).transform.up);
			num = Mathf.Clamp(num, 0f - ((Vector3)(ref val)).magnitude, ((Vector3)(ref val)).magnitude);
			if (Mathf.Abs(m_xSpinVel) < 90f || Mathf.Sign(num) == Mathf.Sign(m_xSpinVel))
			{
				m_xSpinVel += num * Time.deltaTime * 600f;
			}
			if (Mathf.Abs(m_xSpinVel) < 90f)
			{
				if (Vector3.Dot(((Component)this).transform.up, Vector3.down) >= 0f && Mathf.Sign(m_xSpinVel) >= 0f)
				{
					m_xSpinVel += Time.deltaTime * 50f;
				}
				if (Vector3.Dot(((Component)this).transform.up, Vector3.down) < 0f && Mathf.Sign(m_xSpinVel) < 0f)
				{
					m_xSpinVel -= Time.deltaTime * 50f;
				}
			}
			m_xSpinVel = Mathf.Clamp(m_xSpinVel, -500f, 500f);
			m_xSpinRot += m_xSpinVel * Time.deltaTime * 5f;
			if ((Object)(object)PoseSpinHolder != (Object)null)
			{
				PoseSpinHolder.localEulerAngles = new Vector3(m_xSpinRot, 0f, 0f);
			}
			float num2 = Mathf.Repeat(m_xSpinRot, 360f);
			if (num2 >= 260f && num2 <= 280f)
			{
				if (!m_spinAudioTriggeredThisRev && Mathf.Abs(m_xSpinVel) > 40f)
				{
					m_spinAudioTriggeredThisRev = true;
					if ((Object)(object)m_spinAudioSource != (Object)null && (Object)(object)SpinAudioClip != (Object)null)
					{
						m_spinAudioSource.pitch = Mathf.Lerp(0.9f, 1.25f, Mathf.Abs(m_xSpinVel) / 500f);
						m_spinAudioSource.PlayOneShot(SpinAudioClip, SpinAudioMaxVolume);
					}
					if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
					{
						((FVRInteractiveObject)this).m_hand.Buzz(((FVRInteractiveObject)this).m_hand.Buzzer.Buzz_BeginInteraction);
					}
				}
			}
			else
			{
				m_spinAudioTriggeredThisRev = false;
			}
			m_xSpinVel = Mathf.Lerp(m_xSpinVel, 0f, Time.deltaTime * 0.6f);
		}
		else
		{
			m_xSpinVel = 0f;
			m_spinAudioTriggeredThisRev = false;
			if ((Object)(object)PoseSpinHolder != (Object)null)
			{
				PoseSpinHolder.localRotation = Quaternion.RotateTowards(PoseSpinHolder.localRotation, m_storedSpinHolderRot, Time.deltaTime * 500f);
				m_xSpinRot = PoseSpinHolder.localEulerAngles.x;
			}
			else
			{
				m_xSpinRot = 0f;
			}
		}
	}

	public bool IsLatchOpen()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_latchStockScript != (Object)null)
		{
			return (int)m_latchStockScript.m_curPos == 2;
		}
		if ((Object)(object)CylinderLatch != (Object)null)
		{
			float x = CylinderLatch.localEulerAngles.x;
			return Mathf.Abs(Mathf.DeltaAngle(x, Latch_Rot_Open)) <= LatchAngleTolerance;
		}
		return true;
	}

	public bool IsLatchClosed()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_latchStockScript != (Object)null)
		{
			return (int)m_latchStockScript.m_curPos == 0;
		}
		if ((Object)(object)CylinderLatch != (Object)null)
		{
			float x = CylinderLatch.localEulerAngles.x;
			return Mathf.Abs(Mathf.DeltaAngle(x, Latch_Rot_Closed)) <= LatchAngleTolerance;
		}
		return true;
	}

	public bool IsRodForward()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_rodMovablePart != (Object)null)
		{
			return m_rodMovablePart.IsClosed;
		}
		if ((Object)(object)EjectorRod != (Object)null)
		{
			return Vector3.Distance(EjectorRod.localPosition, EjectorRod_Pos_Forward) <= RodDistanceTolerance;
		}
		return true;
	}

	public bool IsRodRearward()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_rodMovablePart != (Object)null)
		{
			return m_rodMovablePart.IsOpen;
		}
		if ((Object)(object)EjectorRod != (Object)null)
		{
			return Vector3.Distance(EjectorRod.localPosition, EjectorRod_Pos_Rearward) <= RodDistanceTolerance;
		}
		return true;
	}

	private bool CheckFiringConditions()
	{
		return IsRodRearward() && IsLatchClosed();
	}

	public bool CheckReloadConditions()
	{
		bool flag = true;
		if (RequireHalfCockToReload)
		{
			flag = m_isHalfCocked;
		}
		return IsRodForward() && IsLatchOpen() && flag;
	}

	public override void OnCollisionEnter(Collision col)
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		((FVRPhysicalObject)this).OnCollisionEnter(col);
		if (!HasTransferBarSafety && (Object)(object)col.collider.attachedRigidbody == (Object)null && base.CylinderLoaded && base.Chambers != null && ((RevolvingShotgun)this).CurChamber >= 0 && ((RevolvingShotgun)this).CurChamber < base.Chambers.Length && base.Chambers[((RevolvingShotgun)this).CurChamber].IsFull && !base.Chambers[((RevolvingShotgun)this).CurChamber].IsSpent && !m_isHammerCocked && !m_isHammerCocking && !m_isHalfCocked && !m_isEasingDown)
		{
			Vector3 relativeVelocity = col.relativeVelocity;
			if (((Vector3)(ref relativeVelocity)).magnitude > 2f && m_timeSinceColFire > 2.9f)
			{
				m_timeSinceColFire = 0f;
				m_isHammerCocked = true;
				DropHammer();
			}
		}
	}
}
public class ActiveDefenseSystem : FVRPhysicalObject, IFVRDamageable
{
	public enum ADSMode
	{
		Placement,
		Armed,
		Discharged
	}

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

	[Header("Modal Configuration")]
	public ADSMode Mode = ADSMode.Placement;

	[Header("Physical Visuals")]
	public Transform FlipPiece;

	public Vector2 FlipPieceRots;

	public GameObject Light_Red;

	public GameObject Light_Green;

	[Header("Deploy Base Plate")]
	[Tooltip("Place an empty GameObject exactly on the back/bottom plate of your model. Ensure its Z+ (blue arrow) points straight out of the base.")]
	public Transform AttachmentOrigin;

	[Tooltip("How long (in seconds) you must hold the base plate against a surface before it deploys.")]
	public float AttachmentTime = 0.5f;

	[Tooltip("How long (in seconds) the device takes to prime and arm itself once attached to a surface.")]
	public float PrimingTime = 2.5f;

	[Header("Radar Rotation")]
	[Tooltip("The mesh transform representing the radar head that rotates indefinitely when armed.")]
	public Transform RadarMesh;

	[Tooltip("Speed of the radar rotation in degrees per second.")]
	public float RadarRotationSpeed = 90f;

	[Tooltip("The local axis the radar mesh rotates around.")]
	public Axis RadarRotationAxis = (Axis)1;

	[Header("Interception Settings")]
	public float InterceptionRadius = 5f;

	public LayerMask InterceptionLayerMask;

	[Tooltip("The minimum time delay (in seconds) between zaps.")]
	public float CooldownBetweenZaps = 0.5f;

	[Tooltip("The mathematical probability (from 0.0 to 1.0) that each shot hits. Lower values delay destruction.")]
	public float HitChance = 0.7f;

	[Tooltip("Maximum amount of zaps before the gadget is depleted.")]
	public int MaxCharges = 3;

	[Tooltip("How long (in seconds) the gadget stays armed before powering down. Set to 0 for infinite.")]
	public float ExpirationTime = 60f;

	[Tooltip("How long (in seconds) after the gadget powers down before it completely deletes itself.")]
	public float SelfDestructDelay = 2f;

	[Tooltip("Should the gadget intercept enemy Sosig-thrown grenades?")]
	public bool InterceptSosigGrenades = true;

	[Tooltip("Should the gadget intercept rockets, mortars, or slow ballistic projectiles?")]
	public bool InterceptBallisticProjectiles = true;

	[Tooltip("If false, the device will ignore grenades thrown by the player.")]
	public bool InterceptFriendlyProjectiles = false;

	[Header("Effects & Spawn Points")]
	[Tooltip("Assign multiple muzzle points. The script will automatically fire from the one closest to the target.")]
	public List<Transform> InterceptionMuzzles;

	public LineRenderer LaserBeamEffect;

	public float LaserBeamDuration = 0.1f;

	public GameObject InterceptionEffectPrefab;

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

	public AudioEvent AudEvent_ArmButtonClick;

	public AudioEvent AudEvent_Priming;

	public AudioEvent AudEvent_Armed;

	public AudioEvent AudEvent_Zap;

	public AudioEvent AudEvent_HitConfirmation;

	public AudioEvent AudEvent_Discharged;

	[Header("Line of Sight & Placement Layers")]
	public LayerMask LM_Attach;

	[Tooltip("The layers (like environments/walls) that block the device's line of sight to projectiles.")]
	public LayerMask LineOfSightObstacleLayers;

	private int m_chargesLeft;

	private float m_timeRemaining;

	private float m_laserResetTimer;

	private RaycastHit m_hit;

	private bool m_isPriming;

	private float m_primeLerp;

	private bool m_isPrimed;

	private float m_attachTimer;

	private float m_zapCooldownTimer;

	private FieldInfo m_isFuseTickingDownField;

	private MethodInfo m_shatterMethodField;

	public override bool IsInteractable()
	{
		return Mode != ADSMode.Armed && ((FVRPhysicalObject)this).IsInteractable();
	}

	public override bool IsDistantGrabbable()
	{
		return Mode != ADSMode.Armed && ((FVRPhysicalObject)this).IsDistantGrabbable();
	}

	public override void Awake()
	{
		((FVRPhysicalObject)this).Awake();
		m_chargesLeft = MaxCharges;
		m_timeRemaining = ExpirationTime;
		if ((Object)(object)LaserBeamEffect != (Object)null)
		{
			((Renderer)LaserBeamEffect).enabled = false;
		}
		try
		{
			m_isFuseTickingDownField = typeof(SosigWeapon).GetField("m_isFuseTickingDown", BindingFlags.Instance | BindingFlags.NonPublic);
			m_shatterMethodField = typeof(SosigWeapon).GetMethod("Shatter", BindingFlags.Instance | BindingFlags.NonPublic);
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("ActiveDefenseSystem: Failed to get reflection fields. " + ex.Message));
		}
		SetMode(ADSMode.Placement);
	}

	public void SetMode(ADSMode m)
	{
		//IL_0054: 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_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: 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)
		Mode = m;
		switch (Mode)
		{
		case ADSMode.Placement:
			if ((Object)(object)FlipPiece != (Object)null)
			{
				FlipPiece.localEulerAngles = new Vector3(FlipPieceRots.x, 0f, 0f);
			}
			if ((Object)(object)Light_Red != (Object)null)
			{
				Light_Red.SetActive(false);
			}
			if ((Object)(object)Light_Green != (Object)null)
			{
				Light_Green.SetActive(true);
			}
			base.Size = (FVRPhysicalObjectSize)1;
			((FVRPhysicalObject)this).RootRigidbody.isKinematic = false;
			m_isPrimed = false;
			m_isPriming = false;
			break;
		case ADSMode.Armed:
			if ((Object)(object)FlipPiece != (Object)null)
			{
				FlipPiece.localEulerAngles = new Vector3(FlipPieceRots.y, 0f, 0f);
			}
			if ((Object)(object)Light_Red != (Object)null)
			{
				Light_Red.SetActive(true);
			}
			if ((Object)(object)Light_Green != (Object)null)
			{
				Light_Green.SetActive(false);
			}
			PrimeDevice();
			base.Size = (FVRPhysicalObjectSize)5;
			break;
		case ADSMode.Discharged:
			if ((Object)(object)FlipPiece != (Object)null)
			{
				FlipPiece.localEulerAngles = new Vector3(FlipPieceRots.x, 0f, 0f);
			}
			if ((Object)(object)Light_Red != (Object)null)
			{
				Light_Red.SetActive(false);
			}
			if ((Object)(object)Light_Green != (Object)null)
			{
				Light_Green.SetActive(false);
			}
			if ((Object)(object)LaserBeamEffect != (Object)null)
			{
				((Renderer)LaserBeamEffect).enabled = false;
			}
			DetachAndDisarm();
			break;
		}
	}

	private void DetachAndDisarm()
	{
		((FVRPhysicalObject)this).RootRigidbody.isKinematic = false;
		m_isPrimed = false;
		m_isPriming = false;
	}

	private void PrimeDevice()
	{
		m_isPriming = true;
		m_primeLerp = 0f;
	}

	public override void BeginInteraction(FVRViveHand hand)
	{
		if (Mode == ADSMode.Armed || Mode == ADSMode.Discharged)
		{
			LogDebug("Player grabbed deployed device off the wall. Disarming...");
			SetMode(ADSMode.Placement);
		}
		((FVRPhysicalObject)this).BeginInteraction(hand);
	}

	public override void FVRUpdate()
	{
		//IL_00a5: 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_00e1: 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_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Invalid comparison between Unknown and I4
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Invalid comparison between Unknown and I4
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		((FVRPhysicalObject)this).FVRUpdate();
		if ((Object)(object)LaserBeamEffect != (Object)null && ((Renderer)LaserBeamEffect).enabled)
		{
			m_laserResetTimer -= Time.deltaTime;
			if (m_laserResetTimer <= 0f)
			{
				((Renderer)LaserBeamEffect).enabled = false;
			}
		}
		if (m_isPriming)
		{
			m_primeLerp += Time.deltaTime;
			if (m_primeLerp > PrimingTime)
			{
				m_isPriming = false;
				m_isPrimed = true;
				SM.PlayCoreSound((FVRPooledAudioType)0, AudEvent_Armed, ((Component)this).transform.position);
			}
		}
		if (m_isPrimed && Mode == ADSMode.Armed)
		{
			if ((Object)(object)RadarMesh != (Object)null)
			{
				Vector3 zero = Vector3.zero;
				float num = RadarRotationSpeed * Time.deltaTime;
				if ((int)RadarRotationAxis == 0)
				{
					zero.x = num;
				}
				else if ((int)RadarRotationAxis == 1)
				{
					zero.y = num;
				}
				else if ((int)RadarRotationAxis == 2)
				{
					zero.z = num;
				}
				RadarMesh.Rotate(zero, (Space)1);
			}
			if (m_zapCooldownTimer > 0f)
			{
				m_zapCooldownTimer -= Time.deltaTime;
			}
			if (ExpirationTime > 0f)
			{
				m_timeRemaining -= Time.deltaTime;
				if (m_timeRemaining <= 0f)
				{
					PowerDownDevice();
					return;
				}
			}
			if (m_zapCooldownTimer <= 0f)
			{
				ScanAndIntercept();
			}
		}
		if (Mode == ADSMode.Placement && (Object)(object)((FVRPhysicalObject)this).QuickbeltSlot == (Object)null && ((FVRInteractiveObject)this).IsHeld)
		{
			AttachTest();
		}
	}

	private void AttachTest()
	{
		//IL_0028: 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_0044: 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_008f: 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_009e: 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_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_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)AttachmentOrigin == (Object)null)
		{
			Debug.LogError((object)"ActiveDefenseSystem: AttachmentOrigin Transform is not assigned in the inspector!");
		}
		else if (Physics.Raycast(AttachmentOrigin.position, AttachmentOrigin.forward, ref m_hit, 0.15f, LayerMask.op_Implicit(LM_Attach), (QueryTriggerInteraction)1))
		{
			m_attachTimer += Time.deltaTime;
			if (m_attachTimer >= AttachmentTime)
			{
				Quaternion val = Quaternion.FromToRotation(AttachmentOrigin.forward, -((RaycastHit)(ref m_hit)).normal);
				((Component)this).transform.rotation = val * ((Component)this).transform.rotation;
				Vector3 val2 = ((Component)this).transform.position - AttachmentOrigin.position;
				((Component)this).transform.position = ((RaycastHit)(ref m_hit)).point + val2;
				SM.PlayCoreSound((FVRPooledAudioType)0, AudEvent_Priming, ((Component)this).transform.position);
				SetMode(ADSMode.Armed);
				if (((FVRInteractiveObject)this).IsHeld)
				{
					((FVRInteractiveObject)this).ForceBreakInteraction();
				}
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = true;
				m_attachTimer = 0f;
			}
		}
		else
		{
			m_attachTimer = 0f;
		}
	}

	private void ScanAndIntercept()
	{
		//IL_0007: 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_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_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Invalid comparison between Unknown and I4
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: 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_016d: 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_0176: Unknown result type (might be due to invalid IL or missing references)
		Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, InterceptionRadius, LayerMask.op_Implicit(InterceptionLayerMask));
		if (array == null || array.Length == 0)
		{
			return;
		}
		RaycastHit val2 = default(RaycastHit);
		RaycastHit val3 = default(RaycastHit);
		foreach (Collider val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Vector3 position = ((Component)val).transform.position;
			if (InterceptSosigGrenades)
			{
				SosigWeapon component = ((Component)val).GetComponent<SosigWeapon>();
				if ((Object)(object)component == (Object)null && (Object)(object)val.attachedRigidbody != (Object)null)
				{
					component = ((Component)val.attachedRigidbody).GetComponent<SosigWeapon>();
				}
				if ((Object)(object)component != (Object)null && (int)component.GetMyType() == 2 && (Object)(object)component.O != (Object)null && !((FVRInteractiveObject)component.O).IsHeld && !component.IsHeldByBot && (Object)(object)component.O.QuickbeltSlot == (Object)null)
				{
					bool flag = false;
					if ((object)m_isFuseTickingDownField != null)
					{
						flag = (bool)m_isFuseTickingDownField.GetValue(component);
					}
					if (flag)
					{
						if (!InterceptFriendlyProjectiles && component.SourceIFF == GM.CurrentPlayerBody.GetPlayerIFF())
						{
							continue;
						}
						Transform closestMuzzle = GetClosestMuzzle(position);
						if ((Object)(object)closestMuzzle != (Object)null && Physics.Linecast(closestMuzzle.position, position, ref val2, LayerMask.op_Implicit(LineOfSightObstacleLayers), (QueryTriggerInteraction)1))
						{
							continue;
						}
						if (Random.value > HitChance)
						{
							LogDebug("Interception missed/delayed. Setting cooldown.");
							m_zapCooldownTimer = CooldownBetweenZaps;
						}
						else
						{
							ZapTarget(((Component)component).gameObject, closestMuzzle);
						}
						break;
					}
				}
			}
			if (!InterceptBallisticProjectiles)
			{
				continue;
			}
			BallisticProjectile component2 = ((Component)val).GetComponent<BallisticProjectile>();
			if ((Object)(object)component2 == (Object)null && (Object)(object)val.attachedRigidbody != (Object)null)
			{
				component2 = ((Component)val.attachedRigidbody).GetComponent<BallisticProjectile>();
			}
			if (!((Object)(object)component2 != (Object)null) || !component2.IsMoving() || (!InterceptFriendlyProjectiles && component2.Source_IFF == GM.CurrentPlayerBody.GetPlayerIFF()))
			{
				continue;
			}
			Transform closestMuzzle2 = GetClosestMuzzle(position);
			if ((Object)(object)closestMuzzle2 != (Object)null && Physics.Linecast(closestMuzzle2.position, position, ref val3, LayerMask.op_Implicit(LineOfSightObstacleLayers), (QueryTriggerInteraction)1))
			{
				continue;
			}
			if (Random.value > HitChance)
			{
				LogDebug("Interception missed/delayed. Setting cooldown.");
				m_zapCooldownTimer = CooldownBetweenZaps;
			}
			else
			{
				ZapTarget(((Component)component2).gameObject, closestMuzzle2);
			}
			break;
		}
	}

	private Transform GetClosestMuzzle(Vector3 targetPosition)
	{
		//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)
		Transform result = null;
		if (InterceptionMuzzles != null && InterceptionMuzzles.Count > 0)
		{
			float num = float.MaxValue;
			for (int i = 0; i < InterceptionMuzzles.Count; i++)
			{
				if (!((Object)(object)InterceptionMuzzles[i] == (Object)null))
				{
					float num2 = Vector3.Distance(InterceptionMuzzles[i].position, targetPosition);
					if (num2 < num)
					{
						num = num2;
						result = InterceptionMuzzles[i];
					}
				}
			}
		}
		return result;
	}

	private void ZapTarget(GameObject target, Transform bestMuzzle)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Expected O, but got Unknown
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target == (Object)null || (Object)(object)bestMuzzle == (Object)null)
		{
			return;
		}
		Vector3 position = target.transform.position;
		LogDebug("Intercepting target: " + ((Object)target).name);
		if ((Object)(object)LaserBeamEffect != (Object)null)
		{
			LaserBeamEffect.useWorldSpace = true;
			LaserBeamEffect.positionCount = 2;
			((Renderer)LaserBeamEffect).enabled = true;
			m_laserResetTimer = LaserBeamDuration;
			LaserBeamEffect.SetPosition(0, bestMuzzle.position);
			LaserBeamEffect.SetPosition(1, position);
		}
		SM.PlayCoreSound((FVRPooledAudioType)0, AudEvent_Zap, ((Component)this).transform.position);
		if (AudEvent_HitConfirmation != null)
		{
			SM.PlayCoreSound((FVRPooledAudioType)0, AudEvent_HitConfirmation, position);
		}
		if ((Object)(object)InterceptionEffectPrefab != (Object)null)
		{
			Object.Instantiate<GameObject>(InterceptionEffectPrefab, position, Quaternion.identity);
		}
		SosigWeapon component = target.GetComponent<SosigWeapon>();
		if ((Object)(object)component == (Object)null && (Object)(object)target.GetComponent<Collider>() != (Object)null && (Object)(object)target.GetComponent<Collider>().attachedRigidbody != (Object)null)
		{
			component = ((Component)target.GetComponent<Collider>().attachedRigidbody).GetComponent<SosigWeapon>();
		}
		if ((Object)(object)component != (Object)null)
		{
			if (component.TakesDamage)
			{
				Damage val = new Damage();
				val.Class = (DamageClass)1;
				val.Dam_Blunt = 1000f;
				val.Dam_TotalKinetic = 1000f;
				val.point = position;
				Vector3 val2 = position - bestMuzzle.position;
				val.strikeDir = ((Vector3)(ref val2)).normalized;
				val.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
				component.Damage(val);
			}
			else if ((object)m_shatterMethodField != null)
			{
				m_shatterMethodField.Invoke(component, null);
			}
			else
			{
				Object.Destroy((Object)(object)target);
			}
		}
		else
		{
			Object.Destroy((Object)(object)target);
		}
		m_zapCooldownTimer = CooldownBetweenZaps;
		m_chargesLeft--;
		if (m_chargesLeft <= 0)
		{
			PowerDownDevice();
		}
	}

	private void PowerDownDevice()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		LogDebug("Gadget has run out of power/charges. Discharging...");
		SM.PlayCoreSound((FVRPooledAudioType)0, AudEvent_Discharged, ((Component)this).transform.position);
		SetMode(ADSMode.Discharged);
		if (SelfDestructDelay >= 0f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject, SelfDestructDelay);
		}
	}

	private void LogDebug(string message)
	{
		if (DebugLogging)
		{
			Debug.Log((object)("ActiveDefenseSystem: " + message));
		}
	}

	public void Damage(Damage d)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		if ((int)d.Class == 1 && Mode == ADSMode.Armed)
		{
			PowerDownDevice();
		}
	}
}
namespace VolksScripts
{
	public class NVGPowerSwitch : FVRInteractiveObject
	{
		public PIPScope Scope;

		[HideInInspector]
		public bool Toggle = true;

		public override void SimpleInteraction(FVRViveHand hand)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).SimpleInteraction(hand);
			SM.PlayCoreSound((FVRPooledAudioType)10, ManagerSingleton<SM>.Instance.AudioEvent_AttachmentClick_Minor, ((Component)this).transform.position);
			if (Toggle)
			{
				Scope.enableNightvision = (Scope.enableThermal = false);
			}
			else
			{
				Scope.enableNightvision = (Scope.enableThermal = true);
			}
			Toggle = !Toggle;
		}
	}
	public class ANVIS21Control : MonoBehaviour
	{
		public Transform armreal;

		public Transform armfake;

		public PIPScope scopeL;

		public PIPScope scopeR;

		public float onspeed = 0.5f;

		public float offspeed = 0.5f;

		public AudioEvent powerOn;

		public AudioEvent powerOff;

		public bool isOn;

		private float gainVelL;

		private float gainVelR;

		private float brightVelL;

		private float brightVelR;

		public bool IsOn => isOn;

		private void Start()
		{
			SetScopesImmediate(0f);
		}

		private void Update()
		{
			SyncArms();
			UpdateNVG();
		}

		public void SetPower(bool value)
		{
			//IL_006d: 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)
			if (isOn == value)
			{
				return;
			}
			isOn = value;
			if (isOn)
			{
				if (powerOn != null)
				{
					SM.PlayCoreSound((FVRPooledAudioType)10, powerOn, ((Component)this).transform.position);
				}
			}
			else if (powerOff != null)
			{
				SM.PlayCoreSound((FVRPooledAudioType)10, powerOff, ((Component)this).transform.position);
			}
		}

		private void SyncArms()
		{
			//IL_0035: 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)
			if (!((Object)(object)armreal == (Object)null) && !((Object)(object)armfake == (Object)null))
			{
				armfake.localPosition = armreal.localPosition;
				armfake.localRotation = armreal.localRotation;
			}
		}

		private void UpdateNVG()
		{
			float num = ((!isOn) ? 0f : 1f);
			float num2 = ((!isOn) ? offspeed : onspeed);
			if ((Object)(object)scopeL != (Object)null)
			{
				scopeL.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeL.nvDef.nightVisionTargetBrightness, num, ref brightVelL, num2);
				scopeL.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeL.nightVisionManualGainFactor, num, ref gainVelL, num2);
				((Behaviour)scopeL).enabled = true;
				scopeL.UpdateParameters();
			}
			if ((Object)(object)scopeR != (Object)null)
			{
				scopeR.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeR.nvDef.nightVisionTargetBrightness, num, ref brightVelR, num2);
				scopeR.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeR.nightVisionManualGainFactor, num, ref gainVelR, num2);
				((Behaviour)scopeR).enabled = true;
				scopeR.UpdateParameters();
			}
		}

		private void SetScopesImmediate(float value)
		{
			if ((Object)(object)scopeL != (Object)null)
			{
				scopeL.nvDef.nightVisionTargetBrightness = value;
				scopeL.nightVisionManualGainFactor = value;
			}
			if ((Object)(object)scopeR != (Object)null)
			{
				scopeR.nvDef.nightVisionTargetBrightness = value;
				scopeR.nightVisionManualGainFactor = value;
			}
		}
	}
	public class ANVIS21PowerSwitch : FVRInteractiveObject
	{
		public ANVIS21Control control;

		public Transform switchTransform;

		public Vector3 offEulerAngles;

		public Vector3 onEulerAngles;

		public float lerpSpeed = 8f;

		private float m_lerp;

		protected void Awake()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).Awake();
			if ((Object)(object)switchTransform == (Object)null)
			{
				switchTransform = ((Component)this).transform;
			}
			if ((Object)(object)control != (Object)null)
			{
				m_lerp = ((!control.IsOn) ? 0f : 1f);
				switchTransform.localEulerAngles = Vector3.Lerp(offEulerAngles, onEulerAngles, m_lerp);
			}
		}

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

		protected void FVRUpdate()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).FVRUpdate();
			if (!((Object)(object)control == (Object)null) && !((Object)(object)switchTransform == (Object)null))
			{
				float num = ((!control.IsOn) ? 0f : 1f);
				m_lerp = Mathf.MoveTowards(m_lerp, num, Time.deltaTime * lerpSpeed);
				switchTransform.localEulerAngles = Vector3.Lerp(offEulerAngles, onEulerAngles, m_lerp);
			}
		}
	}
}
public class ForceBindToHead : MonoBehaviour
{
	[Tooltip("The object that should follow the player's head (e.g. NVG physical root).")]
	public GameObject phys;

	[Tooltip("Optional: if true, runs even when not equipped.")]
	public bool alwaysFollow = true;

	private Transform headTransform;

	private void Start()
	{
		if ((Object)(object)GM.CurrentMovementManager != (Object)null && (Object)(object)GM.CurrentMovementManager.Head != (Object)null)
		{
			headTransform = ((Component)GM.CurrentMovementManager.Head).transform;
		}
		else
		{
			Debug.LogWarning((object)"[ForceBindToHead] Could not find head transform.");
		}
	}

	private void FixedUpdate()
	{
		//IL_00ac: 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)
		if (!((Object)(object)phys == (Object)null) && (alwaysFollow || !((Object)(object)headTransform == (Object)null)))
		{
			if ((Object)(object)headTransform == (Object)null && (Object)(object)GM.CurrentMovementManager != (Object)null)
			{
				headTransform = ((Component)GM.CurrentMovementManager.Head).transform;
			}
			if ((Object)(object)phys.transform.parent != (Object)(object)headTransform)
			{
				phys.transform.SetParent(headTransform);
			}
			phys.transform.localPosition = Vector3.zero;
			phys.transform.localEulerAngles = Vector3.zero;
		}
	}
}
public class BaffleSuppressor : Suppressor
{
	public enum PerceptionMode
	{
		Automatic,
		ForceEnvironment,
		UseVolumeOnly
	}

	[Header("Baffle (wear) settings")]
	[Tooltip("Max integrity (brand new).")]
	public int MaxIntegrity = 10;

	[Tooltip("Current integrity (MaxIntegrity = new, 0 = broken).")]
	[Range(0f, 100f)]
	public int Integrity = 10;

	[Tooltip("Integrity lost per shot.")]
	public int WearPerShot = 1;

	[Tooltip("Multiplier applied to loudness at full integrity (very quiet).")]
	[Range(0f, 1f)]
	public float QuietMultiplierAtFull = 0.12f;

	[Tooltip("Multiplier applied to loudness when fully broken (typically 1).")]
	[Range(0f, 2f)]
	public float LoudMultiplierAtBroken = 1f;

	[Header("Suppressor audio (played by this suppressor)")]
	[Tooltip("Clip played as the primary suppressed shot. If null, suppressor will still attempt to mute nearby audio but won't play a replacement.")]
	public AudioClip SuppressedShotClip;

	[Tooltip("Optional tail/ambience clip to complement the suppressed shot.")]
	public AudioClip SuppressedTailClip;

	[Tooltip("Base volume multiplier for suppressed shot clip (before applying integrity multiplier).")]
	[Range(0f, 2f)]
	public float SuppressedShotBaseVolume = 1f;

	[Tooltip("Base volume multiplier for suppressed tail clip.")]
	[Range(0f, 2f)]
	public float SuppressedTailBaseVolume = 1f;

	[Header("Visuals")]
	[Tooltip("GameObject root for intact visual (enable when not broken).")]
	public GameObject IntactVisual;

	[Tooltip("GameObject root for broken visual (enable when broken).")]
	public GameObject BrokenVisual;

	[Header("Feedback")]
	[Tooltip("Clip played when suppressor breaks.")]
	public AudioClip BreakClip;

	[Tooltip("Local audio source used for PlayOneShot; if null PlayClipAtPoint is used.")]
	public AudioSource LocalAudioSource;

	[Tooltip("If > 0, auto-repair after this many seconds (debugging/testing). 0 = disabled.")]
	public float AutoRepairAfterSeconds = 0f;

	[Header("Audio-silencing tuning (best-effort)")]
	[Tooltip("Radius around muzzle within which playing AudioSources may be considered gunshot audio (meters).")]
	public float MuzzleSilenceRadius = 0.75f;

	[Tooltip("Maximum age (seconds) of a recent AudioSource play to consider it for silencing.")]
	public float RecentPlayMaxAge = 0.2f;

	[Tooltip("Time (seconds) to fade an AudioSource's volume to zero before stopping it.")]
	public float FadeOutTime = 0.04f;

	[Header("Perception / Environment")]
	[Tooltip("How perception is reported to the scene (affects AI hearing/travel distance).")]
	public PerceptionMode PerceptionBehavior = PerceptionMode.Automatic;

	[Tooltip("When PerceptionBehavior == ForceEnvironment, use this environment for travel multiplier lookups.")]
	public FVRSoundEnvironment ForcedEnvironment = (FVRSoundEnvironment)11;

	[Tooltip("When PerceptionBehavior == UseVolumeOnly, scale perceived primary loudness by this multiplier (independent of environment).")]
	[Range(0f, 10f)]
	public float PerceptionVolumeMultiplier = 1f;

	[Header("Debris & Hole visuals")]
	[Tooltip("Optional debris prefab spawned when the suppressor breaks.")]
	public GameObject DebrisPrefab;

	[Tooltip("Spawn debris when the suppressor breaks.")]
	public bool SpawnDebrisOnBreak = true;

	[Tooltip("Min scale applied to spawned debris.")]
	public Vector3 DebrisScaleMin = new Vector3(0.2f, 0.2f, 0.2f);

	[Tooltip("Max scale applied to spawned debris.")]
	public Vector3 DebrisScaleMax = new Vector3(1.5f, 1.5f, 1.5f);

	[Tooltip("Lifetime of spawned debris (0 = no auto-destroy).")]
	public float DebrisLifetime = 5f;

	[Tooltip("Optional transform used as an animated 'hole' visual; its scale is driven by damage.")]
	public Transform HoleVisual;

	[Tooltip("Scale when intact (usually small or 0).")]
	public Vector3 HoleScaleAtIntact = Vector3.zero;

	[Tooltip("Scale when fully broken.")]
	public Vector3 HoleScaleAtBroken = Vector3.one;

	[Tooltip("How long to animate hole scale changes.")]
	public float HoleScaleAnimTime = 0.15f;

	private bool _isBroken = false;

	private readonly Dictionary<AudioSource, float> _audioPlayStart = new Dictionary<AudioSource, float>();

	private FVRFireArm _cachedFirearm = null;

	private FVRFireArm _lastShotFirearm = null;

	private Coroutine _holeAnimCoroutine = null;

	public bool IsBroken => _isBroken;

	public override void Awake()
	{
		((MuzzleDevice)this).Awake();
		MaxIntegrity = Mathf.Max(1, MaxIntegrity);
		Integrity = Mathf.Clamp(Integrity, 0, MaxIntegrity);
		_isBroken = Integrity <= 0;
		ApplyVisualState();
		UpdateHoleVisualImmediate();
	}

	public float GetSuppressionMultiplier()
	{
		if (MaxIntegrity <= 0)
		{
			return LoudMultiplierAtBroken;
		}
		if (IsBroken)
		{
			return LoudMultiplierAtBroken;
		}
		float num = 1f - (float)Integrity / (float)MaxIntegrity;
		return Mathf.Lerp(QuietMultiplierAtFull, LoudMultiplierAtBroken, num);
	}

	public override void OnShot(FVRFireArm firearm, FVRTailSoundClass tailClass)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			((MuzzleDevice)this).OnShot(firearm, tailClass);
		}
		catch
		{
		}
		_lastShotFirearm = firearm;
		if (!IsBroken)
		{
			AttemptSilenceRecentAudioNearMuzzle(firearm);
			PlaySuppressedAudio(firearm);
		}
		NotifyPerception(firearm, tailClass);
		ApplyWear();
	}

	private void AttemptSilenceRecentAudioNearMuzzle(FVRFireArm firearm)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = ((Component)this).transform.position;
		try
		{
			if ((Object)(object)firearm != (Object)null)
			{
				Transform muzzle = firearm.GetMuzzle();
				if ((Object)(object)muzzle != (Object)null)
				{
					position = muzzle.position;
				}
			}
		}
		catch
		{
		}
		AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
		float time = Time.time;
		foreach (AudioSource val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				bool isPlaying = val.isPlaying;
				bool flag = _audioPlayStart.ContainsKey(val);
				if (isPlaying && !flag)
				{
					_audioPlayStart[val] = time;
				}
				else if (!isPlaying && flag)
				{
					_audioPlayStart.Remove(val);
				}
			}
		}
		List<AudioSource> list = new List<AudioSource>();
		foreach (KeyValuePair<AudioSource, float> item in _audioPlayStart)
		{
			AudioSource key = item.Key;
			float value = item.Value;
			if (!((Object)(object)key == (Object)null) && key.isPlaying && !(time - value > RecentPlayMaxAge) && (!((Object)(object)LocalAudioSource != (Object)null) || !((Object)(object)key == (Object)(object)LocalAudioSource)))
			{
				Vector3 position2 = ((Component)key).transform.position;
				float num = Vector3.Distance(position2, position);
				if (num <= MuzzleSilenceRadius && (!((Object)(object)key.clip != (Object)null) || !(key.clip.length > 5f)))
				{
					list.Add(key);
				}
			}
		}
		for (int j = 0; j < list.Count; j++)
		{
			AudioSource s = list[j];
			((MonoBehaviour)this).StartCoroutine(FadeOutAndStopAudio(s, FadeOutTime));
		}
	}

	private IEnumerator FadeOutAndStopAudio(AudioSource s, float fadeTime)
	{
		if ((Object)(object)s == (Object)null)
		{
			yield break;
		}
		float startVol = s.volume;
		float t = 0f;
		while (t < fadeTime)
		{
			if ((Object)(object)s == (Object)null)
			{
				yield break;
			}
			t += Time.deltaTime;
			float mul = 1f - Mathf.Clamp01(t / fadeTime);
			try
			{
				s.volume = startVol * mul;
			}
			catch
			{
			}
			yield return null;
		}
		try
		{
			s.Stop();
			s.volume = startVol;
		}
		catch
		{
		}
		if (_audioPlayStart.ContainsKey(s))
		{
			_audioPlayStart.Remove(s);
		}
	}

	private void PlaySuppressedAudio(FVRFireArm firearm)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: 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_00de: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		float suppressionMultiplier = GetSuppressionMultiplier();
		float num = 1f;
		if ((Object)(object)SuppressedShotClip != (Object)null)
		{
			Vector3 val = ((Component)this).transform.position;
			try
			{
				if ((Object)(object)firearm != (Object)null)
				{
					Transform muzzle = firearm.GetMuzzle();
					val = ((!((Object)(object)muzzle != (Object)null)) ? ((Component)firearm).transform.position : muzzle.position);
				}
			}
			catch
			{
			}
			float num2 = Mathf.Clamp01(SuppressedShotBaseVolume * suppressionMultiplier * num);
			if ((Object)(object)LocalAudioSource != (Object)null)
			{
				LocalAudioSource.PlayOneShot(SuppressedShotClip, num2);
			}
			else
			{
				AudioSource.PlayClipAtPoint(SuppressedShotClip, val, num2);
			}
		}
		if (!((Object)(object)SuppressedTailClip != (Object)null))
		{
			return;
		}
		Vector3 position = ((Component)this).transform.position;
		try
		{
			if ((Object)(object)firearm != (Object)null)
			{
				Transform muzzle2 = firearm.GetMuzzle();
				if ((Object)(object)muzzle2 != (Object)null)
				{
					position = muzzle2.position;
				}
			}
		}
		catch
		{
		}
		float num3 = Mathf.Clamp01(SuppressedTailBaseVolume * suppressionMultiplier * num);
		AudioSource.PlayClipAtPoint(SuppressedTailClip, position, num3);
	}

	private void NotifyPerception(FVRFireArm firearm, FVRTailSoundClass tailClass)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_003f: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: 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)
		try
		{
			Vector3 position = ((Component)this).transform.position;
			if ((Object)(object)firearm != (Object)null)
			{
				Transform muzzle = firearm.GetMuzzle();
				if ((Object)(object)muzzle != (Object)null)
				{
					position = muzzle.position;
				}
			}
			float suppressionMultiplier = GetSuppressionMultiplier();
			FVRSoundEnvironment val = (FVRSoundEnvironment)11;
			float num = 1f;
			int num2 = 0;
			try
			{
				num2 = GM.CurrentPlayerBody.GetPlayerIFF();
			}
			catch
			{
			}
			if (PerceptionBehavior == PerceptionMode.Automatic)
			{
				try
				{
					val = GM.CurrentPlayerBody.GetCurrentSoundEnvironment();
				}
				catch
				{
				}
				try
				{
					num = SM.GetSoundTravelDistanceMultByEnvironment(val);
				}
				catch
				{
					num = 1f;
				}
			}
			else if (PerceptionBehavior == PerceptionMode.ForceEnvironment)
			{
				val = ForcedEnvironment;
				try
				{
					num = SM.GetSoundTravelDistanceMultByEnvironment(val);
				}
				catch
				{
					num = 1f;
				}
			}
			else
			{
				num = 1f;
			}
			float num3 = 1f * suppressionMultiplier;
			if (PerceptionBehavior == PerceptionMode.UseVolumeOnly)
			{
				num3 *= PerceptionVolumeMultiplier;
			}
			float num4 = num3 * num * 0.5f;
			GM.CurrentSceneSettings.OnPerceiveableSound(num3, num4, position, num2, GM.CurrentPlayerBody.PlayerEntities[0]);
		}
		catch
		{
		}
	}

	private void ApplyWear()
	{
		if (!IsBroken)
		{
			Integrity -= WearPerShot;
			Integrity = Mathf.Clamp(Integrity, 0, MaxIntegrity);
			UpdateHoleVisual();
			if (Integrity <= 0)
			{
				Integrity = 0;
				BreakSuppressor();
			}
		}
	}

	private void BreakSuppressor()
	{
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_0106: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing