Decompiled source of Switch Attachment v1.0.0

Switch_Attachment.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using OpenScripts2;
using OtherLoader;
using Sodalite.Api;
using Sodalite.Utilities;
using UnityEditor;
using UnityEngine;
using UnityEngine.AI;
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]
public class RemingtonCylinderController : MonoBehaviour
{
	[Header("Debugging")]
	public bool DebugLogging = false;

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

	public MovableObjectPart Latch;

	public MovableObjectPart Rod;

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

	[Tooltip("Optional. The interaction collider on your cylinder. If left blank, it will automatically find the collider on the gun's cylinder.")]
	public Collider CylinderCollider;

	[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 void Start()
	{
		if ((Object)(object)Weapon == (Object)null)
		{
			Weapon = ((Component)this).GetComponent<Revolver>();
		}
	}

	private void Update()
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Invalid comparison between Unknown and I4
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Invalid comparison between Unknown and I4
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Invalid comparison between Unknown and I4
		if ((Object)(object)Weapon == (Object)null || (Object)(object)Latch == (Object)null || (Object)(object)Rod == (Object)null)
		{
			return;
		}
		if (!IsCylinderLoaded && (Object)(object)Weapon.Cylinder != (Object)null && Weapon.Cylinder.HasSpeedLoadedIn)
		{
			IsCylinderLoaded = true;
			LogDebug("New cylinder loaded. State updated.");
		}
		if ((int)Latch.State == 0)
		{
			if ((Object)(object)RodCollider != (Object)null && !RodCollider.enabled)
			{
				RodCollider.enabled = true;
				LogDebug("Latch is open. Rod collider enabled.");
			}
		}
		else if ((int)Rod.State == 2 && (Object)(object)RodCollider != (Object)null && RodCollider.enabled)
		{
			RodCollider.enabled = false;
			LogDebug("Latch is closed and Rod is back. Rod collider disabled.");
		}
		bool flag = (int)Rod.State == 0;
		if (IsCylinderLoaded && (Object)(object)Weapon.Cylinder != (Object)null)
		{
			Collider val = CylinderCollider;
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)Weapon.Cylinder).GetComponent<Collider>();
			}
			if ((Object)(object)val != (Object)null && val.enabled != flag)
			{
				val.enabled = flag;
			}
			if (flag && ((FVRInteractiveObject)Weapon.Cylinder).IsHeld)
			{
				FVRViveHand hand = ((FVRInteractiveObject)Weapon.Cylinder).m_hand;
				((FVRInteractiveObject)Weapon.Cylinder).EndInteraction(hand);
				hand.ForceSetInteractable((FVRInteractiveObject)null);
				PerformCylinderEjection(hand);
			}
		}
	}

	private void PerformCylinderEjection(FVRViveHand hand)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Weapon == (Object)null) && !((Object)(object)Weapon.Cylinder == (Object)null))
		{
			LogDebug("Player grabbed the cylinder. Ejecting...");
			if (string.IsNullOrEmpty(Weapon.Cylinder.SpeedLoaderID))
			{
				Weapon.Cylinder.SpeedLoaderID = DefaultCylinderPrefabID;
			}
			Weapon.EjectChambers();
			FVRPhysicalObject val = FindClosestSpawnedCylinder(((Component)Weapon.Cylinder).transform.position);
			if ((Object)(object)val != (Object)null && (Object)(object)hand != (Object)null)
			{
				hand.ForceSetInteractable((FVRInteractiveObject)(object)val);
				((FVRInteractiveObject)val).BeginInteraction(hand);
			}
			IsCylinderLoaded = false;
		}
	}

	private FVRPhysicalObject FindClosestSpawnedCylinder(Vector3 position)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		Speedloader[] array = Object.FindObjectsOfType<Speedloader>();
		Speedloader result = null;
		float num = float.MaxValue;
		for (int i = 0; i < array.Length; i++)
		{
			if (!((Object)(object)array[i] == (Object)null))
			{
				float num2 = Vector3.Distance(((Component)array[i]).transform.position, position);
				if (num2 < num)
				{
					num = num2;
					result = array[i];
				}
			}
		}
		return (FVRPhysicalObject)(object)result;
	}

	private void LogDebug(string message)
	{
		if (DebugLogging)
		{
			Debug.Log((object)("RemingtonCylinderController: " + message));
		}
	}
}
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;

	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);
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("ActiveDefenseSystem: Failed to get reflection field for grenade fuse. " + 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_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Expected O, but got Unknown
		//IL_0150: 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_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)target == (Object)null) && !((Object)(object)bestMuzzle == (Object)null))
		{
			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);
			}
			IFVRDamageable component = target.GetComponent<IFVRDamageable>();
			if (component == null && (Object)(object)target.GetComponent<Collider>() != (Object)null && (Object)(object)target.GetComponent<Collider>().attachedRigidbody != (Object)null)
			{
				component = ((Component)target.GetComponent<Collider>().attachedRigidbody).GetComponent<IFVRDamageable>();
			}
			if (component != null)
			{
				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
			{
				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;
		}
	}
}
namespace JerryComponent
{
	public class PNV57EControl : MonoBehaviour
	{
		public GameObject phys;

		public GameObject armreal;

		public GameObject armfake;

		public Vector3 velLinearWorldL;

		public Vector3 velLinearWorldR;

		public Transform slapdirUP;

		public Transform slapdirDown;

		public HeadAttachment HA;

		public PIPScope scopeL;

		public PIPScope scopeR;

