Decompiled source of New Universal Speedloader v1.0.1

New_Universal_Speedloader.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 System.Text;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using H3VRUtils;
using HarmonyLib;
using OpenScripts2;
using OtherLoader;
using Steamworks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
using UnityEngine.UI;

[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]
[ExecuteInEditMode]
public class HolographicSightCustom : MonoBehaviour
{
	public Transform VirtualQuad;

	public float Scale = 1f;

	public bool SizeCompensation = true;

	private MaterialPropertyBlock m_block;

	private void OnEnable()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		m_block = new MaterialPropertyBlock();
		((Component)this).GetComponent<Renderer>().SetPropertyBlock(m_block);
	}

	private void OnWillRenderObject()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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)
		Vector3 val = ((Component)this).transform.InverseTransformPoint(((Component)VirtualQuad).transform.position);
		m_block.SetVector("_Offset", Vector4.op_Implicit(val));
		m_block.SetFloat("_Scale", Scale);
		m_block.SetFloat("_SizeCompensation", (!SizeCompensation) ? 0f : 1f);
		((Component)this).GetComponent<Renderer>().SetPropertyBlock(m_block);
	}
}
public class AudioPlayer : StateMachineBehaviour
{
	public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
	{
		AudioSource component = ((Component)animator).GetComponent<AudioSource>();
		component.Play();
	}
}
namespace Niko666
{
	public class ChargeRifleBatteryLid : MonoBehaviour
	{
		[Header("References")]
		public FVRFireArm Weapon;

		[Tooltip("Pivot of the battery cover. Rotates from its authored pose to OpenLocalEuler.")]
		public Transform LidPivot;

		[Tooltip("The little release lever under the receiver. A hand squeezing here opens the bay.")]
		public Transform ReleaseLever;

		[Tooltip("Point a hand has to sweep through to slap the cover shut. Defaults to the lid pivot.")]
		public Transform SlapPoint;

		[Header("Motion")]
		[Tooltip("Cover rotation while open, in degrees around the pivot's local axes.")]
		public Vector3 OpenLocalEuler = new Vector3(0f, 0f, -115f);

		public float OpenTime = 0.2f;

		public float CloseTime = 0.09f;

		[Tooltip("Seconds after the lid starts opening before the cell is released.")]
		public float EjectDelay = 0.1f;

		[Tooltip("Push given to the ejected cell, in world space, so it pops clear of the bay.")]
		public Vector3 EjectVelocity = new Vector3(0f, 0.7f, 0.1f);

		public float EjectSpin = 90f;

		[Header("Interaction")]
		[Tooltip("How close a hand must be to the release lever to open the bay.")]
		public float ReleaseProximity = 0.09f;

		[Tooltip("How close a hand must come to the cover to slap it shut.")]
		public float SlapProximity = 0.14f;

		[Tooltip("Minimum hand speed toward the cover for a slap, in m/s.")]
		public float SlapMinSpeed = 1.1f;

		[Tooltip("A freshly opened bay ignores slaps for this long, so the opening motion cannot close it again.")]
		public float SlapCooldown = 0.35f;

		[Header("Audio")]
		public AudioClip OpenClip;

		public AudioClip EjectClip;

		public AudioClip CloseClip;

		[Range(0f, 1f)]
		public float Volume = 1f;

		[Header("State (read-only)")]
		public bool IsOpen;

		private float _lidT;

		private float _openTime = -1f;

		private bool _ejected;

		private float _lastCloseTime = -10f;

		private Vector3 _closedEuler;

		private bool _captured;

		public bool IsOpening => _lidT > 0f && _lidT < 1f && IsOpen;

		private void Awake()
		{
			if ((Object)(object)Weapon == (Object)null)
			{
				Weapon = ((Component)this).GetComponent<FVRFireArm>();
			}
			if ((Object)(object)SlapPoint == (Object)null)
			{
				SlapPoint = LidPivot;
			}
			Capture();
		}

		private void Update()
		{
			float deltaTime = Time.deltaTime;
			if (!IsOpen)
			{
				if (CanOpenNow())
				{
					Open();
				}
			}
			else
			{
				_lidT = Mathf.MoveTowards(_lidT, 1f, (!(OpenTime <= 0f)) ? (deltaTime / OpenTime) : 999f);
				if (!_ejected && _openTime >= 0f && Time.time - _openTime >= EjectDelay)
				{
					_ejected = true;
					EjectCell();
				}
				if (Time.time - _openTime > SlapCooldown && HandSlapped())
				{
					Close();
				}
			}
			if (!IsOpen && _lidT > 0f)
			{
				_lidT = Mathf.MoveTowards(_lidT, 0f, (!(CloseTime <= 0f)) ? (deltaTime / CloseTime) : 999f);
			}
			ApplyLidPose();
		}

		private void ApplyLidPose()
		{
			//IL_003f: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)LidPivot == (Object)null) && _captured)
			{
				float num = Mathf.SmoothStep(0f, 1f, _lidT);
				LidPivot.localEulerAngles = Vector3.Lerp(_closedEuler, OpenLocalEuler, num);
			}
		}

		private void Capture()
		{
			//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)
			if (!_captured && !((Object)(object)LidPivot == (Object)null))
			{
				_closedEuler = LidPivot.localEulerAngles;
				_captured = true;
			}
		}

		public void Open()
		{
			//IL_005e: 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)
			Capture();
			if (!IsOpen)
			{
				IsOpen = true;
				_openTime = Time.time;
				_ejected = false;
				PlayAt(OpenClip, (!((Object)(object)LidPivot != (Object)null)) ? ((Component)this).transform.position : LidPivot.position);
			}
		}

