Decompiled source of HuntHuntingBow v1.0.0

HuntHuntingBow.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BitWizrd.Palming;
using FistVR;
using HarmonyLib;
using OtherLoader;
using UnityEngine;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace BitWizrd.HuntHuntingBow
{
	[BepInPlugin("BitWizrd.HuntHuntingBow", "HuntHuntingBow", "1.0.0")]
	[BepInProcess("h3vr.exe")]
	[Description("Built with MeatKit")]
	[BepInDependency("h3vr.otherloader", "1.3.0")]
	public class HuntHuntingBowPlugin : 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(), "BitWizrd.HuntHuntingBow");
			OtherLoader.RegisterDirectLoad(BasePath, "BitWizrd.HuntHuntingBow", "", "huntingbow", "", "");
		}
	}
}
namespace BitWizrd.Archery
{
	public sealed class ArrowRef
	{
		private const string TypeName = "BitWizrd.SpecialAmmo.Arrow";

		private static Type s_type;

		private static float s_nextLookup;

		private static FieldInfo s_instances;

		private static FieldInfo s_nockPoint;

		private static FieldInfo s_tipPoint;

		private static PropertyInfo s_isLoose;

		private static MethodInfo s_drawLength;

		private static MethodInfo s_onNocked;

		private static MethodInfo s_launch;

		private static MethodInfo s_release;

		private static readonly Dictionary<int, ArrowRef> s_cache = new Dictionary<int, ArrowRef>();

		public readonly FVRFireArmRound Round;

		public readonly Transform NockPoint;

		public readonly Transform TipPoint;

		public static bool Available
		{
			get
			{
				if ((object)s_type != null)
				{
					return true;
				}
				if (Time.unscaledTime < s_nextLookup)
				{
					return false;
				}
				s_nextLookup = Time.unscaledTime + 2f;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					Type type = null;
					try
					{
						type = assemblies[i].GetType("BitWizrd.SpecialAmmo.Arrow", throwOnError: false);
					}
					catch (Exception)
					{
					}
					if ((object)type != null)
					{
						s_type = type;
						s_instances = type.GetField("Instances", BindingFlags.Static | BindingFlags.Public);
						s_nockPoint = type.GetField("NockPoint", BindingFlags.Instance | BindingFlags.Public);
						s_tipPoint = type.GetField("TipPoint", BindingFlags.Instance | BindingFlags.Public);
						s_isLoose = type.GetProperty("IsLoose", BindingFlags.Instance | BindingFlags.Public);
						s_drawLength = type.GetMethod("DrawLength", BindingFlags.Instance | BindingFlags.Public);
						s_onNocked = type.GetMethod("OnNocked", BindingFlags.Instance | BindingFlags.Public);
						s_launch = type.GetMethod("Launch", BindingFlags.Instance | BindingFlags.Public);
						s_release = type.GetMethod("ReleaseToLoose", BindingFlags.Instance | BindingFlags.Public);
						if ((object)s_instances == null || (object)s_isLoose == null || (object)s_drawLength == null || (object)s_onNocked == null || (object)s_launch == null || (object)s_release == null)
						{
							Debug.LogError((object)"ArrowRef: BitWizrd.SpecialAmmo.Arrow is missing a member the bow needs (is the ammo mod up to date?).");
						}
						return true;
					}
				}
				return false;
			}
		}

		public Transform transform => ((Component)Round).transform;

		public GameObject gameObject => ((Component)Round).gameObject;

		public bool IsHeld => ((FVRInteractiveObject)Round).IsHeld;

		public FVRViveHand m_hand => ((FVRInteractiveObject)Round).m_hand;

		public List<ProxyRound> ProxyRounds => Round.ProxyRounds;

		public bool IsLoose => (object)s_isLoose != null && (bool)s_isLoose.GetValue(Round, null);

		private ArrowRef(FVRFireArmRound round)
		{
			Round = round;
			NockPoint = (Transform)(((object)s_nockPoint == null) ? null : /*isinst with value type is only supported in some contexts*/);
			TipPoint = (Transform)(((object)s_tipPoint == null) ? null : /*isinst with value type is only supported in some contexts*/);
		}