		public GameObject powerknob;

		public float refgain;

		public float reflum;

		public AudioEvent flip;

		public bool started = false;

		public float onspeed = 0.5f;

		public float offspeed = 2.5f;

		public bool isheadmounted = true;

		public AudioSource whing;

		public float volref;

		private void Start()
		{
			scopeL.nvDef.nightVisionTargetBrightness = 0f;
			scopeL.nightVisionManualGainFactor = 0f;
			scopeR.nvDef.nightVisionTargetBrightness = 0f;
			scopeR.nightVisionManualGainFactor = 0f;
			refgain = 0f;
			reflum = 0f;
			volref = 0f;
			whing.volume = 0f;
			whing.pitch = 0f;
		}

		private void FixedUpdate()
		{
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Invalid comparison between Unknown and I4
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: 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_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)scopeL).enabled = true;
			scopeL.UpdateParameters();
			((Behaviour)scopeR).enabled = true;
			scopeR.UpdateParameters();
			if (isheadmounted)
			{
				armfake.transform.localEulerAngles = armreal.transform.localEulerAngles;
				phys.transform.SetParent(((Component)GM.CurrentMovementManager.Head).gameObject.transform);
				phys.transform.localPosition = Vector3.zero;
				phys.transform.localEulerAngles = Vector3.zero;
				velLinearWorldL = GM.CurrentMovementManager.Hands[0].Input.VelLinearWorld;
				velLinearWorldR = GM.CurrentMovementManager.Hands[1].Input.VelLinearWorld;
				if ((Object)(object)GM.CurrentMovementManager.Hands[0].m_currentInteractable == (Object)null && (int)HA.MAState == 0 && Vector3.Distance(GM.CurrentMovementManager.Hands[0].PalmTransform.position, slapdirUP.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdirUP.forward) < 60f && ((Vector3)(ref velLinearWorldL)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				else if ((Object)(object)GM.CurrentMovementManager.Hands[0].m_currentInteractable == (Object)null && (int)HA.MAState == 1 && Vector3.Distance(GM.CurrentMovementManager.Hands[0].PalmTransform.position, slapdirDown.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdirDown.forward) < 60f && ((Vector3)(ref velLinearWorldL)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				if ((Object)(object)GM.CurrentMovementManager.Hands[1].m_currentInteractable == (Object)null && (int)HA.MAState == 0 && Vector3.Distance(GM.CurrentMovementManager.Hands[1].PalmTransform.position, slapdirUP.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdirUP.forward) < 60f && ((Vector3)(ref velLinearWorldR)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				else if ((Object)(object)GM.CurrentMovementManager.Hands[1].m_currentInteractable == (Object)null && (int)HA.MAState == 1 && Vector3.Distance(GM.CurrentMovementManager.Hands[1].PalmTransform.position, slapdirDown.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdirDown.forward) < 60f && ((Vector3)(ref velLinearWorldR)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
			}
			if (powerknob.transform.localEulerAngles.x > 15f)
			{
				scopeL.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeL.nvDef.nightVisionTargetBrightness, 0f, ref refgain, offspeed);
				scopeL.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeL.nightVisionManualGainFactor, 0f, ref reflum, offspeed);
				scopeR.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeR.nvDef.nightVisionTargetBrightness, 0f, ref refgain, offspeed);
				scopeR.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeR.nightVisionManualGainFactor, 0f, ref reflum, offspeed);
				whing.volume = Mathf.SmoothDamp(whing.volume, 0f, ref volref, offspeed);
				whing.pitch = Mathf.SmoothDamp(whing.pitch, 0f, ref volref, offspeed);
				started = false;
			}
			else if (powerknob.transform.localEulerAngles.x < 15f)
			{
				scopeL.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeL.nightVisionManualGainFactor, 1f, ref reflum, onspeed);
				scopeR.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeR.nightVisionManualGainFactor, 1f, ref reflum, onspeed);
				whing.volume = Mathf.SmoothDamp(whing.volume, 0.5f, ref volref, onspeed);
				whing.pitch = Mathf.SmoothDamp(whing.pitch, 1.3f, ref volref, onspeed);
				if (!started)
				{
					scopeL.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeL.nvDef.nightVisionTargetBrightness, 1f, ref refgain, onspeed);
					scopeR.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeR.nvDef.nightVisionTargetBrightness, 1f, ref refgain, onspeed);
				}
				if (scopeL.nvDef.nightVisionTargetBrightness > 0.9f && scopeR.nvDef.nightVisionTargetBrightness > 0.9f)
				{
					started = true;
				}
			}
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)phys);
		}
	}
	public class PNV57EControlAdj : MonoBehaviour
	{
		public GameObject phys;

		public PIPScope scopeL;

		public PIPScope scopeR;

		public GameObject powerknob;

		public float refgain;

		public float reflum;

		public AudioEvent flip;

		public bool started = false;

		public float onspeed = 0.5f;

		public float offspeed = 2.5f;

		public bool isheadmounted = true;

		public AudioSource whing;

		public float volref;

		public float pitref;

		public float volume;

		public float pitch;

		public GameObject root;

		public int scopePara;

		private void Start()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			scopePara = GM.Options.SimulationOptions.ScopeRecursiveRendering;
			GM.Options.SimulationOptions.ScopeRecursiveRendering = 0;
			GM.RefreshQuality();
			powerknob.transform.localEulerAngles = new Vector3(30f, 0f, 0f);
			scopeL.nvDef.nightVisionTargetBrightness = 0f;
			scopeL.nightVisionManualGainFactor = 0f;
			scopeR.nvDef.nightVisionTargetBrightness = 0f;
			scopeR.nightVisionManualGainFactor = 0f;
			refgain = 0f;
			reflum = 0f;
			volref = 0f;
			pitref = 0f;
			whing.volume = 0f;
			whing.pitch = 0f;
		}

		private void FixedUpdate()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			root.transform.localPosition = new Vector3(0f, 0f, 0f);
			((Behaviour)scopeL).enabled = true;
			scopeL.UpdateParameters();
			((Behaviour)scopeR).enabled = true;
			scopeR.UpdateParameters();
			if (isheadmounted)
			{
				phys.transform.SetParent(((Component)GM.CurrentMovementManager.Head).gameObject.transform);
				phys.transform.localPosition = Vector3.zero;
				phys.transform.localEulerAngles = Vector3.zero;
			}
			if (powerknob.transform.localEulerAngles.x > 15f)
			{
				scopeL.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeL.nvDef.nightVisionTargetBrightness, 0f, ref refgain, offspeed);
				scopeL.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeL.nightVisionManualGainFactor, 0f, ref reflum, offspeed);
				scopeR.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeR.nvDef.nightVisionTargetBrightness, 0f, ref refgain, offspeed);
				scopeR.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeR.nightVisionManualGainFactor, 0f, ref reflum, offspeed);
				whing.volume = Mathf.SmoothDamp(whing.volume, 0f, ref volref, offspeed);
				whing.pitch = Mathf.SmoothDamp(whing.pitch, 0f, ref pitref, offspeed);
				started = false;
			}
			else if (powerknob.transform.localEulerAngles.x < 15f)
			{
				scopeL.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeL.nightVisionManualGainFactor, 1f, ref reflum, onspeed);
				scopeR.nightVisionManualGainFactor = Mathf.SmoothDamp(scopeR.nightVisionManualGainFactor, 1f, ref reflum, onspeed);
				whing.volume = Mathf.SmoothDamp(whing.volume, volume, ref volref, onspeed);
				whing.pitch = Mathf.SmoothDamp(whing.pitch, pitch, ref pitref, onspeed);
				if (!started)
				{
					scopeL.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeL.nvDef.nightVisionTargetBrightness, 1f, ref refgain, onspeed);
					scopeR.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scopeR.nvDef.nightVisionTargetBrightness, 1f, ref refgain, onspeed);
				}
				if (scopeL.nvDef.nightVisionTargetBrightness > 0.9f && scopeR.nvDef.nightVisionTargetBrightness > 0.9f)
				{
					started = true;
				}
			}
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)phys);
			GM.Options.SimulationOptions.ScopeRecursiveRendering = scopePara;
			GM.RefreshQuality();
		}
	}
	public class PVS7Control : MonoBehaviour
	{
		public GameObject phys;

		public GameObject armreal;

		public GameObject armfake;

		public Vector3 velLinearWorldL;

		public Vector3 velLinearWorldR;

		public Transform slapdirUP;

		public Transform slapdirDown;

		public HeadAttachment HA;

		public PIPScope scope;

		public GameObject powerknob;

		public float refgain;

		public float reflum;

		public AudioEvent flip;

		public bool started = false;

		public float onspeed = 0.5f;

		public float offspeed = 2.5f;

		public bool isheadmounted = true;

		private void Start()
		{
			scope.nvDef.nightVisionTargetBrightness = 0f;
			scope.nightVisionManualGainFactor = 0f;
			refgain = 0f;
			reflum = 0f;
		}

		private void FixedUpdate()
		{
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Invalid comparison between Unknown and I4
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Invalid comparison between Unknown and I4
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)scope).enabled = true;
			scope.UpdateParameters();
			if (isheadmounted)
			{
				armfake.transform.localEulerAngles = armreal.transform.localEulerAngles;
				phys.transform.SetParent(((Component)GM.CurrentMovementManager.Head).gameObject.transform);
				phys.transform.localPosition = Vector3.zero;
				phys.transform.localEulerAngles = Vector3.zero;
				velLinearWorldL = GM.CurrentMovementManager.Hands[0].Input.VelLinearWorld;
				velLinearWorldR = GM.CurrentMovementManager.Hands[1].Input.VelLinearWorld;
				if ((Object)(object)GM.CurrentMovementManager.Hands[0].m_currentInteractable == (Object)null && (int)HA.MAState == 0 && Vector3.Distance(GM.CurrentMovementManager.Hands[0].PalmTransform.position, slapdirUP.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdirUP.forward) < 60f && ((Vector3)(ref velLinearWorldL)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				else if ((Object)(object)GM.CurrentMovementManager.Hands[0].m_currentInteractable == (Object)null && (int)HA.MAState == 1 && Vector3.Distance(GM.CurrentMovementManager.Hands[0].PalmTransform.position, slapdirDown.position) < 0.15f && Vector3.Angle(velLinearWorldL, slapdirDown.forward) < 60f && ((Vector3)(ref velLinearWorldL)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				if ((Object)(object)GM.CurrentMovementManager.Hands[1].m_currentInteractable == (Object)null && (int)HA.MAState == 0 && Vector3.Distance(GM.CurrentMovementManager.Hands[1].PalmTransform.position, slapdirUP.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdirUP.forward) < 60f && ((Vector3)(ref velLinearWorldR)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
				else if ((Object)(object)GM.CurrentMovementManager.Hands[1].m_currentInteractable == (Object)null && (int)HA.MAState == 1 && Vector3.Distance(GM.CurrentMovementManager.Hands[1].PalmTransform.position, slapdirDown.position) < 0.15f && Vector3.Angle(velLinearWorldR, slapdirDown.forward) < 60f && ((Vector3)(ref velLinearWorldR)).magnitude > 1.5f)
				{
					HA.ToggleFlip();
					SM.PlayCoreSound((FVRPooledAudioType)41, flip, phys.transform.position);
				}
			}
			if (powerknob.transform.localEulerAngles.x > 15f)
			{
				scope.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scope.nvDef.nightVisionTargetBrightness, 0f, ref refgain, offspeed);
				scope.nightVisionManualGainFactor = Mathf.SmoothDamp(scope.nightVisionManualGainFactor, 0f, ref reflum, offspeed);
				started = false;
			}
			else if (powerknob.transform.localEulerAngles.x < 15f)
			{
				scope.nightVisionManualGainFactor = Mathf.SmoothDamp(scope.nightVisionManualGainFactor, 1f, ref reflum, onspeed);
				if (!started)
				{
					scope.nvDef.nightVisionTargetBrightness = Mathf.SmoothDamp(scope.nvDef.nightVisionTargetBrightness, 1f, ref refgain, onspeed);
				}
				if (scope.nvDef.nightVisionTargetBrightness > 0.9f)
				{
					started = true;
				}
			}
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)phys);
		}
	}
}
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 references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		if (_isBroken)
		{
			return;
		}
		_isBroken = true;
		ApplyVisualState();
		if ((Object)(object)LocalAudioSource != (Object)null && (Object)(object)BreakClip != (Object)null)
		{
			LocalAudioSource.PlayOneShot(BreakClip);
		}
		else if ((Object)(object)BreakClip != (Object)null)
		{
			AudioSource.PlayClipAtPoint(BreakClip, ((Component)this).transform.position, 1f);
		}
		if (SpawnDebrisOnBreak && (Object)(object)DebrisPrefab != (Object)null)
		{
			Vector3 position = ((Component)this).transform.position;
			Quaternion rot = Quaternion.identity;
			if ((Object)(object)_lastShotFirearm != (Object)null)
			{
				try
				{
					Transform muzzle = _lastShotFirearm.GetMuzzle();
					if ((Object)(object)muzzle != (Object)null)
					{
						position = muzzle.position;
						rot = muzzle.rotation;
					}
					else
					{
						position = ((Component)_lastShotFirearm).transform.position;
					}
				}
				catch
				{
				}
			}
			SpawnDebrisAt(position, rot, 1f);
		}
		if (AutoRepairAfterSeconds > 0f)
		{
			((MonoBehaviour)this).StartCoroutine(AutoRepairCoroutine(AutoRepairAfterSeconds));
		}
	}

	private IEnumerator AutoRepairCoroutine(float seconds)
	{
		yield return (object)new WaitForSeconds(seconds);
		RepairToFull();
	}

	protected void ApplyVisualState()
	{
		if ((Object)(object)IntactVisual != (Object)null)
		{
			IntactVisual.SetActive(!_isBroken);
		}
		if ((Object)(object)BrokenVisual != (Object)null)
		{
			BrokenVisual.SetActive(_isBroken);
		}
	}

	public void RepairToFull()
	{
		Integrity = MaxIntegrity;
		_isBroken = false;
		ApplyVisualState();
		UpdateHoleVisualImmediate();
	}

	private void SpawnDebrisAt(Vector3 pos, Quaternion rot, float damageT)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)DebrisPrefab == (Object)null)
		{
			return;
		}
		try
		{
			GameObject val = Object.Instantiate<GameObject>(DebrisPrefab, pos, rot);
			if ((Object)(object)val != (Object)null)
			{
				Vector3 localScale = Vector3.Lerp(DebrisScaleMin, DebrisScaleMax, Mathf.Clamp01(damageT));
				val.transform.localScale = localScale;
				if (DebrisLifetime > 0f)
				{
					Object.Destroy((Object)(object)val, DebrisLifetime);
				}
			}
		}
		catch
		{
		}
	}

	private IEnumerator AnimateHoleScale(Transform tform, Vector3 target, float duration)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)tform == (Object)null)
		{
			yield break;
		}
		Vector3 start = tform.localScale;
		float elapsed = 0f;
		while (elapsed < duration)
		{
			elapsed += Time.deltaTime;
			float k = Mathf.Clamp01(elapsed / duration);
			try
			{
				tform.localScale = Vector3.Lerp(start, target, k);
			}
			catch
			{
			}
			yield return null;
		}
		try
		{
			tform.localScale = target;
		}
		catch
		{
		}
		_holeAnimCoroutine = null;
	}

	private void UpdateHoleVisualImmediate()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)HoleVisual == (Object)null)
		{
			return;
		}
		float num = 1f - (float)Integrity / (float)MaxIntegrity;
		Vector3 localScale = Vector3.Lerp(HoleScaleAtIntact, HoleScaleAtBroken, Mathf.Clamp01(num));
		try
		{
			HoleVisual.localScale = localScale;
		}
		catch
		{
		}
	}

	private void UpdateHoleVisual()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)HoleVisual == (Object)null))
		{
			float num = 1f - (float)Integrity / (float)MaxIntegrity;
			Vector3 target = Vector3.Lerp(HoleScaleAtIntact, HoleScaleAtBroken, Mathf.Clamp01(num));
			if (_holeAnimCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_holeAnimCoroutine);
			}
			_holeAnimCoroutine = ((MonoBehaviour)this).StartCoroutine(AnimateHoleScale(HoleVisual, target, HoleScaleAnimTime));
		}
	}

	public override void AttachToMount(FVRFireArmAttachmentMount m, bool playSound)
	{
		((Suppressor)this).AttachToMount(m, playSound);
		_cachedFirearm = null;
		try
		{
			if (!((Object)(object)m != (Object)null))
			{
				return;
			}
			FVRFireArmAttachmentMount rootMount = m.GetRootMount();
			if ((Object)(object)rootMount != (Object)null && rootMount.Parent is FVRFireArm)
			{
				ref FVRFireArm cachedFirearm = ref _cachedFirearm;
				FVRPhysicalObject parent = rootMount.Parent;
				cachedFirearm = (FVRFireArm)(object)((parent is FVRFireArm) ? parent : null);
				return;
			}
			Transform val = ((Component)m).transform;
			while ((Object)(object)val != (Object)null)
			{
				FVRFireArm component = ((Component)val).GetComponent<FVRFireArm>();
				if ((Object)(object)component != (Object)null)
				{
					_cachedFirearm = component;
					break;
				}
				val = val.parent;
			}
		}
		catch
		{
		}
	}
}
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(FVRPhysicalObject))]
public class Boomerang : MonoBehaviour
{
	public enum HandPreference
	{
		Nearest,
		Left,
		Right
	}