		public void Close()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				IsOpen = false;
				_lastCloseTime = Time.time;
				PlayAt(CloseClip, (!((Object)(object)SlapPoint != (Object)null)) ? ((Component)this).transform.position : SlapPoint.position);
				BuzzHands(0.5f);
			}
		}

		public void ForceClose()
		{
			IsOpen = false;
		}

		private bool CanOpenNow()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Weapon == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((FVRInteractiveObject)Weapon).m_hand == (Object)null)
			{
				return false;
			}
			if ((Object)(object)ReleaseLever == (Object)null)
			{
				return false;
			}
			FVRViveHand[] hands = GM.CurrentMovementManager.Hands;
			foreach (FVRViveHand val in hands)
			{
				if (!((Object)(object)val == (Object)null) && !(Vector3.Distance(((Component)val).transform.position, ReleaseLever.position) > ReleaseProximity) && (val.Input.GripPressed || val.Input.TriggerPressed || val.Input.BYButtonPressed))
				{
					return true;
				}
			}
			return false;
		}

		private bool HandSlapped()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00a7: 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)
			if ((Object)(object)SlapPoint == (Object)null)
			{
				return false;
			}
			FVRViveHand[] hands = GM.CurrentMovementManager.Hands;
			foreach (FVRViveHand val in hands)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Vector3 val2 = SlapPoint.position - ((Component)val).transform.position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!(magnitude > SlapProximity))
				{
					Vector3 velLinearWorld = val.Input.VelLinearWorld;
					Vector3 val3 = ((!(magnitude > 0.0001f)) ? Vector3.forward : (val2 / magnitude));
					float num = Vector3.Dot(velLinearWorld, val3);
					if (num >= SlapMinSpeed)
					{
						return true;
					}
					if (magnitude < SlapProximity * 0.6f && ((Vector3)(ref velLinearWorld)).magnitude > SlapMinSpeed * 0.5f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void EjectCell()
		{
			//IL_0068: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Weapon == (Object)null || (Object)(object)Weapon.Magazine == (Object)null)
			{
				return;
			}
			FVRFireArmMagazine magazine = Weapon.Magazine;
			Weapon.EjectMag(false);
			if (!((Object)(object)magazine == (Object)null))
			{
				PlayAt(EjectClip, ((Component)magazine).transform.position);
				if ((Object)(object)((FVRPhysicalObject)magazine).RootRigidbody != (Object)null)
				{
					Vector3 velocity = ((Component)Weapon).transform.TransformDirection(EjectVelocity);
					((FVRPhysicalObject)magazine).RootRigidbody.velocity = velocity;
					((FVRPhysicalObject)magazine).RootRigidbody.angularVelocity = Random.insideUnitSphere * EjectSpin;
				}
			}
		}

		private void BuzzHands(float strength)
		{
			if (!((Object)(object)Weapon == (Object)null) && !((Object)(object)((FVRInteractiveObject)Weapon).m_hand == (Object)null))
			{
				((FVRInteractiveObject)Weapon).m_hand.Buzz(((FVRInteractiveObject)Weapon).m_hand.Buzzer.Buzz_BeginInteraction);
			}
		}

		private void PlayAt(AudioClip clip, Vector3 pos)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)clip == (Object)null))
			{
				AudioEvent val = new AudioEvent();
				val.Clips.Add(clip);
				val.VolumeRange = new Vector2(Volume, Volume);
				val.PitchRange = new Vector2(0.97f, 1.03f);
				SM.PlayGenericSound(val, pos);
			}
		}
	}
	public class ChargeRifleDisplay : MonoBehaviour
	{
		public MeshRenderer ScreenRenderer;

		[Tooltip("Number of cells in the gauge. The gauge fills one cell at a time.")]
		public int Segments = 5;

		public int TexWidth = 64;

		public int TexHeight = 20;

		public Color BgColor = new Color(0.02f, 0.05f, 0.06f, 1f);

		public Color OffCellColor = new Color(0.06f, 0.16f, 0.18f, 1f);

		public Color OnCellColor = new Color(0.25f, 0.95f, 1f, 1f);

		public Color FullCellColor = new Color(1f, 0.92f, 0.55f, 1f);

		public Color ReloadColor = new Color(1f, 0.28f, 0.2f, 1f);

		[Tooltip("Blink period of the RELOAD warning, in seconds. 0 = solid.")]
		public float ReloadBlinkPeriod = 0.6f;

		[Tooltip("Skip repainting when nothing changed. Set to 0 to force a repaint every frame.")]
		public float MinRepaintInterval = 0f;

		private Texture2D _tex;

		private Color32[] _pixels;

		private float _lastLevel = -1f;

		private bool _lastReload;

		private float _nextRepaint;

		private static readonly string[] GlyphR = new string[7] { "11110", "10001", "10001", "11110", "10100", "10010", "10001" };

		private static readonly string[] GlyphE = new string[7] { "11111", "10000", "10000", "11110", "10000", "10000", "11111" };

		private static readonly string[] GlyphL = new string[7] { "10000", "10000", "10000", "10000", "10000", "10000", "11111" };

		private static readonly string[] GlyphO = new string[7] { "01110", "10001", "10001", "10001", "10001", "10001", "01110" };

		private static readonly string[] GlyphA = new string[7] { "01110", "10001", "10001", "11111", "10001", "10001", "10001" };

		private static readonly string[] GlyphD = new string[7] { "11110", "10001", "10001", "10001", "10001", "10001", "11110" };

		private void Awake()
		{
			Build();
		}

		private void Build()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_tex == (Object)null)
			{
				_tex = new Texture2D(TexWidth, TexHeight, (TextureFormat)4, false);
				((Texture)_tex).filterMode = (FilterMode)0;
				((Texture)_tex).wrapMode = (TextureWrapMode)1;
				_pixels = (Color32[])(object)new Color32[TexWidth * TexHeight];
			}
			if ((Object)(object)ScreenRenderer != (Object)null)
			{
				Material material = ((Renderer)ScreenRenderer).material;
				if ((Object)(object)material != (Object)null)
				{
					if (material.HasProperty("_MainTex"))
					{
						material.mainTexture = (Texture)(object)_tex;
					}
					if (material.HasProperty("_Color"))
					{
						material.color = Color.white;
					}
				}
			}
			SetCharge(0f);
		}

		public void SetCharge(float level01)
		{
			level01 = Mathf.Clamp01(level01);
			if (!(Mathf.Abs(level01 - _lastLevel) < 0.0005f) || _lastReload)
			{
				_lastLevel = level01;
				_lastReload = false;
				Paint(level01, reloadWarning: false);
			}
		}

		public void ShowReload()
		{
			bool flag = true;
			if (ReloadBlinkPeriod > 0.01f)
			{
				flag = Mathf.Repeat(Time.time, ReloadBlinkPeriod) > ReloadBlinkPeriod * 0.5f;
			}
			if (!_lastReload || !(_lastLevel < 0f) || !flag)
			{
			}
			_lastLevel = -1f;
			_lastReload = true;
			Paint(0f, flag);
		}

		public void Clear()
		{
			_lastLevel = 0f;
			_lastReload = false;
			Paint(0f, reloadWarning: false);
		}

		private void Paint(float level01, bool reloadWarning)
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (_pixels == null)
			{
				Build();
			}
			for (int i = 0; i < _pixels.Length; i++)
			{
				ref Color32 reference = ref _pixels[i];
				reference = Color32.op_Implicit(BgColor);
			}
			if (Segments < 1)
			{
				Segments = 1;
			}
			int num = 2;
			int num2 = TexWidth - num * 2;
			int num3 = 1;
			int num4 = (num2 - num3 * (Segments - 1)) / Segments;
			if (num4 < 1)
			{
				num4 = 1;
			}
			int h = TexHeight - num * 2;
			int num5 = Mathf.CeilToInt(level01 * (float)Segments);
			if (level01 > 0f && num5 < 1)
			{
				num5 = 1;
			}
			for (int j = 0; j < Segments; j++)
			{
				int x = num + j * (num4 + num3);
				Color c = OffCellColor;
				if (j < num5)
				{
					c = ((!(level01 >= 0.999f)) ? OnCellColor : FullCellColor);
				}
				FillRect(x, num, num4, h, c);
			}
			if (reloadWarning)
			{
				DrawString("RELOAD", ReloadColor);
			}
			_tex.SetPixels32(_pixels);
			_tex.Apply(false);
			_nextRepaint = Time.time + MinRepaintInterval;
		}

		private void FillRect(int x0, int y0, int w, int h, Color c)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = y0; i < y0 + h; i++)
			{
				if (i < 0 || i >= TexHeight)
				{
					continue;
				}
				for (int j = x0; j < x0 + w; j++)
				{
					if (j >= 0 && j < TexWidth)
					{
						ref Color32 reference = ref _pixels[i * TexWidth + j];
						reference = Color32.op_Implicit(c);
					}
				}
			}
		}

		private void DrawString(string text, Color c)
		{
			//IL_004b: 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)
			int num = 1;
			int num2 = 5 * num;
			int num3 = 7 * num;
			int num4 = 1;
			int num5 = text.Length * num2 + (text.Length - 1) * num4;
			int num6 = (TexWidth - num5) / 2;
			int y = (TexHeight - num3) / 2;
			FillRect(0, 0, TexWidth, TexHeight, BgColor);
			for (int i = 0; i < text.Length; i++)
			{
				string[] array = GlyphFor(text[i]);
				if (array != null)
				{
					DrawGlyph(array, num6, y, num, c);
				}
				num6 += num2 + num4;
			}
		}

		private void DrawGlyph(string[] g, int x0, int y0, int scale, Color c)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 7; i++)
			{
				string text = g[i];
				for (int j = 0; j < text.Length; j++)
				{
					if (text[j] == '1')
					{
						FillRect(x0 + j * scale, y0 + (6 - i) * scale, scale, scale, c);
					}
				}
			}
		}

		private static string[] GlyphFor(char ch)
		{
			return ch switch
			{
				'R' => GlyphR, 
				'E' => GlyphE, 
				'L' => GlyphL, 
				'O' => GlyphO, 
				'A' => GlyphA, 
				'D' => GlyphD, 
				_ => null, 
			};
		}

		private void OnDestroy()
		{
			if ((Object)(object)_tex != (Object)null)
			{
				Object.Destroy((Object)(object)_tex);
			}
		}
	}
	public class ChargeRifleSystem : MonoBehaviour
	{
		[Header("References")]
		public FVRFireArm Weapon;

		[Tooltip("Where the beams start. Defaults to the weapon's MuzzlePos.")]
		public Transform Muzzle;

		[Tooltip("Barrel part that turns 90 degrees while the rifle charges (BarrelRotate).")]
		public Transform TiltPart;

		[Tooltip("Barrel part that spins fast while the rifle charges (Barrel).")]
		public Transform SpinPart;

		[Tooltip("Glow shells driven by the charge level (BarrelHeat / BatteryLeftHeat / BatteryRightHeat).")]
		public Renderer[] HeatRenderers;

		public ChargeRifleDisplay Display;

		public ChargeRifleBatteryLid BatteryLid;

		[Header("Charge")]
		[Tooltip("Seconds of holding the trigger until the burst is ready.")]
		public float ChargeTime = 0.85f;

		[Tooltip("Seconds for a full charge to drain back to zero after the trigger is released.")]
		public float ChargeDecayTime = 0.5f;

		[Tooltip("Trigger value (0..1) at which the charge starts.")]
		[Range(0f, 1f)]
		public float TriggerThreshold = 0.55f;

		[Tooltip("Trigger value the player has to fall back under before a burst can start a new charge.")]
		[Range(0f, 1f)]
		public float TriggerReleaseThreshold = 0.25f;

		[Tooltip("Fire the next burst automatically while the trigger stays held (Apex behaviour).")]
		public bool AutoRepeatWhileHeld = true;

		[Tooltip("How many tier sounds are played during a charge (ChargeLevel1..N).")]
		public int ChargeLevels = 3;

		[Header("Barrel motion")]
		[Tooltip("Rotation applied to the tilt part at full charge, degrees around its local Z.")]
		public float TiltAngle = 90f;

		[Tooltip("Seconds the tilt part needs to reach TiltAngle.")]
		public float TiltTime = 0.22f;

		[Tooltip("Spin speed of the spinning barrel part at full charge, degrees per second.")]
		public float SpinMaxDps = 1250f;

		public float SpinAccelDps2 = 2600f;

		[Tooltip("Seconds the barrel keeps spinning after the burst before it winds down.")]
		public float SpinContinueAfterShot = 1f;

		[Tooltip("Seconds the spinning part takes to settle back to its home angle.")]
		public float SpinReturnTime = 0.35f;

		[Header("Beam - thin (charging)")]
		public float ThinBeamRange = 150f;

		public float ThinBeamWidthMin = 0.004f;

		public float ThinBeamWidthMax = 0.016f;

		[Tooltip("Seconds between thin beam damage applications.")]
		public float ThinBeamTickInterval = 0.1f;

		[Tooltip("Kinetic damage per thin beam tick. Grows a little as the charge builds.")]
		public float ThinBeamDamageKinetic = 22f;

		[Header("Beam - burst")]
		public float BurstBeamRange = 300f;

		public float BurstBeamWidth = 0.055f;

		[Tooltip("Seconds the burst beam stays visible while it fades.")]
		public float BurstBeamDuration = 0.15f;

		public float BurstDamageKinetic = 900f;

		public float BurstDamageThermal = 220f;

		[Header("Ammo")]
		[Tooltip("Rounds taken out of the battery cell per burst.")]
		public int RoundsPerBurst = 1;

		[Header("Audio")]
		public AudioClip ChargeClickClip;

		public AudioClip ChargeLoopClip;

		public AudioClip[] ChargeLevelClips;

		public AudioClip ChargeDownClip;

		public AudioClip SpinLoopClip;

		public AudioClip SpinDownClip;

		public AudioClip BeamIgniteClip;

		public AudioClip BeamBuzzLoopClip;

		public AudioClip[] ThinBeamFireClips;

		public AudioClip[] BurstClips;

		public AudioClip BurstBodyClip;

		public AudioClip FireSizzleClip;

		public AudioClip[] TriggerClips;

		public AudioClip DrawClip;

		[Range(0f, 1f)]
		public float ChargeLoopMaxVolume = 0.7f;

		[Range(0f, 1f)]
		public float SpinLoopVolume = 0.45f;

		[Range(0f, 1f)]
		public float BeamBuzzVolume = 0.5f;

		[Range(0f, 1f)]
		public float OneShotVolume = 1f;

		[Tooltip("Pitch of the charge hum at zero charge and at full charge.")]
		public float ChargeLoopPitchMin = 0.9f;

		public float ChargeLoopPitchMax = 1.18f;

		[Header("Visuals")]
		public Material BeamMaterial;

		public Color ThinBeamColor = new Color(0.45f, 0.95f, 1f, 0.85f);

		public Color BurstBeamColor = new Color(1f, 0.95f, 0.8f, 1f);

		[Tooltip("Layer mask for the hitscans. Trigger colliders are ignored.")]
		public LayerMask RayMask = LayerMask.op_Implicit(-1);

		[Tooltip("Spawn bullet hole decals where the beams land.")]
		public bool SpawnDecals = true;

		[Header("State (read-only)")]
		[Range(0f, 1f)]
		public float Charge;

		private float _charge;

		private float _tiltLerp;

		private float _spinSpeed;

		private float _spinAngle;

		private float _spinHomeZ;

		private float _tiltHomeZ;

		private float _spinCoastUntil = -1f;

		private float _nextThinTick;

		private float _nextLevelIndex;

		private int _lastLevelIndex;

		private bool _waitRelease;

		private bool _wasHeld;

		private bool _wasHeldGun;

		private float _burstFade;

		private float _glow;

		private LineRenderer _thinBeam;

		private LineRenderer _burstBeam;

		private AudioSource _chargeLoop;

		private AudioSource _spinLoop;

		private AudioSource _buzzLoop;

		private MaterialPropertyBlock _pb;

		private RaycastHit[] _hits = (RaycastHit[])(object)new RaycastHit[32];

		private float _beamOnTime = -1f;

		private AudioEvent _ev;

		public bool IsCharging { get; private set; }

		private void Awake()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Weapon == (Object)null)
			{
				Weapon = ((Component)this).GetComponent<FVRFireArm>();
			}
			if ((Object)(object)Muzzle == (Object)null && (Object)(object)Weapon != (Object)null)
			{
				Muzzle = Weapon.MuzzlePos;
			}
			if ((Object)(object)TiltPart != (Object)null)
			{
				_tiltHomeZ = TiltPart.localEulerAngles.z;
			}
			if ((Object)(object)SpinPart != (Object)null)
			{
				_spinHomeZ = SpinPart.localEulerAngles.z;
			}
			_pb = new MaterialPropertyBlock();
			_ev = new AudioEvent();
			_ev.VolumeRange = new Vector2(OneShotVolume, OneShotVolume);
			BuildBeams();
			BuildLoops();
		}

		private void BuildBeams()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_thinBeam == (Object)null)
			{
				GameObject val = new GameObject("ChargeRifleThinBeam");
				val.transform.SetParent(((Component)this).transform, false);
				_thinBeam = val.AddComponent<LineRenderer>();
				SetupLine(_thinBeam, ThinBeamWidthMax, ThinBeamColor);
				((Renderer)_thinBeam).enabled = false;
			}
			if ((Object)(object)_burstBeam == (Object)null)
			{
				GameObject val2 = new GameObject("ChargeRifleBurstBeam");
				val2.transform.SetParent(((Component)this).transform, false);
				_burstBeam = val2.AddComponent<LineRenderer>();
				SetupLine(_burstBeam, BurstBeamWidth, BurstBeamColor);
				((Renderer)_burstBeam).enabled = false;
			}
		}

		private void SetupLine(LineRenderer lr, float width, Color color)
		{
			//IL_0058: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			Material val = BeamMaterial;
			if ((Object)(object)val == (Object)null)
			{
				Shader val2 = Shader.Find("Sprites/Default");
				if ((Object)(object)val2 != (Object)null)
				{
					val = new Material(val2);
				}
			}
			((Renderer)lr).material = val;
			lr.useWorldSpace = true;
			lr.positionCount = 2;
			lr.startWidth = width;
			lr.endWidth = width;
			lr.startColor = color;
			lr.endColor = color;
			((Renderer)lr).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)lr).receiveShadows = false;
		}

		private void BuildLoops()
		{
			_chargeLoop = MakeLoopSource("ChargeHum", ChargeLoopClip);
			_spinLoop = MakeLoopSource("BarrelSpin", SpinLoopClip);
			_buzzLoop = MakeLoopSource("BeamBuzz", BeamBuzzLoopClip);
		}

		private AudioSource MakeLoopSource(string name, AudioClip clip)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(((Component)this).transform, false);
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.clip = clip;
			val2.loop = true;
			val2.playOnAwake = false;
			val2.volume = 0f;
			val2.spatialBlend = 1f;
			val2.dopplerLevel = 0f;
			val2.rolloffMode = (AudioRolloffMode)1;
			val2.minDistance = 1.5f;
			val2.maxDistance = 35f;
			return val2;
		}

		private void Update()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Weapon == (Object)null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			bool flag = ((FVRInteractiveObject)Weapon).IsHeld && (Object)(object)((FVRInteractiveObject)Weapon).m_hand != (Object)null;
			FVRViveHand val = ((!flag) ? null : ((FVRInteractiveObject)Weapon).m_hand);
			bool flag2 = flag && val.Input.TriggerFloat >= TriggerThreshold;
			if (!flag)
			{
				CancelCharge(playSound: false);
				_waitRelease = false;
			}
			else if (!_wasHeldGun)
			{
				PlayDrawSound();
			}
			_wasHeldGun = flag;
			bool flag3 = (Object)(object)BatteryLid != (Object)null && BatteryLid.IsOpen;
			bool flag4 = HasAmmo();
			if (flag2 && !_wasHeld && !_waitRelease)
			{
				if (flag4 && !flag3)
				{
					PlayOneShot(TriggerClips, MuzzlePos(), 0.85f);
				}
				else
				{
					PlayOneShot(TriggerClips, MuzzlePos(), 1f);
				}
			}
			_wasHeld = flag2;
			if (flag && val.Input.TriggerFloat < TriggerReleaseThreshold)
			{
				_waitRelease = false;
			}
			bool flag5 = flag2 && flag4 && !flag3 && !_waitRelease;
			if (flag5)
			{
				if (!IsCharging)
				{
					BeginCharge();
				}
				_charge += deltaTime / Mathf.Max(0.01f, ChargeTime);
				if (_charge >= 1f)
				{
					_charge = 1f;
					FireBurst(val);
					_charge = 0f;
					_lastLevelIndex = 0;
					if (!AutoRepeatWhileHeld)
					{
						_waitRelease = true;
					}
				}
			}
			else
			{
				if (IsCharging)
				{
					EndCharge(flag4 && !flag3);
				}
				_charge = Mathf.MoveTowards(_charge, 0f, deltaTime / Mathf.Max(0.01f, ChargeDecayTime));
				if (_charge <= 0f)
				{
					_lastLevelIndex = 0;
				}
			}
			Charge = _charge;
			UpdateTicks();
			UpdateThinBeam(deltaTime, flag2, flag5);
			UpdateBarrelMotion(deltaTime, flag5);
			UpdateGlow(deltaTime);
			UpdateAudio(deltaTime);
			UpdateDisplay();
			UpdateBurstFade(deltaTime);
		}

		private void BeginCharge()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			IsCharging = true;
			_lastLevelIndex = 0;
			PlayOneShot(ChargeClickClip, MuzzlePos(), 1f);
			if ((Object)(object)_chargeLoop != (Object)null && (Object)(object)ChargeLoopClip != (Object)null && !_chargeLoop.isPlaying)
			{
				_chargeLoop.Play();
			}
		}

		private void EndCharge(bool playSound)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			IsCharging = false;
			if (playSound && _charge > 0.08f)
			{
				PlayOneShot(ChargeDownClip, MuzzlePos(), 1f);
			}
		}

		private void CancelCharge(bool playSound)
		{
			if (IsCharging)
			{
				EndCharge(playSound);
			}
			_charge = Mathf.MoveTowards(_charge, 0f, Time.deltaTime / Mathf.Max(0.01f, ChargeDecayTime));
		}

		private void UpdateTicks()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (ChargeLevels > 0)
			{
				int num = Mathf.FloorToInt(_charge * (float)ChargeLevels);
				if (num > _lastLevelIndex && ChargeLevelClips != null && ChargeLevelClips.Length > 0)
				{
					int num2 = Mathf.Clamp(_lastLevelIndex, 0, ChargeLevelClips.Length - 1);
					PlayOneShot(ChargeLevelClips[num2], MuzzlePos(), 1f);
					_lastLevelIndex = num;
				}
			}
		}

		private bool HasAmmo()
		{
			FVRFireArmMagazine magazine = Weapon.Magazine;
			if ((Object)(object)magazine == (Object)null)
			{
				return false;
			}
			if (magazine.IsInfinite)
			{
				return true;
			}
			return magazine.HasARound();
		}

		private void ConsumeRound(int count)
		{
			FVRFireArmMagazine magazine = Weapon.Magazine;
			if ((Object)(object)magazine == (Object)null || magazine.IsInfinite)
			{
				return;
			}
			for (int i = 0; i < count; i++)
			{
				if (!magazine.HasARound())
				{
					break;
				}
				magazine.RemoveRound();
			}
		}

		private void FireBurst(FVRViveHand hand)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = MuzzlePos();
			Vector3 val2 = MuzzleDir();
			RaycastHit best;
			float dist;
			bool flag = TraceBeam(val, val2, BurstBeamRange, out best, out dist);
			FireBurstVisual(val, (!flag) ? (val + val2 * BurstBeamRange) : ((RaycastHit)(ref best)).point);
			if (flag)
			{
				ApplyDamage(best, val2, BurstDamageKinetic, BurstDamageThermal, 0.02f, strong: true);
			}
			ConsumeRound(Mathf.Max(1, RoundsPerBurst));
			PlayOneShot(BurstClips, val, 1f);
			PlayOneShot(BurstBodyClip, val, 1f);
			if (flag)
			{
				PlayOneShot(FireSizzleClip, ((RaycastHit)(ref best)).point, 0.8f);
			}
			Weapon.Recoil(Weapon.IsTwoHandStabilized(), Weapon.IsForegripStabilized(), Weapon.IsShoulderStabilized(), (FVRFireArmRecoilProfile)null, 1f);
			if ((Object)(object)hand != (Object)null)
			{
				hand.Buzz(hand.Buzzer.Buzz_GunShot);
			}
			if ((Object)(object)GM.CurrentSceneSettings != (Object)null)
			{
				GM.CurrentSceneSettings.OnShotFired(Weapon);
			}
			if ((Object)(object)GM.CurrentPlayerBody != (Object)null)
			{
				GM.CurrentPlayerBody.VisibleEvent(2f);
			}
			if (!((FVRInteractiveObject)Weapon).IsHeld && (Object)(object)((FVRPhysicalObject)Weapon).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)Weapon).RootRigidbody.AddForceAtPosition(-val2 * 0.6f, val, (ForceMode)2);
			}
			_spinCoastUntil = Time.time + SpinContinueAfterShot;
			_burstFade = 1f;
		}

		private void FireBurstVisual(Vector3 from, Vector3 to)
		{
			//IL_002a: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_burstBeam == (Object)null))
			{
				((Renderer)_burstBeam).enabled = true;
				_burstBeam.SetPosition(0, from);
				_burstBeam.SetPosition(1, to);
				_burstBeam.startWidth = BurstBeamWidth;
				_burstBeam.endWidth = BurstBeamWidth * 0.35f;
				_burstBeam.startColor = BurstBeamColor;
				_burstBeam.endColor = BurstBeamColor;
			}
		}

		private void UpdateBurstFade(float dt)
		{
			//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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (_burstFade <= 0f)
			{
				return;
			}
			_burstFade = Mathf.MoveTowards(_burstFade, 0f, dt / Mathf.Max(0.01f, BurstBeamDuration));
			Color burstBeamColor = BurstBeamColor;
			burstBeamColor.a *= _burstFade;
			if ((Object)(object)_burstBeam != (Object)null)
			{
				_burstBeam.startColor = burstBeamColor;
				_burstBeam.endColor = burstBeamColor;
				_burstBeam.startWidth = BurstBeamWidth * _burstFade;
				_burstBeam.endWidth = BurstBeamWidth * 0.35f * _burstFade;
				if (_burstFade <= 0f)
				{
					((Renderer)_burstBeam).enabled = false;
				}
			}
		}

		private void UpdateThinBeam(float dt, bool triggerDown, bool canCharge)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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_01e1: 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)
			if (!triggerDown || !canCharge || !(_charge > 0.02f))
			{
				if ((Object)(object)_thinBeam != (Object)null && ((Renderer)_thinBeam).enabled)
				{
					((Renderer)_thinBeam).enabled = false;
				}
				_beamOnTime = -1f;
				return;
			}
			if (_beamOnTime < 0f)
			{
				_beamOnTime = Time.time;
				PlayOneShot(BeamIgniteClip, MuzzlePos(), 1f);
			}
			Vector3 val = MuzzlePos();
			Vector3 val2 = MuzzleDir();
			RaycastHit best;
			float dist;
			bool flag = TraceBeam(val, val2, ThinBeamRange, out best, out dist);
			Vector3 val3 = ((!flag) ? (val + val2 * ThinBeamRange) : ((RaycastHit)(ref best)).point);
			if ((Object)(object)_thinBeam != (Object)null)
			{
				((Renderer)_thinBeam).enabled = true;
				_thinBeam.SetPosition(0, val);
				_thinBeam.SetPosition(1, val3);
				float num = Mathf.Lerp(ThinBeamWidthMin, ThinBeamWidthMax, _charge);
				_thinBeam.startWidth = num;
				_thinBeam.endWidth = num;
				Color thinBeamColor = ThinBeamColor;
				thinBeamColor.a = Mathf.Lerp(0.35f, 1f, _charge) * ThinBeamColor.a;
				_thinBeam.startColor = thinBeamColor;
				_thinBeam.endColor = thinBeamColor;
			}
			if (Time.time >= _nextThinTick)
			{
				_nextThinTick = Time.time + ThinBeamTickInterval;
				if (flag)
				{
					float num2 = ThinBeamDamageKinetic * Mathf.Lerp(0.45f, 1f, _charge);
					ApplyDamage(best, val2, num2, num2 * 0.5f, 0.006f, strong: false);
				}
				if (ThinBeamFireClips != null && ThinBeamFireClips.Length > 0 && Random.value < 0.5f)
				{
					PlayOneShot(ThinBeamFireClips, val, 0.55f);
				}
			}
		}

		private Vector3 MuzzlePos()
		{
			//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_003d: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			return (!((Object)(object)Muzzle != (Object)null)) ? (((Component)this).transform.position + ((Component)this).transform.forward * 0.5f) : Muzzle.position;
		}

		private Vector3 MuzzleDir()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			return (!((Object)(object)Muzzle != (Object)null)) ? ((Component)this).transform.forward : Muzzle.forward;
		}

		private bool TraceBeam(Vector3 origin, Vector3 dir, float range, out RaycastHit best, out float dist)
		{
			//IL_0003: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			best = default(RaycastHit);
			dist = range;
			int num = Physics.RaycastNonAlloc(origin, dir, _hits, range, LayerMask.op_Implicit(RayMask), (QueryTriggerInteraction)1);
			if (num <= 0)
			{
				return false;
			}
			float num2 = float.MaxValue;
			bool flag = false;
			Transform root = ((Component)this).transform.root;
			Transform val = ((!((Object)(object)GM.CurrentPlayerBody != (Object)null)) ? null : ((Component)GM.CurrentPlayerBody).transform);
			for (int i = 0; i < num; i++)
			{
				RaycastHit val2 = _hits[i];
				if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null))
				{
					Transform transform = ((Component)((RaycastHit)(ref val2)).collider).transform;
					if (!((Object)(object)transform.root == (Object)(object)root) && (!((Object)(object)val != (Object)null) || (!((Object)(object)transform == (Object)(object)val) && !transform.IsChildOf(val))) && ((RaycastHit)(ref val2)).distance < num2)
					{
						num2 = ((RaycastHit)(ref val2)).distance;
						best = val2;
						flag = true;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			dist = num2;
			return true;
		}

		private void ApplyDamage(RaycastHit hit, Vector3 dir, float kinetic, float thermal, float size, bool strong)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			IFVRDamageable component = ((Component)((RaycastHit)(ref hit)).collider).gameObject.GetComponent<IFVRDamageable>();
			if (component == null && (Object)(object)((RaycastHit)(ref hit)).collider.attachedRigidbody != (Object)null)
			{
				component = ((Component)((RaycastHit)(ref hit)).collider.attachedRigidbody).gameObject.GetComponent<IFVRDamageable>();
			}
			if (component != null)
			{
				Damage val = new Damage();
				val.Class = (DamageClass)1;
				val.Dam_TotalKinetic = kinetic;
				val.Dam_Blunt = kinetic * 0.1f;
				val.Dam_Piercing = kinetic * 0.9f;
				val.Dam_Thermal = thermal;
				val.Dam_TotalEnergetic = thermal;
				val.point = ((RaycastHit)(ref hit)).point;
				val.hitNormal = ((RaycastHit)(ref hit)).normal;
				val.strikeDir = dir;
				val.damageSize = size;
				if ((Object)(object)GM.CurrentPlayerBody != (Object)null)
				{
					val.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
				}
				component.Damage(val);
			}
			if (SpawnDecals && (Object)(object)((RaycastHit)(ref hit)).collider.attachedRigidbody == (Object)null)
			{
				SpawnDecal(hit, size, strong);
			}
		}

		private void SpawnDecal(RaycastHit hit, float size, bool strong)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//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_00b4: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			if (GM.Options == null || (int)GM.Options.SimulationOptions.HitDecalMode2 != 1)
			{
				return;
			}
			PMat component = ((Component)((RaycastHit)(ref hit)).collider).gameObject.GetComponent<PMat>();
			MatDef val = ((!((Object)(object)component != (Object)null) || !((Object)(object)component.MatDef != (Object)null)) ? PM.DefaultMatDef : component.MatDef);
			if (!((Object)(object)val == (Object)null))
			{
				BulletHoleDecalType bulletHoleType = val.BulletHoleType;
				if ((int)bulletHoleType != 0)
				{
					float num = Mathf.Clamp(size * ((!strong) ? 3f : 6f), 0.0001f, 0.02f);
					FXM.SpawnBulletDecal(bulletHoleType, ((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, num);
				}
			}
		}

		private void UpdateBarrelMotion(float dt, bool canCharge)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(_charge);
			_tiltLerp = Mathf.MoveTowards(_tiltLerp, num, dt / Mathf.Max(0.01f, TiltTime));
			if ((Object)(object)TiltPart != (Object)null)
			{
				Vector3 localEulerAngles = TiltPart.localEulerAngles;
				TiltPart.localEulerAngles = new Vector3(localEulerAngles.x, localEulerAngles.y, _tiltHomeZ + TiltAngle * _tiltLerp);
			}
			bool flag = canCharge || _charge > 0.02f || Time.time < _spinCoastUntil;
			float num2 = ((!flag) ? 0f : (SpinMaxDps * Mathf.Clamp01(0.35f + 0.65f * _charge)));
			if (num2 <= 0.01f && _spinSpeed <= 0.01f && !flag)
			{
				_spinAngle = Mathf.MoveTowardsAngle(_spinAngle, 0f, dt * (360f / Mathf.Max(0.05f, SpinReturnTime)));
			}
			_spinSpeed = Mathf.MoveTowards(_spinSpeed, num2, SpinAccelDps2 * dt);
			_spinAngle -= _spinSpeed * dt;
			if (_spinAngle < -360f)
			{
				_spinAngle += 360f;
			}
			if ((Object)(object)SpinPart != (Object)null)
			{
				Vector3 localEulerAngles2 = SpinPart.localEulerAngles;
				SpinPart.localEulerAngles = new Vector3(localEulerAngles2.x, localEulerAngles2.y, _spinHomeZ + _spinAngle);
			}
		}

		private void UpdateGlow(float dt)
		{
			float num = (IsCharging ? Mathf.Lerp(0.12f, 1f, _charge) : ((!(_burstFade > 0f)) ? 0f : _burstFade));
			_glow = Mathf.MoveTowards(_glow, num, dt * 6f);
			if (HeatRenderers == null || HeatRenderers.Length == 0)
			{
				return;
			}
			_pb.SetFloat("_EmissionWeight", _glow);
			_pb.SetFloat("_Emission", (!(_glow > 0.01f)) ? 0f : 1f);
			for (int i = 0; i < HeatRenderers.Length; i++)
			{
				if ((Object)(object)HeatRenderers[i] != (Object)null)
				{
					HeatRenderers[i].SetPropertyBlock(_pb);
				}
			}
		}

		private void UpdateAudio(float dt)
		{
			if ((Object)(object)_chargeLoop != (Object)null)
			{
				bool flag = (Object)(object)ChargeLoopClip != (Object)null && (IsCharging || _charge > 0.02f);
				float num = ((!flag) ? 0f : (ChargeLoopMaxVolume * Mathf.Clamp01(_charge)));
				_chargeLoop.volume = Mathf.MoveTowards(_chargeLoop.volume, num, dt * 3f);
				if (_chargeLoop.volume <= 0.001f && _chargeLoop.isPlaying)
				{
					_chargeLoop.Stop();
				}
				else if (flag && !_chargeLoop.isPlaying)
				{
					_chargeLoop.Play();
				}
				_chargeLoop.pitch = Mathf.Lerp(ChargeLoopPitchMin, ChargeLoopPitchMax, _charge);
			}
			if ((Object)(object)_spinLoop != (Object)null)
			{
				bool flag2 = _spinSpeed > 20f;
				float num2 = ((!flag2) ? 0f : (SpinLoopVolume * Mathf.Clamp01(_spinSpeed / Mathf.Max(1f, SpinMaxDps))));
				_spinLoop.volume = Mathf.MoveTowards(_spinLoop.volume, num2, dt * 4f);
				if (_spinLoop.volume <= 0.001f && _spinLoop.isPlaying)
				{
					_spinLoop.Stop();
				}
				else if (flag2 && !_spinLoop.isPlaying)
				{
					_spinLoop.Play();
				}
				_spinLoop.pitch = Mathf.Lerp(0.85f, 1.15f, Mathf.Clamp01(_spinSpeed / Mathf.Max(1f, SpinMaxDps)));
			}
			if ((Object)(object)_buzzLoop != (Object)null)
			{
				bool flag3 = (Object)(object)_thinBeam != (Object)null && ((Renderer)_thinBeam).enabled;
				float num3 = ((!flag3) ? 0f : BeamBuzzVolume);
				_buzzLoop.volume = Mathf.MoveTowards(_buzzLoop.volume, num3, dt * 8f);
				if (_buzzLoop.volume <= 0.001f && _buzzLoop.isPlaying)
				{
					_buzzLoop.Stop();
				}
				else if (flag3 && !_buzzLoop.isPlaying)
				{
					_buzzLoop.Play();
				}
			}
		}

		private void PlayOneShot(AudioClip clip, Vector3 pos, float volumeScale)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0035: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)clip == (Object)null))
			{
				AudioEvent val = new AudioEvent();
				val.Clips.Add(clip);
				val.VolumeRange = new Vector2(OneShotVolume * volumeScale, OneShotVolume * volumeScale);
				val.PitchRange = new Vector2(0.97f, 1.03f);
				SM.PlayGenericSound(val, pos);
			}
		}

		private void PlayOneShot(AudioClip[] clips, Vector3 pos, float volumeScale)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (clips != null && clips.Length != 0)
			{
				int num = Random.Range(0, clips.Length);
				PlayOneShot(clips[num], pos, volumeScale);
			}
		}

		private void UpdateDisplay()
		{
			if (!((Object)(object)Display == (Object)null))
			{
				if (!HasAmmo())
				{
					Display.ShowReload();
				}
				else
				{
					Display.SetCharge(_charge);
				}
			}
		}

		public void PlayDrawSound()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			PlayOneShot(DrawClip, MuzzlePos(), 1f);
		}

		private void OnDisable()
		{
			if ((Object)(object)_chargeLoop != (Object)null)
			{
				_chargeLoop.Stop();
			}
			if ((Object)(object)_spinLoop != (Object)null)
			{
				_spinLoop.Stop();
			}
			if ((Object)(object)_buzzLoop != (Object)null)
			{
				_buzzLoop.Stop();
			}
			if ((Object)(object)_thinBeam != (Object)null)
			{
				((Renderer)_thinBeam).enabled = false;
			}
			if ((Object)(object)_burstBeam != (Object)null)
			{
				((Renderer)_burstBeam).enabled = false;
			}
		}
	}
}
namespace Niko666.New_Universal_Speedloader
{
	[BepInPlugin("Niko666.New_Universal_Speedloader", "New_Universal_Speedloader", "1.0.1")]
	[BepInProcess("h3vr.exe")]
	[Description("Built with MeatKit")]
	[BepInDependency("h3vr.otherloader", "1.3.0")]
	public class New_Universal_SpeedloaderPlugin : BaseUnityPlugin
	{
		private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static ManualLogSource Logger;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			LoadAssets();
		}