		public static void All(List<ArrowRef> into)
		{
			into.Clear();
			if (!Available || (object)s_instances == null || !(s_instances.GetValue(null) is IList list))
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				object? obj = list[i];
				ArrowRef arrowRef = Of((Component)((obj is Component) ? obj : null));
				if (arrowRef != null)
				{
					into.Add(arrowRef);
				}
			}
			if (s_cache.Count > list.Count + 16)
			{
				PurgeCache();
			}
		}

		public static ArrowRef Of(Component c)
		{
			FVRFireArmRound val = (FVRFireArmRound)(object)((c is FVRFireArmRound) ? c : null);
			if ((Object)(object)val == (Object)null || !Available)
			{
				return null;
			}
			if ((object)s_type != null && !s_type.IsInstanceOfType(val))
			{
				return null;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (s_cache.TryGetValue(instanceID, out var value) && (Object)(object)value.Round == (Object)(object)val)
			{
				return value;
			}
			value = new ArrowRef(val);
			s_cache[instanceID] = value;
			return value;
		}

		public static ArrowRef Of(GameObject go)
		{
			if ((Object)(object)go == (Object)null || !Available || (object)s_type == null)
			{
				return null;
			}
			return Of(go.GetComponent(s_type));
		}

		private static void PurgeCache()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, ArrowRef> item in s_cache)
			{
				if ((Object)(object)item.Value.Round == (Object)null)
				{
					list.Add(item.Key);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				s_cache.Remove(list[i]);
			}
		}

		public float DrawLength()
		{
			return ((object)s_drawLength == null) ? 0.5f : ((float)s_drawLength.Invoke(Round, null));
		}

		public void ForceBreakInteraction()
		{
			((FVRInteractiveObject)Round).ForceBreakInteraction();
		}

		public void BeginInteraction(FVRViveHand hand)
		{
			((FVRInteractiveObject)Round).BeginInteraction(hand);
		}

		public void UpdateProxyDisplay()
		{
			Round.UpdateProxyDisplay();
		}

		public void OnNocked(Component holder, Collider[] holderColliders)
		{
			if ((object)s_onNocked != null)
			{
				s_onNocked.Invoke(Round, new object[2] { holder, holderColliders });
			}
		}

		public void Launch(Vector3 velocity, Collider[] holderColliders, int shooterIFF, float chargeDamageMult = 1f)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((object)s_launch != null)
			{
				s_launch.Invoke(Round, new object[4] { velocity, holderColliders, shooterIFF, chargeDamageMult });
			}
		}

		public void ReleaseToLoose()
		{
			if ((object)s_release != null)
			{
				s_release.Invoke(Round, null);
			}
		}

		private static bool IsNull(ArrowRef r)
		{
			return object.ReferenceEquals(r, null) || (Object)(object)r.Round == (Object)null;
		}

		public static bool operator ==(ArrowRef a, ArrowRef b)
		{
			bool flag = IsNull(a);
			bool flag2 = IsNull(b);
			if (flag || flag2)
			{
				return flag && flag2;
			}
			return (Object)(object)a.Round == (Object)(object)b.Round;
		}

		public static bool operator !=(ArrowRef a, ArrowRef b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			return obj is ArrowRef && this == (ArrowRef)obj;
		}

		public override int GetHashCode()
		{
			return ((Object)(object)Round != (Object)null) ? ((Object)Round).GetInstanceID() : 0;
		}
	}
	[Serializable]
	public class BowLimbFlex
	{
		public Transform Bone;

		public Vector3 LocalAxis = Vector3.forward;

		public float DegreesAtFullDraw = 0f;

		[HideInInspector]
		public Quaternion RestLocalRotation = Quaternion.identity;
	}
	public class Bow : FVRFireArm
	{
		private class NockedRound
		{
			public FVRObject Wrapper;

			public GameObject Visual;

			public Vector3 NockLocal;

			public float DrawLength;
		}

		[Header("Rig")]
		public Transform StringBone;

		public Transform StringNockPoint;

		public Transform ArrowRest;

		public BowNockGrip StringGrip;

		public BowLimbFlex[] Limbs;

		[Header("Optional drawn string (leave empty for the Hunt bows)")]
		public LineRenderer StringLine;

		public float StringWidth = 0.002f;

		public Transform StringUpperAnchor;

		public Transform StringLowerAnchor;

		[Header("Draw")]
		public float DrawDistance = 0.6f;

		public float MinDrawToFire = 0.05f;

		public float MaxArrowSpeed = 150f;

		public float ChargeMinDraw = 0.05f;

		public float ChargeFullDraw = 0.8f;

		public float MinSpeedFraction = 0.1f;

		public float ChargeCurveExponent = 1.6f;

		public float OverchargeDamageBonus = 0.1f;

		public float StringReturnSpeed = 15f;

		public float DrawSoundAt = 0.5f;

		public float ReleaseSoundAt = 0.5f;

		public float SoundDeadBand = 0.03f;

		[Header("Aim")]
		public bool TwoHandAimBlend = true;

		public float TwoHandAimWeight = 0.4f;

		public float TwoHandAimFade = 6f;

		public bool StringBox = false;

		public float BoxHalfWidth = 0.09f;

		public float BoxShrinkWidth = 0.06f;

		public float BoxHalfHeight = 0.15f;

		public float BoxShrinkHeight = 0.12f;

		public float TearOffDistance = 0.25f;

		public bool TearOffByVelocity = true;

		public float TearOffSpeed = 2.5f;

		public float TearMinGap = 0.08f;

		public float TearRateTau = 0.05f;

		public float TearMaxFrame = 0.04f;

		public float TearBumpGrace = 0.4f;

		public bool RefreshBeforeRender = true;

		public bool TriggerReleasesString = true;

		[Header("Haptics (kept brief on purpose)")]
		public bool FullDrawBuzz = false;

		public float FullDrawThreshold = 0.8f;

		public float FullPowerOff = 0.7f;

		public float ShotCooldown = 0.1f;

		public float FullDrawBuzzAmp = 0.35f;

		public float FullDrawBuzzLength = 0.06f;

		public int FullDrawBuzzFrequency = 150;

		public bool NockBuzz = true;

		public bool ReleaseBuzz = false;

		[Header("Nocking")]
		public CapsuleCollider NockZone;

		public bool NockFromHand = true;

		[Header("Handedness")]
		public bool MirrorForOtherHand = true;

		public bool BuiltForLeftHand = true;

		[Header("Audio (optional; one clip is picked at random each time)")]
		public AudioSource Audio;

		public float AudioVolume = 1f;

		public AudioClip[] NockClips;

		public AudioClip[] WoodTensionClips;

		public AudioClip[] ReleaseTensionClips;

		public AudioClip[] ReleaseClips;

		public AudioClip[] ReleaseSlapClips;

		public AudioClip[] DryReleaseClips;

		private Vector3 m_stringRestLocal;

		private Vector3 m_nockOffsetLocal;

		private Collider[] m_bowColliders;

		private NockedRound m_round;

		private readonly List<ArrowRef> m_arrowBuf = new List<ArrowRef>();

		private bool m_stringHeld;

		private bool m_cancelShot;

		private float m_drawDistance;

		private float m_drawTarget;

		private float m_grabAxisOffset;

		private bool m_playedDrawSound;

		private FVRHapticBuzzProfile m_fullDrawBuzz;

		private bool m_fullDrawBuzzed;

		private float m_nextNockTime;

		private FVRFireArmChamber m_needChamber;

		private Vector2 m_lateral;

		private Vector2 m_grabLateral;

		private float m_lastGap;

		private float m_lastBumpTime = -10f;

		private float m_gapRate;

		private bool m_gapValid;

		private float m_aimBlend;

		private Quaternion m_poseBaseLocalRot = Quaternion.identity;

		private Quaternion m_smoothRot = Quaternion.identity;

		private bool m_aimActive;

		private bool m_mirrored;

		private bool m_warnedNoZone;

		private int m_lastRefreshFrame = -1;

		public bool IsStringHeld => m_stringHeld;

		public bool HasNockedArrow => m_round != null;

		public float Draw01
		{
			get
			{
				float num = EffectiveDraw();
				return (!(num > 0.0001f)) ? 0f : Mathf.Clamp01(m_drawDistance / num);
			}
		}

		public bool IsMirrored => m_mirrored;

		public float EffectiveDraw()
		{
			//IL_002b: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			float num = DrawDistance;
			if (m_round != null && (Object)(object)ArrowRest != (Object)null)
			{
				float num2 = Vector3.Dot(ArrowRest.position - NockAttachRestWorld(), ArrowRest.forward);
				float num3 = m_round.DrawLength - num2;
				num = Mathf.Min(num, Mathf.Max(0.05f, num3));
			}
			return num;
		}

		public override void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d4: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArm)this).Awake();
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(BeforeRender));
			if ((Object)(object)NockZone != (Object)null)
			{
				((Collider)NockZone).isTrigger = true;
			}
			if ((Object)(object)ArrowRest == (Object)null)
			{
				Debug.LogWarning((object)"Bow: ArrowRest is not set; using the bow root (+Z = shot direction).", (Object)(object)this);
				ArrowRest = ((Component)this).transform;
			}
			if ((Object)(object)StringBone != (Object)null)
			{
				m_stringRestLocal = ArrowRest.InverseTransformPoint(StringBone.position);
				if ((Object)(object)StringNockPoint != (Object)null)
				{
					m_nockOffsetLocal = ArrowRest.InverseTransformVector(StringNockPoint.position - StringBone.position);
				}
			}
			if (Limbs != null)
			{
				for (int i = 0; i < Limbs.Length; i++)
				{
					if (Limbs[i] != null && (Object)(object)Limbs[i].Bone != (Object)null)
					{
						Limbs[i].RestLocalRotation = Limbs[i].Bone.localRotation;
					}
				}
			}
			m_bowColliders = ((Component)this).GetComponentsInChildren<Collider>();
			if ((Object)(object)StringGrip != (Object)null)
			{
				StringGrip.Bow = this;
			}
			m_needChamber = PalmingNeedChamber.Attach((FVRFireArm)(object)this);
			PalmingNeedChamber.SetCounting(m_needChamber, counting: true);
			m_fullDrawBuzz = ScriptableObject.CreateInstance<FVRHapticBuzzProfile>();
			m_fullDrawBuzz.BuzzCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);
			m_fullDrawBuzz.BuzzLength = FullDrawBuzzLength;
			m_fullDrawBuzz.Freq = FullDrawBuzzFrequency;
			m_fullDrawBuzz.AmpMult = FullDrawBuzzAmp;
			if ((Object)(object)Audio == (Object)null)
			{
				Audio = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			Audio.playOnAwake = false;
			Audio.spatialBlend = 1f;
			Audio.minDistance = 1f;
			Audio.maxDistance = 25f;
			if ((Object)(object)StringLine != (Object)null)
			{
				StringLine.useWorldSpace = true;
				StringLine.positionCount = 3;
				StringLine.startWidth = StringWidth;
				StringLine.endWidth = StringWidth;
			}
		}

		private Vector3 DrawAxis()
		{
			//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_0011: 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)
			return -ArrowRest.forward;
		}

		private Vector3 StringRestWorld()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			return ArrowRest.TransformPoint(m_stringRestLocal);
		}

		private Vector3 NockWorld()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			return StringRestWorld() + DrawAxis() * m_drawDistance + ArrowRest.TransformVector(new Vector3(m_lateral.x, m_lateral.y, 0f));
		}

		private Vector3 NockAttachWorld()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)StringNockPoint != (Object)null)
			{
				return StringNockPoint.position;
			}
			return NockWorld();
		}

		private Vector3 NockAttachRestWorld()
		{
			//IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			return StringRestWorld() + ArrowRest.TransformVector(m_nockOffsetLocal);
		}

		public void OnStringGrabbed(FVRViveHand hand)
		{
			//IL_0024: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//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_0081: Unknown result type (might be due to invalid IL or missing references)
			m_stringHeld = true;
			m_cancelShot = false;
			m_playedDrawSound = false;
			m_fullDrawBuzzed = false;
			m_grabAxisOffset = Vector3.Dot(((HandInput)(ref hand.Input)).Pos - StringRestWorld(), DrawAxis()) - m_drawDistance;
			Vector3 val = ArrowRest.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos);
			m_grabLateral = new Vector2(val.x, val.y) - m_lateral;
			m_gapValid = false;
			m_gapRate = 0f;
		}

		public void OnStringHeld(FVRViveHand hand)
		{
			//IL_0044: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			if (TriggerReleasesString && hand.Input.TriggerDown && (Object)(object)StringGrip != (Object)null)
			{
				((FVRInteractiveObject)StringGrip).ForceBreakInteraction();
				return;
			}
			float num = Vector3.Dot(((HandInput)(ref hand.Input)).Pos - StringRestWorld(), DrawAxis()) - m_grabAxisOffset;
			m_drawTarget = Mathf.Clamp(num, 0f, EffectiveDraw());
			Vector3 val = ArrowRest.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos);
			Vector2 val2 = new Vector2(val.x, val.y) - m_grabLateral;
			Vector3 val3 = ((HandInput)(ref hand.Input)).Pos - NockWorld();
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (m_gapValid)
			{
				float num2 = Mathf.Max(Time.deltaTime, 0.0005f);
				if (num2 <= TearMaxFrame)
				{
					float num3 = (magnitude - m_lastGap) / num2;
					m_gapRate = Mathf.Lerp(m_gapRate, num3, 1f - Mathf.Exp((0f - num2) / Mathf.Max(0.001f, TearRateTau)));
				}
				else
				{
					m_gapRate = 0f;
				}
			}
			m_lastGap = magnitude;
			m_gapValid = true;
			bool flag = Time.time - m_lastBumpTime < TearBumpGrace;
			bool flag2 = TearOffByVelocity && magnitude > TearMinGap && m_gapRate > TearOffSpeed;
			bool flag3 = TearOffDistance > 0f && magnitude >= TearOffDistance;
			if (m_round != null && !flag && (flag2 || flag3))
			{
				CancelNock(hand);
				return;
			}
			if (StringBox)
			{
				float num4 = Mathf.Max(0.02f, BoxHalfWidth - BoxShrinkWidth * m_drawTarget);
				float num5 = Mathf.Max(0.03f, BoxHalfHeight - BoxShrinkHeight * m_drawTarget);
				m_lateral = new Vector2(SoftClamp(val2.x, 0f - num4, num4), SoftClamp(val2.y, 0f - num5, num5));
			}
			CheckFullDraw(hand);
			float num6 = EffectiveDraw();
			float num7 = ((!(num6 > 0.0001f)) ? 0f : (m_drawTarget / num6));
			if (!m_playedDrawSound)
			{
				if (m_round != null && num7 >= DrawSoundAt)
				{
					m_playedDrawSound = true;
					Play(WoodTensionClips);
				}
			}
			else if (num7 <= ReleaseSoundAt - SoundDeadBand)
			{
				m_playedDrawSound = false;
				Play(ReleaseTensionClips);
			}
		}

		private static float SoftClamp(float v, float min, float max)
		{
			if (v < min)
			{
				return min - (min - v) / (1f + 30f * (min - v));
			}
			if (v > max)
			{
				return max + (v - max) / (1f + 30f * (v - max));
			}
			return v;
		}

		private void CancelNock(FVRViveHand hand)
		{
			NockedRound round = m_round;
			m_cancelShot = true;
			if ((Object)(object)StringGrip != (Object)null)
			{
				((FVRInteractiveObject)StringGrip).ForceBreakInteraction();
			}
			m_nextNockTime = Time.time + 0.2f;
			if (round != null)
			{
				m_round = null;
				ArrowRef arrowRef = SpawnReal(round);
				if (!(arrowRef == null))
				{
					hand.ForceSetInteractable((FVRInteractiveObject)(object)arrowRef.Round);
					arrowRef.BeginInteraction(hand);
				}
			}
		}

		private void CheckFullDraw(FVRViveHand hand)
		{
			if ((Object)(object)hand == (Object)null)
			{
				return;
			}
			float num = EffectiveDraw();
			float num2 = ((!(num > 0.0001f)) ? 0f : (m_drawTarget / num));
			if (!m_fullDrawBuzzed && num2 >= FullDrawThreshold)
			{
				m_fullDrawBuzzed = true;
				if (FullDrawBuzz && (Object)(object)m_fullDrawBuzz != (Object)null)
				{
					hand.Buzz(m_fullDrawBuzz);
				}
			}
			else if (m_fullDrawBuzzed && num2 < FullPowerOff)
			{
				m_fullDrawBuzzed = false;
			}
		}

		public void OnStringReleased(FVRViveHand hand)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = !m_cancelShot && m_round != null && Draw01 >= MinDrawToFire;
			float draw = Draw01;
			Vector3 aim = AimDir();
			m_stringHeld = false;
			m_cancelShot = false;
			m_drawTarget = 0f;
			if (flag)
			{
				Fire(draw, aim);
				if (ReleaseBuzz)
				{
					if ((Object)(object)hand != (Object)null)
					{
						hand.Buzz(hand.Buzzer.Buzz_GunShot);
					}
					if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null)
					{
						((FVRInteractiveObject)this).m_hand.Buzz(((FVRInteractiveObject)this).m_hand.Buzzer.Buzz_GunShot);
					}
				}
			}
			else if (draw > 0.05f)
			{
				Play(DryReleaseClips);
			}
		}

		private Vector3 AimDir()
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0075: 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_0067: 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_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_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_0094: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward = ArrowRest.forward;
			Vector3 val = NockAttachWorld() - ArrowRest.TransformVector(new Vector3(m_lateral.x, m_lateral.y, 0f));
			Vector3 val2 = ArrowRest.position - val;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0004f)
			{
				return forward;
			}
			((Vector3)(ref val2)).Normalize();
			if (Vector3.Dot(val2, forward) < 0.8f)
			{
				return forward;
			}
			return val2;
		}

		private void Fire(float draw01, Vector3 aim)
		{
			//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)
			NockedRound round = m_round;
			m_round = null;
			ArrowRef arrowRef = SpawnReal(round);
			if (!(arrowRef == null))
			{
				float num = Mathf.InverseLerp(ChargeMinDraw, Mathf.Max(ChargeMinDraw + 0.01f, ChargeFullDraw), draw01);
				float num2 = MaxArrowSpeed * Mathf.Lerp(MinSpeedFraction, 1f, Mathf.Pow(num, Mathf.Max(0.1f, ChargeCurveExponent)));
				float num3 = Mathf.InverseLerp(ChargeFullDraw, 1f, draw01) * OverchargeDamageBonus;
				m_nextNockTime = Time.time + ShotCooldown;
				arrowRef.Launch(aim * num2, m_bowColliders, GM.CurrentPlayerBody.GetPlayerIFF(), 1f + num3);
				m_fullDrawBuzzed = false;
				Play(ReleaseClips);
				Play(ReleaseSlapClips);
			}
		}

		public override void OnCollisionEnter(Collision col)
		{
			((FVRPhysicalObject)this).OnCollisionEnter(col);
			if (!col.collider.isTrigger)
			{
				m_lastBumpTime = Time.time;
			}
		}

		private void OnCollisionStay(Collision col)
		{
			if (!col.collider.isTrigger)
			{
				m_lastBumpTime = Time.time;
			}
		}

		public void ArrowUnnocked(Component arrow)
		{
		}

		public void Unnock(ArrowRef arrow)
		{
		}

		private NockedRound MakeRound(ArrowRef a)
		{
			//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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			FVRObject objectWrapper = ((FVRPhysicalObject)a.Round).ObjectWrapper;
			if ((Object)(object)objectWrapper == (Object)null || (Object)(object)((AnvilAsset)objectWrapper).GetGameObject() == (Object)null)
			{
				return null;
			}
			NockedRound nockedRound = new NockedRound();
			nockedRound.Wrapper = objectWrapper;
			nockedRound.NockLocal = a.transform.InverseTransformPoint(a.NockPoint.position);
			nockedRound.DrawLength = a.DrawLength();
			Mesh val = null;
			Material val2 = null;
			try
			{
				val = AM.GetRoundMesh(a.Round.RoundType, a.Round.RoundClass);
				val2 = AM.GetRoundMaterial(a.Round.RoundType, a.Round.RoundClass);
			}
			catch (Exception)
			{
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Renderer unfiredRenderer = a.Round.UnfiredRenderer;
				MeshFilter val3 = ((!((Object)(object)unfiredRenderer != (Object)null)) ? null : ((Component)unfiredRenderer).GetComponent<MeshFilter>());
				if ((Object)(object)val3 != (Object)null)
				{
					val = val3.sharedMesh;
				}
				if ((Object)(object)unfiredRenderer != (Object)null)
				{
					val2 = unfiredRenderer.sharedMaterial;
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject val4 = new GameObject("NockedArrow");
			val4.transform.position = a.transform.position;
			val4.transform.rotation = a.transform.rotation;
			val4.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = val2;
			nockedRound.Visual = val4;
			return nockedRound;
		}

		private ArrowRef SpawnReal(NockedRound r)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (r == null)
			{
				return null;
			}
			Transform val = ((!((Object)(object)r.Visual != (Object)null)) ? ((Component)this).transform : r.Visual.transform);
			GameObject go = Object.Instantiate<GameObject>(((AnvilAsset)r.Wrapper).GetGameObject(), val.position, val.rotation);
			if ((Object)(object)r.Visual != (Object)null)
			{
				Object.Destroy((Object)(object)r.Visual);
			}
			return ArrowRef.Of(go);
		}

		private void ReleaseRoundToWorld()
		{
			NockedRound round = m_round;
			m_round = null;
			SpawnReal(round);
		}

		private static bool ShaftInCapsule(Vector3 tail, Vector3 head, CapsuleCollider cap)
		{
			//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_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_009c: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_012b: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)cap).transform;
			Vector3 lossyScale = transform.lossyScale;
			Vector3 val;
			float num;
			float num2;
			if (cap.direction == 0)
			{
				val = transform.right;
				num = Mathf.Abs(lossyScale.x);
				num2 = Mathf.Max(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z));
			}
			else if (cap.direction == 1)
			{
				val = transform.up;
				num = Mathf.Abs(lossyScale.y);
				num2 = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z));
			}
			else
			{
				val = transform.forward;
				num = Mathf.Abs(lossyScale.z);
				num2 = Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y));
			}
			float num3 = cap.radius * num2;
			float num4 = Mathf.Max(0f, cap.height * num * 0.5f - num3);
			Vector3 val2 = transform.TransformPoint(cap.center);
			Vector3 p = val2 - val * num4;
			Vector3 q = val2 + val * num4;
			return SegmentDistance(tail, head, p, q) <= num3 + 0.01f;
		}

		private static float SegmentDistance(Vector3 p1, Vector3 q1, Vector3 p2, Vector3 q2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = q1 - p1;
			Vector3 val2 = q2 - p2;
			Vector3 val3 = p1 - p2;
			float num = Vector3.Dot(val, val);
			float num2 = Vector3.Dot(val2, val2);
			float num3 = Vector3.Dot(val2, val3);
			if (num <= 1E-08f && num2 <= 1E-08f)
			{
				return ((Vector3)(ref val3)).magnitude;
			}
			float num4;
			float num5;
			if (num <= 1E-08f)
			{
				num4 = 0f;
				num5 = Mathf.Clamp01(num3 / num2);
			}
			else
			{
				float num6 = Vector3.Dot(val, val3);
				if (num2 <= 1E-08f)
				{
					num5 = 0f;
					num4 = Mathf.Clamp01((0f - num6) / num);
				}
				else
				{
					float num7 = Vector3.Dot(val, val2);
					float num8 = num * num2 - num7 * num7;
					num4 = ((!(num8 > 1E-08f)) ? 0f : Mathf.Clamp01((num7 * num3 - num6 * num2) / num8));
					num5 = (num7 * num4 + num3) / num2;
					if (num5 < 0f)
					{
						num5 = 0f;
						num4 = Mathf.Clamp01((0f - num6) / num);
					}
					else if (num5 > 1f)
					{
						num5 = 1f;
						num4 = Mathf.Clamp01((num7 - num6) / num);
					}
				}
			}
			Vector3 val4 = p1 + val * num4 - (p2 + val2 * num5);
			return ((Vector3)(ref val4)).magnitude;
		}

		private void TryAutoNock()
		{
			//IL_010a: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			if (m_round != null || m_stringHeld || (Object)(object)StringBone == (Object)null || Time.time < m_nextNockTime)
			{
				return;
			}
			if ((Object)(object)NockZone == (Object)null)
			{
				if (!m_warnedNoZone)
				{
					m_warnedNoZone = true;
					Debug.LogWarning((object)"Bow: NockZone is not set, so arrows cannot nock. Assign a CapsuleCollider.", (Object)(object)this);
				}
				return;
			}
			ArrowRef.All(m_arrowBuf);
			for (int i = 0; i < m_arrowBuf.Count; i++)
			{
				ArrowRef arrowRef = m_arrowBuf[i];
				if (arrowRef == null || !arrowRef.IsLoose || (Object)(object)arrowRef.NockPoint == (Object)null || !arrowRef.IsHeld || !NockFromHand || (Object)(object)arrowRef.m_hand == (Object)null || (Object)(object)arrowRef.m_hand == (Object)(object)((FVRInteractiveObject)this).m_hand)
				{
					continue;
				}
				bool flag = true;
				Vector3 position = arrowRef.NockPoint.position;
				Vector3 head = ((!((Object)(object)arrowRef.TipPoint != (Object)null)) ? (arrowRef.transform.position + arrowRef.transform.forward * 0.5f) : arrowRef.TipPoint.position);
				if (!ShaftInCapsule(position, head, NockZone))
				{
					continue;
				}
				NockedRound nockedRound = MakeRound(arrowRef);
				if (nockedRound == null)
				{
					continue;
				}
				FVRViveHand val = null;
				if (arrowRef.ProxyRounds != null && arrowRef.ProxyRounds.Count > 0)
				{
					FVRViveHand hand = arrowRef.m_hand;
					if ((Object)(object)hand == (Object)null || (Object)(object)arrowRef.ProxyRounds[0].ObjectWrapper == (Object)null)
					{
						Object.Destroy((Object)(object)nockedRound.Visual);
						continue;
					}
					arrowRef.Round.CycleToProxy(true, false);
					arrowRef.ForceBreakInteraction();
					val = hand;
					flag = false;
				}
				FVRViveHand val2 = null;
				if (flag)
				{
					val2 = arrowRef.m_hand;
					arrowRef.ForceBreakInteraction();
				}
				m_round = nockedRound;
				Object.Destroy((Object)(object)arrowRef.gameObject);
				m_fullDrawBuzzed = false;
				if ((Object)(object)val2 != (Object)null && (Object)(object)StringGrip != (Object)null)
				{
					val2.ForceSetInteractable((FVRInteractiveObject)(object)StringGrip);
					((FVRInteractiveObject)StringGrip).BeginInteraction(val2);
				}
				Play(NockClips);
				if (NockBuzz)
				{
					FVRViveHand val3 = (((Object)(object)val2 != (Object)null) ? val2 : ((!((Object)(object)val != (Object)null)) ? ((FVRInteractiveObject)this).m_hand : val));
					if ((Object)(object)val3 != (Object)null)
					{
						val3.Buzz(val3.Buzzer.Buzz_BeginInteraction);
					}
				}
				break;
			}
		}

		private void UpdateAimTarget()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((FVRInteractiveObject)this).PoseOverride == (Object)null)
			{
				return;
			}
			if (!((FVRInteractiveObject)this).IsHeld || !((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null))
			{
				if (m_aimActive)
				{
					((FVRInteractiveObject)this).PoseOverride.localRotation = m_poseBaseLocalRot;
					m_aimActive = false;
				}
				m_aimBlend = 0f;
				return;
			}
			bool flag = TwoHandAimBlend && m_stringHeld && (Object)(object)StringGrip != (Object)null && (Object)(object)((FVRInteractiveObject)StringGrip).m_hand != (Object)null && (Object)(object)((FVRInteractiveObject)StringGrip).m_hand != (Object)(object)((FVRInteractiveObject)this).m_hand;
			m_aimBlend = Mathf.MoveTowards(m_aimBlend, (!flag) ? 0f : 1f, TwoHandAimFade * Time.fixedDeltaTime);
			if (!(m_aimBlend > 0f))
			{
				if (m_aimActive)
				{
					((FVRInteractiveObject)this).PoseOverride.localRotation = m_poseBaseLocalRot;
					m_aimActive = false;
				}
				else
				{
					m_poseBaseLocalRot = ((FVRInteractiveObject)this).PoseOverride.localRotation;
				}
				return;
			}
			Quaternion handRot = ((FVRInteractiveObject)this).m_handRot;
			Quaternion val = handRot * Quaternion.Inverse(m_poseBaseLocalRot);
			if (m_aimBlend > 0f && flag)
			{
				Vector3 val2 = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Pos - ((HandInput)(ref ((FVRInteractiveObject)StringGrip).m_hand.Input)).Pos;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
				{
					Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, val * Vector3.up);
					val = Quaternion.Slerp(val, val3, Mathf.Clamp01(TwoHandAimWeight) * m_aimBlend);
				}
			}
			if (!m_aimActive)
			{
				m_smoothRot = ((Component)this).transform.rotation;
				m_aimActive = true;
			}
			m_smoothRot = val;
			((FVRInteractiveObject)this).PoseOverride.localRotation = Quaternion.Inverse(m_smoothRot) * handRot;
		}

		public override void FVRFixedUpdate()
		{
			UpdateAimTarget();
			((FVRFireArm)this).FVRFixedUpdate();
		}

		public override void FVRUpdate()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArm)this).FVRUpdate();
			if (((FVRInteractiveObject)this).IsHeld)
			{
				TryAutoNock();
			}
			if (m_stringHeld)
			{
				m_drawDistance = m_drawTarget;
			}
			else
			{
				m_drawDistance = Mathf.MoveTowards(m_drawDistance, 0f, StringReturnSpeed * Time.deltaTime);
				m_lateral = Vector2.MoveTowards(m_lateral, Vector2.zero, StringReturnSpeed * 0.2f * Time.deltaTime);
			}
			ApplyString();
			ApplyLimbs();
			ApplyStringLine();
			FollowNockedArrow();
		}

		private void BeforeRender(Camera cam)
		{
			if (RefreshBeforeRender && !((Object)(object)this == (Object)null) && ((Behaviour)this).isActiveAndEnabled && m_lastRefreshFrame != Time.frameCount)
			{
				m_lastRefreshFrame = Time.frameCount;
				if (((FVRInteractiveObject)this).IsHeld || m_round != null)
				{
					ApplyString();
					ApplyLimbs();
					ApplyStringLine();
					FollowNockedArrow();
				}
			}
		}

		private void ApplyString()
		{
			//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_001f: 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)
			Vector3 position = NockWorld();
			if ((Object)(object)StringBone != (Object)null)
			{
				StringBone.position = position;
			}
			if ((Object)(object)StringGrip != (Object)null)
			{
				((Component)StringGrip).transform.position = position;
			}
		}

		private void ApplyStringLine()
		{
			//IL_0046: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)StringLine == (Object)null) && !((Object)(object)StringUpperAnchor == (Object)null) && !((Object)(object)StringLowerAnchor == (Object)null))
			{
				StringLine.SetPosition(0, StringUpperAnchor.position);
				StringLine.SetPosition(1, NockWorld());
				StringLine.SetPosition(2, StringLowerAnchor.position);
			}
		}

		private void ApplyLimbs()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (Limbs == null)
			{
				return;
			}
			float draw = Draw01;
			for (int i = 0; i < Limbs.Length; i++)
			{
				BowLimbFlex bowLimbFlex = Limbs[i];
				if (bowLimbFlex != null && !((Object)(object)bowLimbFlex.Bone == (Object)null))
				{
					bowLimbFlex.Bone.localRotation = bowLimbFlex.RestLocalRotation * Quaternion.AngleAxis(bowLimbFlex.DegreesAtFullDraw * draw, bowLimbFlex.LocalAxis);
				}
			}
		}

		private void FollowNockedArrow()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (m_round != null && !((Object)(object)m_round.Visual == (Object)null))
			{
				Transform transform = m_round.Visual.transform;
				transform.rotation = Quaternion.LookRotation(AimDir(), ArrowRest.up);
				transform.position = NockAttachWorld() - transform.rotation * m_round.NockLocal;
			}
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			if (MirrorForOtherHand && (Object)(object)hand != (Object)null)
			{
				SetMirrored(hand.IsThisTheRightHand == BuiltForLeftHand);
			}
			((FVRFireArm)this).BeginInteraction(hand);
		}

		private void SetMirrored(bool want)
		{
			if (want == m_mirrored || m_stringHeld || (Object)(object)ArrowRest == (Object)null || (Object)(object)ArrowRest.parent == (Object)null)
			{
				return;
			}
			Transform parent = ArrowRest.parent;
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (HoldsMesh(child))
				{
					MirrorVisual(child);
				}
				else
				{
					MirrorRigid(child);
				}
			}
			m_stringRestLocal.x = 0f - m_stringRestLocal.x;
			m_nockOffsetLocal.x = 0f - m_nockOffsetLocal.x;
			m_lateral.x = 0f - m_lateral.x;
			m_mirrored = want;
		}

		private static bool HoldsMesh(Transform t)
		{
			Renderer[] componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (componentsInChildren[i] is MeshRenderer || componentsInChildren[i] is SkinnedMeshRenderer)
				{
					return true;
				}
			}
			return false;
		}

		private static void MirrorVisual(Transform t)
		{
			//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_001f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = t.localPosition;
			t.localPosition = new Vector3(0f - localPosition.x, localPosition.y, localPosition.z);
			Quaternion localRotation = t.localRotation;
			t.localRotation = new Quaternion(localRotation.x, 0f - localRotation.y, 0f - localRotation.z, localRotation.w);
			Vector3 localScale = t.localScale;
			t.localScale = new Vector3(0f - localScale.x, localScale.y, localScale.z);
		}

		private static void MirrorRigid(Transform t)
		{
			//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_001f: 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_004f: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_0114: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = t.localPosition;
			t.localPosition = new Vector3(0f - localPosition.x, localPosition.y, localPosition.z);
			Quaternion localRotation = t.localRotation;
			t.localRotation = new Quaternion(localRotation.x, 0f - localRotation.y, 0f - localRotation.z, localRotation.w);
			BoxCollider component = ((Component)t).GetComponent<BoxCollider>();
			if ((Object)(object)component != (Object)null)
			{
				component.center = new Vector3(0f - component.center.x, component.center.y, component.center.z);
			}
			SphereCollider component2 = ((Component)t).GetComponent<SphereCollider>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.center = new Vector3(0f - component2.center.x, component2.center.y, component2.center.z);
			}
			CapsuleCollider component3 = ((Component)t).GetComponent<CapsuleCollider>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.center = new Vector3(0f - component3.center.x, component3.center.y, component3.center.z);
			}
			for (int i = 0; i < t.childCount; i++)
			{
				MirrorRigid(t.GetChild(i));
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			if ((Object)(object)StringGrip != (Object)null && ((FVRInteractiveObject)StringGrip).IsHeld)
			{
				m_cancelShot = true;
				((FVRInteractiveObject)StringGrip).ForceBreakInteraction();
			}
			((FVRFireArm)this).EndInteraction(hand);
		}

		public override void OnDestroy()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(BeforeRender));
			if ((Object)(object)m_fullDrawBuzz != (Object)null)
			{
				Object.Destroy((Object)(object)m_fullDrawBuzz);
			}
			if (m_round != null && (Object)(object)m_round.Visual != (Object)null)
			{
				Object.Destroy((Object)(object)m_round.Visual);
			}
			((FVRPhysicalObject)this).OnDestroy();
		}

		public override void SetQuickBeltSlot(FVRQuickBeltSlot slot)
		{
			if ((Object)(object)slot != (Object)null && m_round != null)
			{
				ReleaseRoundToWorld();
			}
			((FVRFireArm)this).SetQuickBeltSlot(slot);
		}

		private void Play(AudioClip[] clips)
		{
			if (!((Object)(object)Audio == (Object)null) && clips != null && clips.Length != 0)
			{
				AudioClip val = clips[Random.Range(0, clips.Length)];
				if ((Object)(object)val != (Object)null)
				{
					Audio.PlayOneShot(val, AudioVolume);
				}
			}
		}
	}
	public class BowNockGrip : FVRInteractiveObject
	{
		[HideInInspector]
		public Bow Bow;

		public override void Awake()
		{
			((FVRInteractiveObject)this).Awake();
			base.EndInteractionIfDistant = false;
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].isTrigger = true;
			}
		}

		public override bool IsInteractable()
		{
			return (Object)(object)Bow != (Object)null && ((FVRInteractiveObject)Bow).IsHeld && ((FVRInteractiveObject)this).IsInteractable();
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			((FVRInteractiveObject)this).BeginInteraction(hand);
			if ((Object)(object)Bow != (Object)null)
			{
				Bow.OnStringGrabbed(hand);
			}
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			((FVRInteractiveObject)this).UpdateInteraction(hand);
			if ((Object)(object)Bow != (Object)null)
			{
				Bow.OnStringHeld(hand);
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			if ((Object)(object)Bow != (Object)null)
			{
				Bow.OnStringReleased(hand);
			}
			((FVRInteractiveObject)this).EndInteraction(hand);
		}
	}
	[Serializable]
	public class CrossbowSide
	{
		public Transform Limb;

		public float RelaxedDegrees = 13f;

		public Transform Tip;

		public Transform End;

		public Transform Hook;

		[HideInInspector]
		public Quaternion LimbRestLocal = Quaternion.identity;

		[HideInInspector]
		public Quaternion TipRestLocal = Quaternion.identity;

		[HideInInspector]
		public Vector3 TipRestDir = Vector3.right;

		[HideInInspector]
		public Vector3 EndRestLocal = Vector3.zero;

		[HideInInspector]
		public float Sign = 1f;
	}
	[Serializable]
	public class CrossbowAimLink
	{
		public Transform Bone;

		public Transform Target;

		[HideInInspector]
		public Quaternion RestLocal = Quaternion.identity;

		[HideInInspector]
		public Vector3 RestDir = Vector3.right;
	}
	public class Crossbow : FVRFireArm
	{
		[Header("Rig")]
		public Transform ArrowRest;

		public Transform Carriage;

		public float CockTravel = 0.3166f;

		public CrossbowSide[] Sides;

		public CrossbowAimLink[] SpringAims;

		[Header("Stretching string")]
		public LineRenderer StringLine;

		public float StringWidth = 0.002f;

		[Header("Cocking (the player pulls the string itself back)")]
		public CrossbowCockingHandle Handle;

		public float LockAt = 0.95f;

		public float CatchSnapSpeed = 10f;

		public float ReturnSpeed = 2.5f;

		public float FireSnapSpeed = 14f;

		[Header("Shot")]
		public float BoltSpeed = 70f;

		public bool AllowDryFire = false;

		public float LoadRadius = 0.06f;

		public float MaxLoadAngle = 30f;

		public float TriggerBreakThreshold = 0.8f;

		public float TriggerResetThreshold = 0.2f;

		[Header("Audio (optional)")]
		public AudioSource Audio;

		public AudioClip LoadSound;

		public AudioClip LockClip;

		public AudioClip FireClip;

		public AudioClip DryClick;

		private Vector3 m_carriageCockedLocal;

		private Collider[] m_ownColliders;

		private ArrowRef m_loaded;

		private readonly List<ArrowRef> m_arrowBuf = new List<ArrowRef>();

		private FVRFireArmChamber m_needChamber;

		private float m_cock;

		private float m_cockTarget;

		private float m_grabOffset;

		private bool m_handleHeld;

		private bool m_locked;

		private bool m_firing;

		private bool m_catching;

		private bool m_hasTriggerCycled;

		public bool IsLocked => m_locked;

		public float Cock01 => m_cock;

		public ArrowRef LoadedArrow => m_loaded;

		public override void Awake()
		{
			//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)
			((FVRFireArm)this).Awake();
			if ((Object)(object)ArrowRest == (Object)null)
			{
				Debug.LogWarning((object)"Crossbow: ArrowRest is not set; using the root (+Z = shot direction).", (Object)(object)this);
				ArrowRest = ((Component)this).transform;
			}
			m_ownColliders = ((Component)this).GetComponentsInChildren<Collider>();
			m_needChamber = PalmingNeedChamber.Attach((FVRFireArm)(object)this);
			PalmingNeedChamber.SetCounting(m_needChamber, counting: false);
			if ((Object)(object)Handle != (Object)null)
			{
				Handle.Crossbow = this;
			}
			if ((Object)(object)Carriage != (Object)null)
			{
				m_carriageCockedLocal = ArrowRest.InverseTransformPoint(Carriage.position);
			}
			CacheRestPose();
			DetectLimbSigns();
			m_cock = 0f;
			m_locked = false;
			if ((Object)(object)StringLine != (Object)null)
			{
				StringLine.useWorldSpace = true;
				StringLine.positionCount = 4;
				StringLine.startWidth = StringWidth;
				StringLine.endWidth = StringWidth;
			}
		}

		private void CacheRestPose()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			if (Sides != null)
			{
				for (int i = 0; i < Sides.Length; i++)
				{
					CrossbowSide crossbowSide = Sides[i];
					if (crossbowSide != null)
					{
						if ((Object)(object)crossbowSide.Hook == (Object)null)
						{
							crossbowSide.Hook = Carriage;
						}
						if ((Object)(object)crossbowSide.Limb != (Object)null)
						{
							crossbowSide.LimbRestLocal = crossbowSide.Limb.localRotation;
						}
						if ((Object)(object)crossbowSide.Tip != (Object)null && (Object)(object)crossbowSide.Hook != (Object)null)
						{
							crossbowSide.TipRestLocal = crossbowSide.Tip.localRotation;
							Vector3 val = crossbowSide.Tip.InverseTransformPoint(crossbowSide.Hook.position);
							crossbowSide.TipRestDir = ((Vector3)(ref val)).normalized;
						}
						if ((Object)(object)crossbowSide.End != (Object)null)
						{
							crossbowSide.EndRestLocal = crossbowSide.End.localPosition;
						}
					}
				}
			}
			if (SpringAims == null)
			{
				return;
			}
			for (int j = 0; j < SpringAims.Length; j++)
			{
				CrossbowAimLink crossbowAimLink = SpringAims[j];
				if (crossbowAimLink != null && !((Object)(object)crossbowAimLink.Bone == (Object)null) && !((Object)(object)crossbowAimLink.Target == (Object)null))
				{
					crossbowAimLink.RestLocal = crossbowAimLink.Bone.localRotation;
					Vector3 val2 = crossbowAimLink.Bone.InverseTransformPoint(crossbowAimLink.Target.position);
					crossbowAimLink.RestDir = ((Vector3)(ref val2)).normalized;
				}
			}
		}

		[ContextMenu("Re-Detect Limb Directions")]
		public void DetectLimbSigns()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0098: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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)
			if (Sides == null)
			{
				return;
			}
			for (int i = 0; i < Sides.Length; i++)
			{
				CrossbowSide crossbowSide = Sides[i];
				if (crossbowSide != null && !((Object)(object)crossbowSide.Limb == (Object)null) && !((Object)(object)crossbowSide.Tip == (Object)null) && !((Object)(object)crossbowSide.Limb.parent == (Object)null))
				{
					Vector3 val = crossbowSide.Limb.parent.InverseTransformDirection(ArrowRest.up);
					Vector3 position = crossbowSide.Tip.position;
					crossbowSide.Limb.localRotation = Quaternion.AngleAxis(5f, val) * crossbowSide.LimbRestLocal;
					float num = Vector3.Dot(crossbowSide.Tip.position - position, ArrowRest.forward);
					crossbowSide.Limb.localRotation = crossbowSide.LimbRestLocal;
					crossbowSide.Sign = ((!(num >= 0f)) ? (-1f) : 1f);
				}
			}
		}

		private Vector3 RelaxedPoint()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0033: Unknown result type (might be due to invalid IL or missing references)
			return ArrowRest.TransformPoint(m_carriageCockedLocal) + ArrowRest.forward * CockTravel;
		}

		public void OnHandleGrabbed(FVRViveHand hand)
		{
			//IL_001b: 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_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)
			m_handleHeld = true;
			m_cockTarget = m_cock;
			m_grabOffset = Vector3.Dot(((HandInput)(ref hand.Input)).Pos - RelaxedPoint(), -ArrowRest.forward) - CockTravel * m_cock;
		}

		public void OnHandleHeld(FVRViveHand hand)
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Dot(((HandInput)(ref hand.Input)).Pos - RelaxedPoint(), -ArrowRest.forward) - m_grabOffset;
			m_cockTarget = Mathf.Clamp01((!(CockTravel > 0.0001f)) ? 0f : (num / CockTravel));
		}

		public void OnHandleReleased(FVRViveHand hand)
		{
			m_handleHeld = false;
		}

		public void ArrowUnnocked(Component arrow)
		{
			ArrowRef arrowRef = ArrowRef.Of(arrow);
			if (arrowRef != null)
			{
				Unnock(arrowRef);
			}
		}

		public void Unnock(ArrowRef arrow)
		{
			if (m_loaded == arrow)
			{
				m_loaded = null;
			}
		}

		private void TryLoad()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00ba: 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)
			if (m_loaded != null || !m_locked)
			{
				return;
			}
			ArrowRef.All(m_arrowBuf);
			for (int i = 0; i < m_arrowBuf.Count; i++)
			{
				ArrowRef arrowRef = m_arrowBuf[i];
				if (!(arrowRef == null) && arrowRef.IsLoose && !arrowRef.IsHeld && !((Object)(object)arrowRef.NockPoint == (Object)null))
				{
					Vector3 val = arrowRef.NockPoint.position - ArrowRest.position;
					if (!(((Vector3)(ref val)).sqrMagnitude > LoadRadius * LoadRadius) && !(Vector3.Angle(arrowRef.transform.forward, ArrowRest.forward) > MaxLoadAngle))
					{
						m_loaded = arrowRef;
						arrowRef.OnNocked((Component)(object)this, m_ownColliders);
						Play(LoadSound);
						break;
					}
				}
			}
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			((FVRFireArm)this).BeginInteraction(hand);
			m_hasTriggerCycled = false;
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			((FVRPhysicalObject)this).UpdateInteraction(hand);
			float triggerFloat = hand.Input.TriggerFloat;
			if (!m_hasTriggerCycled)
			{
				if (triggerFloat >= TriggerBreakThreshold)
				{
					m_hasTriggerCycled = true;
					if (m_locked)
					{
						TryFire(hand);
					}
				}
			}
			else if (triggerFloat <= TriggerResetThreshold)
			{
				m_hasTriggerCycled = false;
			}
		}

		private void TryFire(FVRViveHand hand)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!m_locked || m_firing)
			{
				return;
			}
			if (m_loaded == null && !AllowDryFire)
			{
				Play(DryClick);
				return;
			}
			m_locked = false;
			m_firing = true;
			if (m_loaded != null)
			{
				ArrowRef loaded = m_loaded;
				m_loaded = null;
				loaded.Launch(ArrowRest.forward * BoltSpeed, m_ownColliders, GM.CurrentPlayerBody.GetPlayerIFF());
				Play(FireClip);
				hand.Buzz(hand.Buzzer.Buzz_GunShot);
			}
			else
			{
				Play(DryClick);
			}
		}

		public override void FVRUpdate()
		{
			((FVRFireArm)this).FVRUpdate();
			PalmingNeedChamber.SetCounting(m_needChamber, m_locked && m_loaded == null);
			TryLoad();
			UpdateCock();
			ApplyCarriage();
			ApplyLimbs();
			ApplyStrings();
			ApplySprings();
			ApplyStringLine();
			FollowLoadedArrow();
		}

		private void UpdateCock()
		{
			if (m_firing)
			{
				m_cock = Mathf.MoveTowards(m_cock, 0f, FireSnapSpeed * Time.deltaTime);
				if (m_cock <= 0f)
				{
					m_firing = false;
				}
			}
			else
			{
				if (m_locked)
				{
					return;
				}
				if (m_catching)
				{
					m_cock = Mathf.MoveTowards(m_cock, 1f, CatchSnapSpeed * Time.deltaTime);
					if (m_cock >= 1f)
					{
						Lock();
					}
					return;
				}
				if (m_handleHeld)
				{
					m_cock = m_cockTarget;
				}
				else
				{
					m_cock = Mathf.MoveTowards(m_cock, 0f, ReturnSpeed * Time.deltaTime);
				}
				if (m_cock >= LockAt)
				{
					BeginCatch();
				}
			}
		}

		private void BeginCatch()
		{
			m_catching = true;
			if ((Object)(object)Handle != (Object)null && ((FVRInteractiveObject)Handle).IsHeld)
			{
				((FVRInteractiveObject)Handle).ForceBreakInteraction();
			}
		}

		private void Lock()
		{
			m_locked = true;
			m_catching = false;
			m_cock = 1f;
			m_hasTriggerCycled = (Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null && ((FVRInteractiveObject)this).m_hand.Input.TriggerFloat >= TriggerBreakThreshold;
			Play(LockClip);
			if ((Object)(object)Handle != (Object)null && ((FVRInteractiveObject)Handle).IsHeld)
			{
				FVRViveHand hand = ((FVRInteractiveObject)Handle).m_hand;
				((FVRInteractiveObject)Handle).ForceBreakInteraction();
				if ((Object)(object)hand != (Object)null)
				{
					hand.Buzz(hand.Buzzer.Buzz_GunShot);
				}
			}
		}

		private void ApplyCarriage()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)Carriage == (Object)null))
			{
				Carriage.position = ArrowRest.TransformPoint(m_carriageCockedLocal) + ArrowRest.forward * (CockTravel * (1f - m_cock));
				if ((Object)(object)Handle != (Object)null)
				{
					((Component)Handle).transform.position = Carriage.position;
				}
			}
		}

		private void ApplyLimbs()
		{
			//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_006f: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (Sides == null)
			{
				return;
			}
			for (int i = 0; i < Sides.Length; i++)
			{
				CrossbowSide crossbowSide = Sides[i];
				if (crossbowSide != null && !((Object)(object)crossbowSide.Limb == (Object)null) && !((Object)(object)crossbowSide.Limb.parent == (Object)null))
				{
					Vector3 val = crossbowSide.Limb.parent.InverseTransformDirection(ArrowRest.up);
					crossbowSide.Limb.localRotation = Quaternion.AngleAxis(crossbowSide.Sign * crossbowSide.RelaxedDegrees * (1f - m_cock), val) * crossbowSide.LimbRestLocal;
				}
			}
		}

		private void ApplyStrings()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			if (Sides == null)
			{
				return;
			}
			for (int i = 0; i < Sides.Length; i++)
			{
				CrossbowSide crossbowSide = Sides[i];
				if (crossbowSide == null || (Object)(object)crossbowSide.Tip == (Object)null || (Object)(object)crossbowSide.Hook == (Object)null || (Object)(object)crossbowSide.Tip.parent == (Object)null)
				{
					continue;
				}
				Vector3 val = crossbowSide.Hook.position - crossbowSide.Tip.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (!(magnitude < 1E-05f))
				{
					Vector3 val2 = crossbowSide.TipRestLocal * crossbowSide.TipRestDir;
					Vector3 val3 = crossbowSide.Tip.parent.InverseTransformDirection(val / magnitude);
					crossbowSide.Tip.localRotation = Quaternion.FromToRotation(val2, val3) * crossbowSide.TipRestLocal;
					if ((Object)(object)crossbowSide.End != (Object)null && ((Vector3)(ref crossbowSide.EndRestLocal)).sqrMagnitude > 1E-10f)
					{
						float num = Mathf.Max(1E-05f, crossbowSide.Tip.lossyScale.x);
						crossbowSide.End.localPosition = ((Vector3)(ref crossbowSide.EndRestLocal)).normalized * (magnitude / num);
					}
				}
			}
		}

		private void ApplySprings()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			//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_00a8: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if (SpringAims == null)
			{
				return;
			}
			for (int i = 0; i < SpringAims.Length; i++)
			{
				CrossbowAimLink crossbowAimLink = SpringAims[i];
				if (crossbowAimLink != null && !((Object)(object)crossbowAimLink.Bone == (Object)null) && !((Object)(object)crossbowAimLink.Target == (Object)null) && !((Object)(object)crossbowAimLink.Bone.parent == (Object)null))
				{
					Vector3 val = crossbowAimLink.Target.position - crossbowAimLink.Bone.position;
					if (!(((Vector3)(ref val)).sqrMagnitude < 1E-10f))
					{
						Vector3 val2 = crossbowAimLink.RestLocal * crossbowAimLink.RestDir;
						Vector3 val3 = crossbowAimLink.Bone.parent.InverseTransformDirection(((Vector3)(ref val)).normalized);
						crossbowAimLink.Bone.localRotation = Quaternion.FromToRotation(val2, val3) * crossbowAimLink.RestLocal;
					}
				}
			}
		}

		private void ApplyStringLine()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)StringLine == (Object)null) && Sides != null && Sides.Length >= 2)
			{
				CrossbowSide crossbowSide = Sides[0];
				CrossbowSide crossbowSide2 = Sides[1];
				if (crossbowSide != null && crossbowSide2 != null && !((Object)(object)crossbowSide.Tip == (Object)null) && !((Object)(object)crossbowSide2.Tip == (Object)null) && !((Object)(object)crossbowSide.Hook == (Object)null) && !((Object)(object)crossbowSide2.Hook == (Object)null))
				{
					StringLine.SetPosition(0, crossbowSide.Tip.position);
					StringLine.SetPosition(1, crossbowSide.Hook.position);
					StringLine.SetPosition(2, crossbowSide2.Hook.position);
					StringLine.SetPosition(3, crossbowSide2.Tip.position);
				}
			}
		}

		private void FollowLoadedArrow()
		{
			//IL_002a: 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_0046: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!(m_loaded == null))
			{
				Transform transform = m_loaded.transform;
				transform.rotation = Quaternion.LookRotation(ArrowRest.forward, ArrowRest.up);
				transform.position += ArrowRest.position - m_loaded.NockPoint.position;
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			if ((Object)(object)Handle != (Object)null && ((FVRInteractiveObject)Handle).IsHeld)
			{
				((FVRInteractiveObject)Handle).ForceBreakInteraction();
			}
			m_hasTriggerCycled = false;
			((FVRFireArm)this).EndInteraction(hand);
		}

		public override void SetQuickBeltSlot(FVRQuickBeltSlot slot)
		{
			if ((Object)(object)slot != (Object)null && m_loaded != null)
			{
				ArrowRef loaded = m_loaded;
				m_loaded = null;
				loaded.ReleaseToLoose();
			}
			((FVRFireArm)this).SetQuickBeltSlot(slot);
		}

		private void Play(AudioClip clip)
		{
			if ((Object)(object)Audio != (Object)null && (Object)(object)clip != (Object)null)
			{
				Audio.PlayOneShot(clip);
			}
		}
	}
	public class CrossbowCockingHandle : FVRInteractiveObject
	{
		[HideInInspector]
		public Crossbow Crossbow;

		public override bool IsInteractable()
		{
			return (Object)(object)Crossbow != (Object)null && ((FVRInteractiveObject)Crossbow).IsHeld && !Crossbow.IsLocked && ((FVRInteractiveObject)this).IsInteractable();
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			((FVRInteractiveObject)this).BeginInteraction(hand);
			if ((Object)(object)Crossbow != (Object)null)
			{
				Crossbow.OnHandleGrabbed(hand);
			}
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			((FVRInteractiveObject)this).UpdateInteraction(hand);
			if ((Object)(object)Crossbow != (Object)null)
			{
				Crossbow.OnHandleHeld(hand);
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			if ((Object)(object)Crossbow != (Object)null)
			{
				Crossbow.OnHandleReleased(hand);
			}
			((FVRInteractiveObject)this).EndInteraction(hand);
		}
	}
}
public class AudioStopWhenDone : MonoBehaviour
{
	public AudioSource Src;