	public float spinTorque = 150f;

	public float lateralStrength = 8f;

	public float returnStrength = 40f;

	public float returnDelay = 0.6f;

	public float maxLifetime = 10f;

	public float pickupRadius = 0.4f;

	public bool autoAttachToHand = false;

	[Tooltip("How strongly lift counteracts gravity while in flight. 1 = full gravity cancel, 0 = no lift.")]
	public float liftFactor = 1.05f;

	[Tooltip("Minimum speed (m/s) the boomerang must be moving to be considered airborne. Below this it is treated as grounded.")]
	public float minAirborneSpeed = 1.5f;

	[Tooltip("Minimum release speed (m/s) required to arm the return. Below this it is treated as a drop, not a throw.")]
	public float minThrowSpeed = 3f;

	[Tooltip("Extra upward force applied during the return arc to maintain height.")]
	public float returnLiftBias = 2.5f;

	public HandPreference attachPreference = HandPreference.Nearest;

	private Rigidbody rb;

	private FVRPhysicalObject phys;

	private Transform playerHead;

	private bool wasHeldLastFrame;

	private bool thrown;

	private bool returnArmed;

	private bool returning;

	private float thrownTime;

	private float releaseSpeedAtThrow = 0f;

	private float origDrag = 0f;

	private float origAngularDrag = 0.05f;