		private void LoadAssets()
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Niko666.New_Universal_Speedloader");
			OtherLoader.RegisterDirectLoad(BasePath, "Niko666.New_Universal_Speedloader", "", "", "newspeedloader", "");
		}
	}
}
namespace Niko666
{
	[RequireComponent(typeof(FVRFireArmClip))]
	[DefaultExecutionOrder(-1000)]
	public class NewSpeedloaderSystem : MonoBehaviour
	{
		[Header("Model References (auto-resolved by child name when empty)")]
		[Tooltip("Grip pivot of the loader (the part the hand holds).")]
		public Transform Handle;

		[Tooltip("The part that slides when feeding. Leave empty to use a child named Handle under Handle.")]
		public Transform Plunger;

		[Tooltip("Front tip of the loader. This is what snaps onto the gun's loading port.")]
		public Transform PointEnd;

		[Tooltip("Rear end of the usable tube, used to measure the stroke length.")]
		public Transform PointBase;

		[Tooltip("Tube mesh. Its local X/Y scale follows the caliber thickness.")]
		public Transform Tube;

		[Tooltip("Extra transforms that should also widen with the caliber (local X/Y).")]
		public Transform[] ThicknessTargets;

		[Tooltip("Model parts that spin with the in-hand rotation preview (auto-filled when empty).")]
		public Transform[] VisualParts;