	public float Delay;

	public float Duration = 1f;

	private void Awake()
	{
		if ((Object)(object)Src == (Object)null)
		{
			Src = ((Component)this).GetComponent<AudioSource>();
		}
	}

	private void OnEnable()
	{
		((MonoBehaviour)this).CancelInvoke();
		if ((Object)(object)Src != (Object)null && Src.loop && !Src.isPlaying)
		{
			Src.Play();
		}
		if (Duration > 0f)
		{
			((MonoBehaviour)this).Invoke("StopLoop", Mathf.Max(0f, Delay) + Duration);
		}
	}

	private void OnDisable()
	{
		((MonoBehaviour)this).CancelInvoke();
	}

	private void StopLoop()
	{
		if ((Object)(object)Src != (Object)null && Src.loop)
		{
			Src.Stop();
		}
		((Behaviour)this).enabled = false;
	}
}
public class AutoDestructWhenDone : MonoBehaviour
{
	[Tooltip("Seconds between checks.")]
	public float PollInterval = 0.5f;

	[Tooltip("Seconds after enabling before the first check, so a delayed start is not mistaken for finished.")]
	public float StartGrace = 1f;

	private ParticleSystem[] m_systems;

	private AudioSource[] m_sources;

	private float m_nextPoll;

	private void OnEnable()
	{
		m_nextPoll = Time.time + Mathf.Max(StartGrace, PollInterval);
	}