	private void Awake()
	{
		rb = ((Component)this).GetComponent<Rigidbody>();
		phys = ((Component)this).GetComponent<FVRPhysicalObject>();
		playerHead = ((!((Object)(object)GM.CurrentPlayerBody != (Object)null)) ? null : GM.CurrentPlayerBody.Head);
		if ((Object)(object)rb != (Object)null)
		{
			rb.collisionDetectionMode = (CollisionDetectionMode)2;
			rb.maxAngularVelocity = Mathf.Max(rb.maxAngularVelocity, 200f);
			origDrag = rb.drag;
			origAngularDrag = rb.angularDrag;
		}
	}

	private void FixedUpdate()
	{
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0332: 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_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0395: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Unknown result type (might be due to invalid IL or missing references)
		//IL_0418: Unknown result type (might be due to invalid IL or missing references)
		//IL_041d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0440: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		//IL_0467: Unknown result type (might be due to invalid IL or missing references)
		//IL_046f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0476: Unknown result type (might be due to invalid IL or missing references)
		//IL_0487: Unknown result type (might be due to invalid IL or missing references)
		//IL_0492: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_053a: Unknown result type (might be due to invalid IL or missing references)
		//IL_054a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)phys == (Object)null || (Object)(object)rb == (Object)null)
		{
			return;
		}
		bool isHeld = ((FVRInteractiveObject)phys).IsHeld;
		if (wasHeldLastFrame && !isHeld)
		{
			Vector3 velocity = rb.velocity;
			releaseSpeedAtThrow = ((Vector3)(ref velocity)).magnitude;
			thrown = true;
			returning = false;
			thrownTime = Time.time;
			returnArmed = releaseSpeedAtThrow >= minThrowSpeed;
			float num = Mathf.Clamp01(releaseSpeedAtThrow / Mathf.Max(minThrowSpeed, 0.0001f));
			float num2 = spinTorque * Mathf.Lerp(0.35f, 1f, num);
			rb.maxAngularVelocity = Mathf.Max(rb.maxAngularVelocity, 200f);
			if (num > 0.01f)
			{
				rb.AddTorque(((Component)this).transform.up * num2, (ForceMode)2);
			}
			rb.drag = Mathf.Min(origDrag, 0.08f);
			rb.angularDrag = Mathf.Min(origAngularDrag, 0.02f);
		}
		wasHeldLastFrame = isHeld;
		if (!thrown)
		{
			return;
		}
		Vector3 velocity2 = rb.velocity;
		if (!(((Vector3)(ref velocity2)).sqrMagnitude > minAirborneSpeed * minAirborneSpeed) && Time.time - thrownTime > returnDelay)
		{
			ResetState();
			rb.velocity = Vector3.zero;
			rb.angularVelocity = Vector3.zero;
			rb.drag = origDrag;
			rb.angularDrag = origAngularDrag;
			return;
		}
		Vector3 velocity3 = rb.velocity;
		if (((Vector3)(ref velocity3)).sqrMagnitude > 0.001f && releaseSpeedAtThrow >= minThrowSpeed)
		{
			Vector3 val = Vector3.Cross(((Vector3)(ref velocity3)).normalized, ((Component)this).transform.up);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (!float.IsNaN(normalized.x))
			{
				float num3 = Mathf.Clamp01(((Vector3)(ref velocity3)).magnitude / Mathf.Max(minThrowSpeed, 1f));
				rb.AddForce(normalized * lateralStrength * Mathf.Lerp(0.6f, 1f, num3), (ForceMode)5);
			}
			Rigidbody obj = rb;
			Vector3 gravity = Physics.gravity;
			Vector3 val2 = -((Vector3)(ref gravity)).normalized;
			Vector3 gravity2 = Physics.gravity;
			obj.AddForce(val2 * ((Vector3)(ref gravity2)).magnitude * liftFactor * 0.9f, (ForceMode)5);
			float num4 = Mathf.Clamp01(releaseSpeedAtThrow / Mathf.Max(minThrowSpeed, 0.0001f));
			rb.AddTorque(((Component)this).transform.up * (spinTorque * 0.01f * Mathf.Lerp(0.6f, 1f, num4)), (ForceMode)5);
		}
		if (!returning && returnArmed && Time.time - thrownTime >= returnDelay)
		{
			returning = true;
		}
		if (returning)
		{
			Vector3 val3 = ((!((Object)(object)playerHead != (Object)null)) ? Vector3.zero : playerHead.position);
			if (autoAttachToHand)
			{
				FVRViveHand val4 = FindPreferredHand();
				if ((Object)(object)val4 != (Object)null)
				{
					val3 = ((!((Object)(object)val4.PoseOverride != (Object)null)) ? ((Component)val4).transform.position : val4.PoseOverride.position);
				}
			}
			if (val3 != Vector3.zero)
			{
				Vector3 val5 = val3 - ((Component)this).transform.position;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				Vector3 val6 = ((!(magnitude > 0.0001f)) ? Vector3.zero : ((Vector3)(ref val5)).normalized);
				float num5 = Mathf.Sqrt(Mathf.Clamp01(magnitude / 4f)) + 0.3f;
				rb.AddForce(val6 * returnStrength * num5, (ForceMode)5);
				rb.AddForce(Vector3.up * returnLiftBias, (ForceMode)5);
				rb.AddForce(-rb.velocity * 0.03f, (ForceMode)5);
				if (magnitude <= pickupRadius)
				{
					if (autoAttachToHand)
					{
						FVRViveHand val7 = FindPreferredHand();
						if ((Object)(object)val7 != (Object)null)
						{
							val7.RetrieveObject(phys);
							ResetState();
							rb.drag = origDrag;
							rb.angularDrag = origAngularDrag;
							return;
						}
					}
					ResetState();
					rb.velocity = Vector3.zero;
					rb.angularVelocity = Vector3.zero;
					rb.drag = origDrag;
					rb.angularDrag = origAngularDrag;
					return;
				}
			}
		}
		if (Time.time - thrownTime > maxLifetime)
		{
			ResetState();
			rb.velocity = Vector3.zero;
			rb.angularVelocity = Vector3.zero;
			rb.drag = origDrag;
			rb.angularDrag = origAngularDrag;
		}
	}