		[Tooltip("Spin those parts while the loader is in hand, so the rotate key is visible before docking.")]
		public bool SpinInHand = true;

		[Header("Attachment")]
		[Tooltip("Max distance (m) between the nose and the port for an automatic snap.")]
		public float AttachRange = 0.1f;

		[Tooltip("Max angle (deg) between the loader and its ideal snapped direction.")]
		public float AttachConeAngle = 75f;

		[Tooltip("Tilt of the loader away from the port, in degrees (45 = the classic speedloader angle).")]
		public float AttachPitch = 45f;

		[Tooltip("How far (m) the nose is pushed past the port point. Negative backs it out.")]
		public float PortInset = 0f;

		[Tooltip("Sideways or backwards hand travel (m) that pops the loader off.")]
		public float DetachDistance = 0.14f;

		[Tooltip("Seconds after a detach during which it will not re-snap.")]
		public float AttachCooldown = 0.6f;

		[Header("Push To Feed")]
		[Tooltip("Hand travel (m) needed per shell. Raise this if feeding feels too touchy.")]
		public float PushTravelPerRound = 0.03f;

		[Tooltip("How much of the push travel the whole loader dips into the port (0 = it stays put).")]
		public float BodyTravelFactor = 0.12f;

		[Tooltip("Plunger travel (m) from full to empty - the local Z it reaches when the loader is empty.")]
		public float HandleStroke = 0.236f;