	private void Update()
	{
		if (!Application.isPlaying || Time.time < m_nextPoll)
		{
			return;
		}
		m_nextPoll = Time.time + PollInterval;
		if (m_systems == null)
		{
			m_systems = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			m_sources = ((Component)this).GetComponentsInChildren<AudioSource>(true);
		}
		for (int i = 0; i < m_systems.Length; i++)
		{
			ParticleSystem val = m_systems[i];
			if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy && val.IsAlive(false))
			{
				return;
			}
		}
		for (int j = 0; j < m_sources.Length; j++)
		{
			AudioSource val2 = m_sources[j];
			if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy && val2.isPlaying)
			{
				return;
			}
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}
}
public class BloodBondSR : MonoBehaviour
{
	private void Awake()
	{
		string name = "Ammo_69_CashMoney_D100(Clone)";
		((Object)((Component)this).gameObject).name = name;
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			((Object)((Component)componentsInChildren[i]).gameObject).name = name;
		}
	}
}
public class ComponentActivateRandomRuntime : MonoBehaviour
{
	public float Probability;

	public int Group;

	public float SelectionStart;

	[NonSerialized]
	private bool rollResolved;

	[NonSerialized]
	private float sharedRoll;

	private void Awake()
	{
		if (Probability >= 1f)
		{
			return;
		}
		bool flag;
		if (Group != 0)
		{
			if (!rollResolved)
			{
				ResolveGroupRollsForRoot();
			}
			flag = sharedRoll >= SelectionStart && sharedRoll <= SelectionStart + Probability;
		}
		else
		{
			flag = Random.value <= Probability;
		}
		if (!flag)
		{
			((Component)this).gameObject.SetActive(false);
		}
	}