	private void ResetState()
	{
		thrown = false;
		returning = false;
		returnArmed = false;
		releaseSpeedAtThrow = 0f;
	}

	private FVRViveHand FindPreferredHand()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		FVRViveHand[] array = Object.FindObjectsOfType<FVRViveHand>();
		if (array == null || array.Length == 0)
		{
			return null;
		}
		FVRViveHand result = null;
		if (attachPreference == HandPreference.Left)
		{
			FVRViveHand[] array2 = array;
			foreach (FVRViveHand val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !val.IsThisTheRightHand)
				{
					result = val;
					break;
				}
			}
			return result;
		}
		if (attachPreference == HandPreference.Right)
		{
			FVRViveHand[] array3 = array;
			foreach (FVRViveHand val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.IsThisTheRightHand)
				{
					result = val2;
					break;
				}
			}
			return result;
		}
		float num = float.MaxValue;
		Vector3 position = ((Component)this).transform.position;
		FVRViveHand[] array4 = array;
		foreach (FVRViveHand val3 in array4)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				Vector3 val4 = ((!((Object)(object)val3.PoseOverride != (Object)null)) ? ((Component)val3).transform.position : val3.PoseOverride.position);
				Vector3 val5 = val4 - position;
				float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					result = val3;
				}
			}
		}
		return result;
	}
}
namespace VolksScripts
{
	public class Bulletholder : FVRPhysicalObject
	{
		[Header("Bullet Slots")]
		[Tooltip("Positions where rounds will be placed. Order defines fill order.")]
		public List<Transform> BulletSlots = new List<Transform>();