		[Tooltip("How fast (m/s) the plunger slides to its new step. 0 = snap.")]
		public float PlungerSpeed = 0.5f;

		[Tooltip("Radius (m) around the plunger home position where the free hand can push it.")]
		public float HandleGripRadius = 0.06f;

		[Tooltip("Push travel (m) below which the feeder re-arms for the next push.")]
		public float ReArmThreshold = 0.008f;

		[Header("Caliber Display")]
		[Tooltip("Extra shift (m) of every displayed shell along the loader axis. Positive = towards the mouth.")]
		public float DisplayAxisBias = 0f;

		[Tooltip("Shell spacing as a fraction of the round length. 1 = shoulder to shoulder, below 1 packs tighter like the authored model.")]
		public float DisplayPackFactor = 0.95f;

		[Tooltip("How far (m) the ejection point walks forward per metre of extra round length.")]
		public float EjectLengthFactor = 1f;

		[Tooltip("Let loose rounds dropped onto the loader load themselves.")]
		public bool AllowDropInLoad = true;

		[Header("Caliber Auto Fit")]
		[Tooltip("Re-fit when the loader is empty and a round of another caliber is held near it.")]
		public bool AutoFitCaliber = true;

		[Tooltip("Radius (m) around the loader's nose within which an offered round re-fits the caliber. Keep it small so walking past ammo does not retype the loader.")]
		public float CaliberLearnRange = 0.12f;