	private void ResolveGroupRollsForRoot()
	{
		ComponentActivateRandomRuntime[] componentsInChildren = ((Component)((Component)this).transform.root).GetComponentsInChildren<ComponentActivateRandomRuntime>(true);
		Dictionary<int, float> dictionary = new Dictionary<int, float>();
		foreach (ComponentActivateRandomRuntime componentActivateRandomRuntime in componentsInChildren)
		{
			if (componentActivateRandomRuntime.Group != 0 && !componentActivateRandomRuntime.rollResolved)
			{
				if (!dictionary.TryGetValue(componentActivateRandomRuntime.Group, out var value))
				{
					value = Random.value;
					dictionary[componentActivateRandomRuntime.Group] = value;
				}
				componentActivateRandomRuntime.sharedRoll = value;
				componentActivateRandomRuntime.rollResolved = true;
			}
		}
	}
}
public class CooldownSound : MonoBehaviour
{
	public ClosedBoltWeapon weapon;

	public AudioClip[] audioClips;

	public float volume = 1f;

	public int minShots = 5;

	public int maxShots = 10;

	public float minDelay = 0.5f;

	public float maxDelay = 2f;

	public float resetTime = 1.5f;

	private AudioSource audioSource;

	private int shotCounter = 0;

	private float lastShotTime;