		[Header("Visuals (optional)")]
		public MeshRenderer SlotHighlight;

		[Header("Behaviors")]
		public bool ClearVelocityOnPlace = true;

		[Header("Capacity")]
		public int capacity = 8;

		private FVRFireArmRound[] _storedRounds;

		public int NumRounds { get; private set; }

		protected void Awake()
		{
			((FVRPhysicalObject)this).Awake();
			if (BulletSlots == null)
			{
				BulletSlots = new List<Transform>();
			}
			if (capacity <= 0 || capacity > BulletSlots.Count)
			{
				capacity = BulletSlots.Count;
			}
			_storedRounds = (FVRFireArmRound[])(object)new FVRFireArmRound[capacity];
			NumRounds = 0;
			UpdateBulletDisplay();
		}

		public bool TryPlace(FVRFireArmRound round)
		{
			if ((Object)(object)round == (Object)null || NumRounds >= capacity || capacity <= 0)
			{
				Debug.Log((object)"TryPlace failed: round is null or holder is full.");
				return false;
			}
			int num = FindFirstFreeSlot();
			if (num < 0)
			{
				Debug.Log((object)"TryPlace failed: no free slot found.");
				return false;
			}
			Debug.Log((object)("TryPlace: placing round at slot " + num));
			return PlaceAtIndex(round, num);
		}