		[Tooltip("Max shells the loader may hold after expanding its display bullets.")]
		public int MaxRounds = 12;

		[Tooltip("Length (m) of the master round the model was authored around - H3VR's 12ga shell mesh.")]
		public float RefRoundLength = 0.0625f;

		[Tooltip("Diameter (m) of the master round - H3VR's 12ga shell mesh.")]
		public float RefRoundDiameter = 0.0225f;

		[Tooltip("Clamp for the caliber thickness multiplier.")]
		public float MinTubeScale = 0.45f;

		public float MaxTubeScale = 1.6f;

		[Header("Rotation")]
		[Tooltip("Roll of the model around its own axis, in degrees. 180 puts the handle under the tube.")]
		public float BaseRoll = 180f;

		[Tooltip("Degrees per press, applied around the gun's bore (bottom / side / top / other side).")]
		public float RollStep = 90f;

		[Header("Debug")]
		public bool DebugLog = false;

		public bool DrawGizmos = true;

		private static readonly Collider[] ProbeBuffer = (Collider[])(object)new Collider[32];

		private static readonly Dictionary<int, Transform> PortCache = new Dictionary<int, Transform>();

		private FVRFireArmClip _clip;

		private FVRFireArm _gun;

		private FVRFireArmMagazine _mag;

		private bool _ready;

		private bool _attached;

		private bool _armed = true;

		private bool _otherPushing;

		private float _cooldown;

		private int _rollStep;

		private float _push;

		private int _dispatched;

		private Vector3 _attachHandLocal;

		private Vector3 _otherStartLocal;

		private Vector3 _lastPortWorld;

		private Vector3 _manualBaseLocal = Vector3.down;

		private Transform _visualRoot;

		private Vector3 _localNose;

		private Vector3 _plungerHome;

		private Vector3 _plungerHomeRootLocal;

		private Vector3[] _thicknessBase;

		private Vector3 _ammoBaseLocal;

		private Vector3 _ejectBaseLocal;

		private float _ammoSpacing;

		private float _ammoRearZ;

		private float _fittedLen;

		private bool _masterFit;

		private int _lastRoundCount = -1;

		private NewSpeedloaderSystem _inheritSource;

		private float _plungerOffset;

		private float _usableLength;

		private float _refLen;

		private float _refDia;

		private int _capacityBase = 4;

		private void Awake()
		{
			_clip = ((Component)this).GetComponent<FVRFireArmClip>();
			if ((Object)(object)_clip == (Object)null)
			{
				Debug.LogError((object)"[Speedloader] needs to sit on an FVRFireArmClip", (Object)(object)this);
				((Behaviour)this).enabled = false;
			}
			else
			{
				EnsureClipInterface();
			}
		}

		private void Start()
		{
			Init();
		}

		private void OnDisable()
		{
			if (_attached)
			{
				Detach(playSound: false);
			}
		}

		private void Update()
		{
			//IL_00a5: 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)
			if (!_ready)
			{
				Init();
				if (!_ready)
				{
					return;
				}
			}
			if (_cooldown > 0f)
			{
				_cooldown -= Time.deltaTime;
			}
			FVRViveHand hand = ((FVRInteractiveObject)_clip).m_hand;
			if ((Object)(object)hand == (Object)null)
			{
				if (_attached)
				{
					Detach(playSound: false);
				}
				UpdatePlunger();
				UpdatePreviewRotation();
				AlignBullets();
				return;
			}
			if (HandleRotateInput(hand))
			{
				SM.PlayGenericSound(_clip.AffixClip, ((Component)this).transform.position);
			}
			if (_attached)
			{
				UpdateAttached(hand);
			}
			else
			{
				UpdateIdle(hand);
			}
			if (_clip.m_numRounds != _lastRoundCount)
			{
				_lastRoundCount = _clip.m_numRounds;
				SanitizeLoadedRounds(_clip.RoundType);
				FillEmptyRoundSlots();
			}
			UpdatePlunger();
			UpdatePreviewRotation();
			AlignBullets();
		}