	private bool lastRoundSpent;

	private int nextShotThreshold;

	private bool isPlayingSound = false;

	private void Start()
	{
		if ((Object)(object)weapon == (Object)null)
		{
			weapon = ((Component)this).GetComponent<ClosedBoltWeapon>();
		}
		if ((Object)(object)weapon == (Object)null)
		{
			Debug.LogError((object)"CooldownSound: Weapon reference is missing. Attach this script to a ClosedBoltWeapon.");
			return;
		}
		audioSource = ((Component)weapon).gameObject.GetComponent<AudioSource>();
		if ((Object)(object)audioSource == (Object)null)
		{
			audioSource = ((Component)weapon).gameObject.AddComponent<AudioSource>();
		}
		audioSource.spatialBlend = 1f;
		audioSource.playOnAwake = false;
		audioSource.rolloffMode = (AudioRolloffMode)0;
		lastRoundSpent = weapon.Chamber.IsSpent;
		SetNewShotThreshold();
	}

	private void Update()
	{
		DetectFiring();
	}

	private void DetectFiring()
	{
		if (weapon.Chamber.IsFull && weapon.Chamber.IsSpent && !lastRoundSpent)
		{
			OnWeaponFired();
		}
		lastRoundSpent = weapon.Chamber.IsSpent;
	}