		public bool PlaceAtIndex(FVRFireArmRound round, int index)
		{
			if ((Object)(object)round == (Object)null || index < 0 || index >= capacity || index >= BulletSlots.Count)
			{
				Debug.Log((object)("PlaceAtIndex failed: invalid round or index " + index));
				return false;
			}
			if ((Object)(object)BulletSlots[index] == (Object)null)
			{
				Debug.Log((object)("PlaceAtIndex failed: slot " + index + " is null"));
				return false;
			}
			if ((Object)(object)_storedRounds[index] != (Object)null)
			{
				Debug.Log((object)("PlaceAtIndex failed: slot " + index + " already occupied"));
				return false;
			}
			PlaceAtSlot(round, BulletSlots[index]);
			_storedRounds[index] = round;
			NumRounds++;
			UpdateBulletDisplay();
			if ((Object)(object)round != (Object)null)
			{
				((FVRInteractiveObject)round).ForceBreakInteraction();
			}
			Debug.Log((object)("PlaceAtIndex: round placed at slot " + index));
			return true;
		}

		public FVRFireArmRound RemoveAt(int index)
		{
			if (index < 0 || index >= capacity)
			{
				return null;
			}
			FVRFireArmRound val = _storedRounds[index];
			if ((Object)(object)val != (Object)null)
			{
				_storedRounds[index] = null;
				NumRounds--;
				UpdateBulletDisplay();
			}
			return val;
		}

		public FVRFireArmRound GetAt(int index)
		{
			if (index < 0 || index >= capacity)
			{
				return null;
			}
			return _storedRounds[index];
		}

		public void ClearAll()
		{
			for (int i = 0; i < capacity; i++)
			{
				_storedRounds[i] = null;
			}
			NumRounds = 0;
			UpdateBulletDisplay();
		}