		private void Init()
		{
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			if (_ready || (Object)(object)_clip == (Object)null)
			{
				return;
			}
			if ((Object)(object)Handle == (Object)null)
			{
				Handle = FindChild("Handle");
			}
			if ((Object)(object)PointEnd == (Object)null)
			{
				PointEnd = FindChild("Point_End");
			}
			if ((Object)(object)PointBase == (Object)null)
			{
				PointBase = FindChild("Point_Base");
			}
			if ((Object)(object)Tube == (Object)null)
			{
				Tube = FindChild("Tube");
			}
			if ((Object)(object)PointEnd == (Object)null || (Object)(object)Handle == (Object)null)
			{
				Debug.LogError((object)("[Speedloader] could not find Point_End / Handle on " + ((Object)this).name + " - assign them in the inspector."), (Object)(object)this);
				((Behaviour)this).enabled = false;
				return;
			}
			RepairClipStateIfNeeded();
			if ((Object)(object)Plunger == (Object)null)
			{
				Plunger = FindChildUnder(Handle, "Handle");
			}
			if ((Object)(object)Plunger == (Object)null)
			{
				Plunger = Handle;
			}
			_localNose = ((Component)this).transform.InverseTransformPoint(PointEnd.position);
			_plungerHome = Plunger.localPosition;
			_plungerHomeRootLocal = ((Component)this).transform.InverseTransformPoint(Plunger.position);
			if (ThicknessTargets == null || ThicknessTargets.Length == 0)
			{
				ThicknessTargets = (Transform[])(object)((!((Object)(object)Tube != (Object)null)) ? new Transform[0] : new Transform[1] { Tube });
			}
			_thicknessBase = (Vector3[])(object)new Vector3[ThicknessTargets.Length];
			for (int i = 0; i < ThicknessTargets.Length; i++)
			{
				ref Vector3 reference = ref _thicknessBase[i];
				reference = ((!((Object)(object)ThicknessTargets[i] != (Object)null)) ? Vector3.one : ThicknessTargets[i].localScale);
			}
			if (_clip.DisplayBullets != null && _clip.DisplayBullets.Length > 0)
			{
				_capacityBase = _clip.DisplayBullets.Length;
				Vector3 val = (_ammoBaseLocal = (Vector3)((!((Object)(object)_clip.DisplayBullets[0] != (Object)null)) ? new Vector3(0f, 0f, _localNose.z * 0.9f) : ((Component)this).transform.InverseTransformPoint(_clip.DisplayBullets[0].transform.position)));
				float ammoSpacing = RefRoundLength;
				if (_clip.DisplayBullets.Length > 1 && (Object)(object)_clip.DisplayBullets[1] != (Object)null)
				{
					float num = ((Component)this).transform.InverseTransformPoint(_clip.DisplayBullets[1].transform.position).z - val.z;
					if (Mathf.Abs(num) > 0.002f)
					{
						ammoSpacing = num;
					}
				}
				_ammoSpacing = ammoSpacing;
			}
			else
			{
				_capacityBase = Mathf.Max(1, _clip.m_capacity);
				_ammoBaseLocal = new Vector3(0f, 0f, _localNose.z * 0.9f);
				_ammoSpacing = 0f - RefRoundLength;
			}
			_ammoRearZ = _ammoBaseLocal.z + _ammoSpacing * (float)(Mathf.Max(1, _capacityBase) - 1);
			if ((Object)(object)PointBase != (Object)null)
			{
				float z = ((Component)this).transform.InverseTransformPoint(PointBase.position).z;
				_ammoRearZ = Mathf.Min(_ammoRearZ, z + 0.002f);
				_usableLength = Mathf.Max(0.01f, Mathf.Abs(_ammoBaseLocal.z - z) + Mathf.Abs(_ammoSpacing));
			}
			else
			{
				_usableLength = Mathf.Max(0.01f, Mathf.Abs(_ammoBaseLocal.z - _ammoRearZ));
			}
			if (DebugLog)
			{
				FVRObject objectWrapper = ((FVRPhysicalObject)_clip).ObjectWrapper;
				Debug.Log((object)string.Format("[Speedloader] measure: item={0} obj={1} bullets={2} baseZ={3:F4} spacing={4:F4} rearZ={5:F4} usable={6:F4} pointEnd={7:F4} tubeZ={8:F2} stroke={9:F3}", ((Object)this).name, (!((Object)(object)objectWrapper != (Object)null)) ? "?" : objectWrapper.ItemID, (_clip.DisplayBullets != null) ? _clip.DisplayBullets.Length : 0, _ammoBaseLocal.z, _ammoSpacing, _ammoRearZ, _usableLength, _localNose.z, (!((Object)(object)Tube != (Object)null)) ? 0f : Tube.localScale.z, HandleStroke));
			}
			_refLen = Mathf.Max(0.005f, RefRoundLength);
			_refDia = Mathf.Max(0.001f, RefRoundDiameter);
			_fittedLen = _refLen;
			if ((Object)(object)_clip.RoundEjectionPos != (Object)null)
			{
				_ejectBaseLocal = _clip.RoundEjectionPos.localPosition;
			}
			_clip.IsDropInLoadable = AllowDropInLoad;
			EnsureVisualRoot();
			_manualBaseLocal = Vector3.down;
			try
			{
				AdoptCaliberFromLoadedRounds();
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Speedloader] caliber adoption failed: " + ex));
			}
			ApplyRoundGeometry(_clip.RoundType, clearRounds: false);
			RestoreSavedRounds();
			_clip.UpdateBulletDisplay();
			AlignBullets();
			if ((Object)(object)_inheritSource != (Object)null)
			{
				InheritState(_inheritSource);
				_inheritSource = null;
			}
			_ready = true;
			if (DebugLog)
			{
				Debug.Log((object)$"[Speedloader] ready: roundType={_clip.RoundType} rounds={_clip.m_numRounds}/{_clip.m_capacity} refLen={_refLen:F4} refDia={_refDia:F4} spacing={_ammoSpacing:F4} baseZ={_ammoBaseLocal.z:F4} rearZ={_ammoRearZ:F4} usable={_usableLength:F4}");
			}
		}