	private void OnWeaponFired()
	{
		float num = Time.time - lastShotTime;
		if (num > resetTime)
		{
			shotCounter = 0;
			SetNewShotThreshold();
		}
		shotCounter++;
		lastShotTime = Time.time;
		if (shotCounter >= nextShotThreshold)
		{
			((MonoBehaviour)this).StartCoroutine(PlaySoundWithDelay());
			shotCounter = 0;
			SetNewShotThreshold();
		}
	}

	private IEnumerator PlaySoundWithDelay()
	{
		if (!isPlayingSound)
		{
			isPlayingSound = true;
			float delay = Random.Range(minDelay, maxDelay);
			yield return (object)new WaitForSeconds(delay);
			if (audioClips.Length > 0)
			{
				int index = Random.Range(0, audioClips.Length);
				audioSource.clip = audioClips[index];
				audioSource.PlayOneShot(audioSource.clip, volume);
				yield return (object)new WaitForSeconds(audioSource.clip.length);
			}
			isPlayingSound = false;
		}
	}

	private void SetNewShotThreshold()
	{
		nextShotThreshold = Random.Range(minShots, maxShots + 1);
	}
}
[ExecuteInEditMode]
public class CryErosionDriver : MonoBehaviour
{
	private static readonly int ErosionValueId = Shader.PropertyToID("_ErosionValue");

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