		private void PlaceAtSlot(FVRFireArmRound round, Transform slot)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)slot == (Object)null))
			{
				Vector3 up = ((Component)this).transform.up;
				Rigidbody val = ((!((Object)(object)((FVRPhysicalObject)round).RootRigidbody != (Object)null)) ? ((Component)round).GetComponent<Rigidbody>() : ((FVRPhysicalObject)round).RootRigidbody);
				if ((Object)(object)val != (Object)null && ClearVelocityOnPlace)
				{
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
				((Component)round).transform.rotation = Quaternion.LookRotation(((Component)this).transform.forward, up);
				if (TryGetBaseAndTipAlongUp(round, up, out var baseAlongUp, out var _))
				{
					float num = Vector3.Dot(slot.position, up);
					float num2 = num - baseAlongUp;
					Transform transform = ((Component)round).transform;
					transform.position += up * num2;
					Collider componentInChildren = ((Component)round).GetComponentInChildren<Collider>();
					Bounds bounds = componentInChildren.bounds;
					Vector3 val2 = Vector3.ProjectOnPlane(slot.position, up);
					Vector3 val3 = Vector3.ProjectOnPlane(((Bounds)(ref bounds)).center, up);
					Vector3 val4 = val2 - val3;
					Transform transform2 = ((Component)round).transform;
					transform2.position += val4;
				}
				else
				{
					((Component)round).transform.position = slot.position;
				}
				if ((Object)(object)SlotHighlight != (Object)null)
				{
					((Component)SlotHighlight).transform.position = slot.position;
				}
			}
		}

		private bool TryGetBaseAndTipAlongUp(FVRFireArmRound round, Vector3 up, out float baseAlongUp, out float tipAlongUp)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			baseAlongUp = (tipAlongUp = 0f);
			Collider componentInChildren = ((Component)round).GetComponentInChildren<Collider>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			Bounds bounds = componentInChildren.bounds;
			baseAlongUp = Vector3.Dot(((Bounds)(ref bounds)).min, up);
			tipAlongUp = Vector3.Dot(((Bounds)(ref bounds)).max, up);
			return true;
		}

		private int FindFirstFreeSlot()
		{
			for (int i = 0; i < capacity; i++)
			{
				if (i < BulletSlots.Count && !((Object)(object)BulletSlots[i] == (Object)null) && (Object)(object)_storedRounds[i] == (Object)null)
				{
					return i;
				}
			}
			return -1;
		}

		public void UpdateBulletDisplay()
		{
			for (int i = 0; i < BulletSlots.Count; i++)
			{
				if ((Object)(object)BulletSlots[i] != (Object)null)
				{
				}
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			FVRFireArmRound componentInParent = ((Component)other).GetComponentInParent<FVRFireArmRound>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				TryPlace(componentInParent);
			}
		}
	}
	public class BulletholderReloadTrigger : MonoBehaviour
	{
		public Bulletholder Holder;

		private void OnTriggerEnter(Collider other)
		{
			if ((Object)(object)Holder == (Object)null)
			{
				Debug.LogWarning((object)"BulletholderReloadTrigger: Holder not assigned.");
				return;
			}
			FVRFireArmRound componentInParent = ((Component)other).GetComponentInParent<FVRFireArmRound>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				Holder.TryPlace(componentInParent);
			}
		}
	}
	public class ShellCaddy : FVRFireArmMagazine
	{
		[Header("Caddy Configuration")]
		public int MaxCapacity = 8;

		public Transform DisplayContainer;

		private readonly List<FireArmRoundClass> roundClassData = new List<FireArmRoundClass>();

		private int currentCapacity;

		private bool hasRoundType;

		private FireArmRoundType storedRoundType;

		private GameObject displayRoot;

		public override void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArmMagazine)this).Awake();
			roundClassData.Clear();
			currentCapacity = 0;
			hasRoundType = false;
			storedRoundType = (FireArmRoundType)0;
		}

		public override void Start()
		{
			((FVRInteractiveObject)this).Start();
			UpdateDisplayMag();
		}

		public void AddShell(FVRFireArmRound shell)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0081: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)shell == (Object)null || !((FVRPhysicalObject)shell).m_isVisible || currentCapacity >= MaxCapacity)
			{
				Debug.LogWarning((object)"Invalid shell or caddy is full.");
				return;
			}
			if (!hasRoundType)
			{
				hasRoundType = true;
				storedRoundType = shell.RoundType;
			}
			if (shell.RoundType != storedRoundType)
			{
				Debug.LogWarning((object)"Shell type mismatch.");
				return;
			}
			roundClassData.Add(shell.RoundClass);
			currentCapacity++;
			Object.Destroy((Object)(object)((Component)shell).gameObject);
			UpdateDisplayMag();
		}

		public FVRFireArmRound RemoveShell()
		{
			//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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			if (currentCapacity == 0)
			{
				Debug.LogWarning((object)"No shells to remove.");
				return null;
			}
			FireArmRoundClass val = roundClassData[currentCapacity - 1];
			roundClassData.RemoveAt(currentCapacity - 1);
			currentCapacity--;
			if (!hasRoundType || (Object)(object)DisplayContainer == (Object)null)
			{
				UpdateDisplayMag();
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((AnvilAsset)AM.GetRoundSelfPrefab(storedRoundType, val)).GetGameObject(), DisplayContainer.position, DisplayContainer.rotation);
			UpdateDisplayMag();
			return val2.GetComponent<FVRFireArmRound>();
		}

		private void UpdateDisplayMag()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)displayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)displayRoot);
				displayRoot = null;
			}
			if (currentCapacity <= 0 || (Object)(object)DisplayContainer == (Object)null || !hasRoundType)
			{
				return;
			}
			displayRoot = new GameObject("ShellCaddyDisplay");
			displayRoot.transform.SetParent(DisplayContainer, false);
			for (int i = 0; i < currentCapacity; i++)
			{
				GameObject val = Object.Instantiate<GameObject>(((AnvilAsset)AM.GetRoundSelfPrefab(storedRoundType, roundClassData[i])).GetGameObject(), displayRoot.transform);
				val.transform.localPosition = Vector3.down * (float)i * 0.02f;
				val.transform.localRotation = Quaternion.identity;
				Rigidbody component = val.GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = true;
					component.detectCollisions = false;
				}
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>();
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					componentsInChildren[j].enabled = false;
				}
			}
		}

		public void ResetCaddy()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			roundClassData.Clear();
			currentCapacity = 0;
			hasRoundType = false;
			storedRoundType = (FireArmRoundType)0;
			if ((Object)(object)displayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)displayRoot);
				displayRoot = null;
			}
			UpdateDisplayMag();
		}

		public void HandleCollision(Collider other)
		{
			FVRFireArmRound component = ((Component)other).GetComponent<FVRFireArmRound>();
			if ((Object)(object)component != (Object)null)
			{
				AddShell(component);
			}
		}
	}
	public class ShellCaddy_Reception : MonoBehaviour
	{
		public ShellCaddy caddy;

		private void OnTriggerStay(Collider other)
		{
			caddy.HandleCollision(other);
		}
	}
}
public class Compass : FVRPhysicalObject
{
	[Header("Compass Lid")]
	public Transform Lid;

	public float openRotationX = 90f;

	public float openRotationY = 0f;

	public float openRotationZ = 0f;

	public float closeRotationX = 0f;

	public float closeRotationY = 0f;

	public float closeRotationZ = 0f;

	public float lidRotationSpeed = 5f;

	public AudioSource openCloseAudioSource;

	public AudioClip openClip;

	public AudioClip closeClip;

	[Header("Compass Needle")]
	public Transform Needle;

	[Tooltip("The direction that is considered North. Default is (0,0,1) (Z+).")]
	public Vector3 NorthDirection = Vector3.forward;

	public float needleSmoothTime = 0.5f;

	public float needleWobbleAmount = 2f;

	public float needleWobbleSpeed = 5f;

	private bool isOpen = false;

	private bool isTouching = false;

	private Vector2 initTouch = Vector2.zero;

	private Vector2 lastTouchPoint = Vector2.zero;

	private float currentNeedleAngle = 0f;

	private float needleVelocity = 0f;

	private void Update()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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 ref