		private void EnsureClipInterface()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (!((Object)(object)_clip.Interface != (Object)null))
			{
				GameObject val = new GameObject("ClipInterface");
				val.transform.SetParent(((Component)this).transform, false);
				FVRFireArmClipInterface val2 = val.AddComponent<FVRFireArmClipInterface>();
				val2.Clip = _clip;
				_clip.Interface = val2;
				val.SetActive(false);
				if (DebugLog)
				{
					Debug.Log((object)"[Speedloader] injected a missing FVRFireArmClipInterface", (Object)(object)this);
				}
			}
		}

		private void RepairClipStateIfNeeded()
		{
			if (_clip.LoadedRounds != null && _clip.LoadedRounds.Length >= Mathf.Max(1, _clip.m_capacity))
			{
				return;
			}
			if (DebugLog)
			{
				Debug.LogWarning((object)"[Speedloader] clip Awake did not finish - rebuilding round state", (Object)(object)this);
			}
			int num = Mathf.Max(1, _clip.m_capacity);
			_clip.LoadedRounds = (FVRLoadedRound[])(object)new FVRLoadedRound[num];
			_clip.m_numRounds = 0;
			_clip.m_capacity = num;
			if (_clip.DefaultLoadingPattern != null && _clip.DefaultLoadingPattern.Classes != null)
			{
				int num2 = Mathf.Min(_clip.DefaultLoadingPattern.Classes.Length, num);
				for (int i = 0; i < num2; i++)
				{
					_clip.AddRound(_clip.DefaultLoadingPattern.Classes[i], false, false);
				}
			}
			_clip.UpdateBulletDisplay();
		}

		private void EnsureVisualRoot()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!SpinInHand || (Object)(object)_visualRoot != (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("VisualRoot");
			_visualRoot = val.transform;
			_visualRoot.SetParent(((Component)this).transform, false);
			List<Transform> list = new List<Transform>();
			if (VisualParts != null && VisualParts.Length > 0)
			{
				for (int i = 0; i < VisualParts.Length; i++)
				{
					if ((Object)(object)VisualParts[i] != (Object)null)
					{
						list.Add(VisualParts[i]);
					}
				}
			}
			else
			{
				Transform val2 = FindChild("speedloader");
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(val2);
				}
				if ((Object)(object)Plunger != (Object)null && (Object)(object)Plunger != (Object)(object)val2)
				{
					list.Add(Plunger);
				}
				if (_clip.DisplayBullets != null)
				{
					for (int j = 0; j < _clip.DisplayBullets.Length; j++)
					{
						if ((Object)(object)_clip.DisplayBullets[j] != (Object)null)
						{
							list.Add(_clip.DisplayBullets[j].transform);
						}
					}
				}
			}
			for (int k = 0; k < list.Count; k++)
			{
				Transform val3 = list[k];
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)_visualRoot) && !((Object)(object)val3.parent == (Object)(object)_visualRoot))
				{
					val3.SetParent(_visualRoot, true);
				}
			}
		}

		private void UpdateIdle(FVRViveHand hand)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_0128: 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_00fa: 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)
			UpdateCaliberFromHeldRound(hand);
			if (_cooldown > 0f)
			{
				return;
			}
			if (!_armed)
			{
				Vector3 val = ((Component)this).transform.TransformPoint(_localNose);
				if (!(Vector3.Distance(val, _lastPortWorld) > AttachRange * 1.5f))
				{
					return;
				}
				_armed = true;
			}
			Vector3 portPos;
			Vector3 bore;
			Vector3 faceNormal;
			FVRFireArm val2 = FindPortCandidate(out portPos, out bore, out faceNormal);
			if ((Object)(object)val2 == (Object)null || _clip.m_numRounds <= 0 || (Object)(object)val2.Magazine == (Object)null || val2.Magazine.IsFull())
			{
				return;
			}
			if (val2.RoundType != _clip.RoundType)
			{
				if (DebugLog)
				{
					Debug.Log((object)$"[Speedloader] port found on {((Object)val2).name} but it takes {val2.RoundType} and the loader holds {_clip.RoundType}");
				}
			}
			else
			{
				Attach(val2, portPos, bore, faceNormal);
			}
		}

		private FVRFireArm FindPortCandidate(out Vector3 portPos, out Vector3 bore, out Vector3 faceNormal)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_002e: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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)
			portPos = Vector3.zero;
			bore = Vector3.forward;
			faceNormal = Vector3.up;
			Vector3 val = ((Component)this).transform.TransformPoint(_localNose);
			Vector3 forward = ((Component)this).transform.forward;
			int num = Physics.OverlapSphereNonAlloc(val, AttachRange + 0.06f, ProbeBuffer, -1, (QueryTriggerInteraction)2);
			FVRFireArm result = null;
			float num2 = float.MaxValue;
			Vector3 val2 = Vector3.zero;
			Vector3 val3 = Vector3.forward;
			Vector3 val4 = Vector3.up;
			for (int i = 0; i < num; i++)
			{
				Collider val5 = ProbeBuffer[i];
				ProbeBuffer[i] = null;
				if ((Object)(object)val5 == (Object)null)
				{
					continue;
				}
				FVRFireArm componentInParent = ((Component)val5).GetComponentInParent<FVRFireArm>();
				if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent == (Object)(object)_gun || !IsSupportedGun(componentInParent) || (Object)(object)componentInParent.Magazine == (Object)null || !componentInParent.Magazine.IsIntegrated || !TryGetPort(componentInParent, out var portPos2, out var bore2, out var faceNormal2))
				{
					continue;
				}
				float num3 = Vector3.Distance(portPos2, val);
				if (num3 > AttachRange)
				{
					continue;
				}
				float num4 = Vector3.Angle(forward, bore2);
				if (!(num4 > AttachConeAngle))
				{
					float num5 = num3 * 100f + num4;
					if (!(num5 >= num2))
					{
						num2 = num5;
						result = componentInParent;
						val2 = portPos2;
						val3 = bore2;
						val4 = faceNormal2;
					}
				}
			}
			portPos = val2;
			bore = val3;
			faceNormal = val4;
			return result;
		}

		private static bool IsSupportedGun(FVRFireArm gun)
		{
			if (gun is TubeFedShotgun)
			{
				return true;
			}
			if (gun is LeverActionFirearm)
			{
				return true;
			}
			return false;
		}

		private static bool TryGetPort(FVRFireArm gun, out Vector3 portPos, out Vector3 bore, out Vector3 faceNormal)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c3: Unknown result type (might be due to invalid IL or missing references)
			portPos = Vector3.zero;
			bore = Vector3.forward;
			faceNormal = Vector3.up;
			Transform val = ResolvePortTransform(gun);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			portPos = val.position;
			bore = BoreDirection(gun);
			Vector3 val2 = portPos - ((Component)gun).transform.position;
			Vector3 val3 = ((Component)gun).transform.position + bore * Vector3.Dot(val2, bore);
			Vector3 val4 = portPos - val3;
			if (((Vector3)(ref val4)).sqrMagnitude < 1E-06f)
			{
				faceNormal = -((Component)gun).transform.up;
			}
			else
			{
				faceNormal = ((Vector3)(ref val4)).normalized;
			}
			return true;
		}

		private static Transform ResolvePortTransform(FVRFireArm gun)
		{
			int instanceID = ((Object)gun).GetInstanceID();
			if (PortCache.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Transform val = null;
			LeverActionFirearm val2 = (LeverActionFirearm)(object)((gun is LeverActionFirearm) ? gun : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.LoadingGate != (Object)null)
			{
				val = val2.LoadingGate;
			}
			if ((Object)(object)val == (Object)null)
			{
				TubeFedShotgun val3 = (TubeFedShotgun)(object)((gun is TubeFedShotgun) ? gun : null);
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3.ReloadTriggerWell != (Object)null)
				{
					val = val3.ReloadTriggerWell.transform;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				FVRFireArmReloadTriggerWell[] componentsInChildren = ((Component)gun).GetComponentsInChildren<FVRFireArmReloadTriggerWell>(true);
				if (componentsInChildren != null && componentsInChildren.Length > 0 && (Object)(object)componentsInChildren[0] != (Object)null)
				{
					val = ((Component)componentsInChildren[0]).transform;
				}
			}
			if ((Object)(object)val == (Object)null && (Object)(object)gun.Magazine != (Object)null)
			{
				val = ((Component)gun.Magazine).transform;
			}
			if (PortCache.Count > 256)
			{
				PortCache.Clear();
			}
			PortCache[instanceID] = val;
			return val;
		}

		private static Vector3 BoreDirection(FVRFireArm gun)
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = ((Component)gun).transform.forward;
			Transform val = gun.GetMuzzle();
			if ((Object)(object)val == (Object)null)
			{
				val = gun.MuzzlePos;
			}
			if ((Object)(object)val != (Object)null)
			{
				Vector3 val2 = val.position - ((Component)gun).transform.position;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.0004f)
				{
					result = ((Vector3)(ref val2)).normalized;
				}
			}
			return result;
		}

		private Vector3 OutwardFor(FVRFireArm gun, Vector3 bore)
		{
			//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_0012: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)gun).transform.TransformDirection(_manualBaseLocal);
			val -= bore * Vector3.Dot(val, bore);
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = Vector3.up - bore * Vector3.Dot(Vector3.up, bore);
			}
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = Vector3.Cross(bore, Vector3.right);
			}
			((Vector3)(ref val)).Normalize();
			return Quaternion.AngleAxis((float)_rollStep * RollStep, bore) * val;
		}

		private Vector3 BuildSnapForward(FVRFireArm gun, Vector3 bore)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = OutwardFor(gun, bore);
			float num = AttachPitch * ((float)Math.PI / 180f);
			Vector3 val2 = bore * Mathf.Cos(num) - val * Mathf.Sin(num);
			Vector3 result = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref result)).sqrMagnitude < 0.01f)
			{
				result = bore;
			}
			return result;
		}

		private Quaternion BuildSnapRotation(FVRFireArm gun, Vector3 bore)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = OutwardFor(gun, bore);
			Vector3 val2 = BuildSnapForward(gun, bore);
			Vector3 val3 = val - val2 * Vector3.Dot(val, val2);
			if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f)
			{
				val3 = Vector3.up - val2 * Vector3.Dot(Vector3.up, val2);
			}
			if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f)
			{
				val3 = Vector3.Cross(val2, Vector3.right);
			}
			((Vector3)(ref val3)).Normalize();
			Quaternion val4 = Quaternion.LookRotation(val2, val3);
			return val4 * Quaternion.AngleAxis(BaseRoll, Vector3.forward);
		}

		private void Attach(FVRFireArm gun, Vector3 portPos, Vector3 bore, Vector3 faceNormal)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			_gun = gun;
			_mag = gun.Magazine;
			_attached = true;
			_push = 0f;
			_dispatched = 0;
			_otherPushing = false;
			_lastPortWorld = portPos;
			_attachHandLocal = ((Component)gun).transform.InverseTransformPoint(((HandInput)(ref ((FVRInteractiveObject)_clip).m_hand.Input)).Pos);
			((FVRPhysicalObject)_clip).IsPivotLocked = true;
			((FVRInteractiveObject)_clip).SetAllCollidersToLayer(false, "NoCol");
			ApplySnapPose(portPos, bore, 0f);
			UpdatePreviewRotation();
			UpdatePlunger();
			PlayGunAudio((FirearmAudioEventType)20, _clip.AffixClip, ((Component)this).transform.position);
			if (DebugLog)
			{
				Debug.Log((object)$"[Speedloader] snapped to {((Object)gun).name} ({((object)gun).GetType().Name}) steps={_rollStep}");
			}
		}

		private void Detach(bool playSound)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			FVRFireArm gun = _gun;
			_attached = false;
			_gun = null;
			_mag = null;
			_push = 0f;
			_dispatched = 0;
			_otherPushing = false;
			if ((Object)(object)_clip != (Object)null)
			{
				((FVRPhysicalObject)_clip).IsPivotLocked = false;
				((FVRInteractiveObject)_clip).SetAllCollidersToLayer(false, "Default");
				if (playSound && (Object)(object)gun != (Object)null)
				{
					_gun = gun;
					PlayGunAudio((FirearmAudioEventType)21, _clip.RemoveClip, ((Component)this).transform.position);
					_gun = null;
				}
			}
			_cooldown = AttachCooldown;
			_armed = false;
			UpdatePlunger();
			if (DebugLog)
			{
				Debug.Log((object)"[Speedloader] detached");
			}
		}

		private void ApplySnapPose(Vector3 portPos, Vector3 bore, float push)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_002f: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = BuildSnapRotation(_gun, bore);
			Vector3 val2 = val * Vector3.forward;
			Vector3 val3 = portPos + val2 * PortInset;
			Vector3 val4 = val3 - val * _localNose;
			val4 += val2 * (push * BodyTravelFactor);
			((FVRPhysicalObject)_clip).PivotLockPos = val4;
			((FVRPhysicalObject)_clip).PivotLockRot = val;
		}

		private void UpdateAttached(FVRViveHand hand)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_gun == (Object)null || !IsSupportedGun(_gun) || (Object)(object)_gun.Magazine == (Object)null)
			{
				Detach(playSound: false);
				return;
			}
			_mag = _gun.Magazine;
			if (!TryGetPort(_gun, out var portPos, out var bore, out var _))
			{
				Detach(playSound: false);
				return;
			}
			_lastPortWorld = portPos;
			Quaternion val = BuildSnapRotation(_gun, bore);
			Vector3 val2 = val * Vector3.forward;
			Vector3 val3 = ((Component)_gun).transform.InverseTransformDirection(val2);
			Vector3 val4 = ((Component)_gun).transform.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos);
			_push = ComputePush(hand, val3);
			ApplySnapPose(portPos, bore, _push);
			FeedRounds(_push);
			Vector3 val5 = val4 - _attac