	public Renderer[] Renderers;

	public bool HideWhenGone = true;

	private MaterialPropertyBlock _block;

	private float _burnRate;

	private float _lastApplied = -1f;

	public void BurnOver(float seconds)
	{
		_burnRate = ((!(seconds > 0.0001f)) ? 0f : ((1f - Burn) / seconds));
		if (_burnRate <= 0f)
		{
			Burn = 1f;
		}
	}

	public void Restore()
	{
		_burnRate = 0f;
		Burn = 0f;
		Apply(force: true);
	}

	private void LateUpdate()
	{
		if (_burnRate > 0f && Application.isPlaying)
		{
			Burn = Mathf.Min(1f, Burn + _burnRate * Time.deltaTime);
			if (Burn >= 1f)
			{
				_burnRate = 0f;
			}
		}
		Apply(force: false);
	}

	private void OnValidate()
	{
		Apply(force: true);
	}

	private void Apply(bool force)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		float num = Mathf.Clamp01(Burn);
		if (!force && Mathf.Approximately(num, _lastApplied))
		{
			return;
		}
		_lastApplied = num;
		if (Renderers == null || Renderers.Length == 0)
		{
			Renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
		}
		if (_block == null)
		{
			_block = new MaterialPropertyBlock();
		}
		bool flag = HideWhenGone && num >= 1f;
		for (int i = 0; i < Renderers.Length; i++)
		{
			Renderer val = Renderers[i];
			if (!((Object)(object)val == (Object)null))
			{
				val.GetPropertyBlock(_block);
				_block.SetFloat(ErosionValueId, 1f - num);
				val.SetPropertyBlock(_block);
				if (HideWhenGone)
				{
					val.enabled = !flag;
				}
			}
		}
	}
}
[ExecuteInEditMode]
public class CryRibbon : MonoBehaviour
{
	private class ParentSlot
	{
		public uint Seed;

		public Vector3 Pos;

		public Vector3 Vel;

		public float Age01 = 1f;

		public bool Dead;
	}

	private struct SeedInfo
	{
		public int Slot;

		public float Fraction;
	}

	private sealed class AgeComparer : IComparer<int>
	{
		public Particle[] Buf;

		public int Compare(int a, int b)
		{
			float num = ((Particle)(ref Buf[a])).startLifetime - ((Particle)(ref Buf[a])).remainingLifetime;
			float num2 = ((Particle)(ref Buf[b])).startLifetime - ((Particle)(ref Buf[b])).remainingLifetime;
			if (num > num2)
			{
				return -1;
			}
			if (num < num2)
			{
				return 1;
			}
			return 0;
		}
	}

	public ParticleSystem OwnPs;

	public ParticleSystem ParentSystem;

	public Transform EffectRoot;

	public Material RibbonMaterial;

	public float SizeConstant = 1f;

	public AnimationCurve SizeOverLife = new AnimationCurve();

	public AnimationCurve SizeBySpawnFraction = new AnimationCurve();

	public float OpacityConstant = 1f;

	public AnimationCurve OpacityOverLife = new AnimationCurve();

	public AnimationCurve OpacityBySpawnFraction = new AnimationCurve();

	public Gradient ColorOverLife = new Gradient();

	public bool StreamFromAge;

	public float TextureFrequency = 1f;

	public bool FlipU;

	public bool FlipV;

	public bool ConnectToParent;

	public bool SampleParentAlpha;

	public AnimationCurve ParentOpacityOverLife = null;

	public AnimationCurve FacingOpacity = null;

	public int PerParentTotal = 1;

	public float SpawnDelay;

	public float SpawnDuration;

	public bool RateMode;

	public float SpawnRate;

	public float CountMin = 1f;

	public float CountMax = 1f;

	public float RestartPeriod;

	public float LifetimeMin = 1f;

	public float LifetimeMax = 1f;

	public int VelocityMode;

	public Vector3 AxisLocal = Vector3.up;

	public float ConeAngle;

	public float SpeedMin;

	public float SpeedMax;

	public AnimationCurve SpeedBySpawnFraction = new AnimationCurve();

	public float Drag;

	public float GravityScale;

	public bool LifetimePerInstance;

	public AnimationCurve DragParentAge = null;

	public AnimationCurve DragSpawnFraction = null;

	private readonly List<ParentSlot> m_parents = new List<ParentSlot>();

	private readonly Dictionary<uint, int> m_parentIndex = new Dictionary<uint, int>();

	private readonly Dictionary<uint, SeedInfo> m_vertSlot = new Dictionary<uint, SeedInfo>();

	private readonly Dictionary<uint, int> m_seedFirstFrame = new Dictionary<uint, int>();

	private readonly List<uint> m_prune = new List<uint>();

	private readonly Dictionary<int, int> m_slotBirthCount = new Dictionary<int, int>();

	private Particle[] m_ownBuf = (Particle[])(object)new Particle[0];

	private Particle[] m_parentBuf = (Particle[])(object)new Particle[0];

	private readonly HashSet<uint> m_liveSeeds = new HashSet<uint>();

	private readonly List<bool> m_seen = new List<bool>();

	private readonly List<int> m_freeSlots = new List<int>();

	private readonly Dictionary<int, int> m_slotRefs = new Dictionary<int, int>();

	private readonly Dictionary<int, int> m_groupIndex = new Dictionary<int, int>();

	private readonly List<List<int>> m_groupLists = new List<List<int>>();

	private readonly List<int> m_groupSlots = new List<int>();

	private readonly AgeComparer m_ageComparer = new AgeComparer();

	private const int k_slotRecycleThreshold = 32;

	private Mesh m_mesh;

	private readonly List<Vector3> m_verts = new List<Vector3>();

	private readonly List<Vector2> m_uvs = new List<Vector2>();

	private readonly List<Color32> m_cols = new List<Color32>();

	private readonly List<Vector3> m_norms = new List<Vector3>();

	private readonly List<Vector4> m_tans = new List<Vector4>();

	private readonly List<int> m_tris = new List<int>();

	private readonly Vector3[] m_posBuf = (Vector3[])(object)new Vector3[256];

	private readonly float[] m_fracBuf = new float[256];

	private readonly float[] m_ageBuf = new float[256];

	public static readonly List<CryRibbon> EditInstances = new List<CryRibbon>();

	private int m_lastFrame = -1;

	private static Camera s_viewerCamera;

	public bool IsBusy
	{
		get
		{
			if (!((Behaviour)this).isActiveAndEnabled)
			{
				return false;
			}
			if ((Object)(object)OwnPs == (Object)null)
			{
				OwnPs = ((Component)this).GetComponent<ParticleSystem>();
			}
			if ((Object)(object)OwnPs != (Object)null && OwnPs.particleCount > 0)
			{
				return true;
			}
			if ((Object)(object)ParentSystem != (Object)null && ParentSystem.IsAlive(true))
			{
				return true;
			}
			return false;
		}
	}

	public int InstanceCount => m_parents.Count;

	public int TrackCount => m_parents.Count;

	private void OnEnable()
	{
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		if (!Application.isPlaying && !EditInstances.Contains(this))
		{
			EditInstances.Add(this);
		}
		m_parents.Clear();
		m_parentIndex.Clear();
		m_freeSlots.Clear();
		m_vertSlot.Clear();
		m_seedFirstFrame.Clear();
		m_slotBirthCount.Clear();
		if ((Object)(object)OwnPs == (Object)null)
		{
			OwnPs = ((Component)this).GetComponent<ParticleSystem>();
		}
		if ((Object)(object)m_mesh == (Object)null)
		{
			m_mesh = new Mesh();
			((Object)m_mesh).hideFlags = (HideFlags)61;
			((Object)m_mesh).name = "CryRibbon";
			m_mesh.MarkDynamic();
		}
	}

	private void OnDisable()
	{
		EditInstances.Remove(this);
	}

	public void EditorTick()
	{
		if (!Application.isPlaying && !((Object)(object)this == (Object)null))
		{
			LateUpdate();
		}
	}

	private void OnDestroy()
	{
		if (!((Object)(object)m_mesh == (Object)null))
		{
			if (Application.isPlaying)
			{
				Object.Destroy((Object)(object)m_mesh);
			}
			else
			{
				Object.DestroyImmediate((Object)(object)m_mesh);
			}
		}
	}

	private void LateUpdate()
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)RibbonMaterial == (Object)null)
		{
			return;
		}
		int frame = CryEditClock.Frame;
		if (m_lastFrame == frame)
		{
			return;
		}
		m_lastFrame = frame;
		if ((Object)