Decompiled source of Hunt Showdown Ammo v1.0.7

Hunt_Showdown_Ammo.dll

Decompiled 5 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 FistVR;
using HarmonyLib;
using OtherLoader;
using UnityEngine;
using UnityEngine.SceneManagement;

[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.Hunt_Showdown_Ammo
{
	[BepInPlugin("BitWizrd.Hunt_Showdown_Ammo", "Hunt_Showdown_Ammo", "1.0.7")]
	[BepInProcess("h3vr.exe")]
	[Description("Built with MeatKit")]
	[BepInDependency("h3vr.otherloader", "1.3.0")]
	public class Hunt_Showdown_AmmoPlugin : 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.Hunt_Showdown_Ammo");
			OtherLoader.RegisterDirectLoad(BasePath, "BitWizrd.Hunt_Showdown_Ammo", "", "huntshowdownammo", "", "");
		}
	}
}
namespace BitWizrd.SpecialAmmo
{
	public enum ArrowState
	{
		Loose,
		Nocked,
		Flying,
		Stuck
	}
	public class Arrow : FVRFireArmRound
	{
		public static List<Arrow> Instances = new List<Arrow>();

		[Tooltip("Tail end of the arrow: sits on the string.")]
		public Transform NockPoint;

		[Tooltip("Head end of the arrow: the point that hits and sticks.")]
		public Transform TipPoint;

		public Transform DrawStopPoint;

		[Tooltip("Used only when Draw Stop Point is empty: how far behind the tip the head ends (m).")]
		public float FallbackHeadLength = 0.06f;

		public float LaunchSpeedMultiplier = 1f;

		public float ExtraGravity = 0f;

		[Tooltip("A hunting arrow is about 25-35 g. 0 keeps the Rigidbody's own mass.")]
		public float MassKg = 0.08f;

		[Tooltip("How fast the nose follows the velocity (deg/s). Slow enough to lag and wobble on the arc.")]
		public float AlignDegreesPerSecond = 120f;

		[Tooltip("Quadratic: speed lost per second = AirDrag * v^2 (about 4.8 m/s^2 at 20 m/s).")]
		public float AirDrag = 0.001f;

		[Tooltip("Radius of the sweep that finds what the arrow hits (m).")]
		public float SweepRadius = 0.012f;

		public bool PassThroughBreakables = true;

		[Tooltip("Share of speed lost to each pane of broken glass.")]
		public float BreakablePassThroughLoss = 0.15f;

		[Tooltip("Slowest impact speed (m/s) at which the arrow sticks instead of bouncing off.")]
		public float StickMinSpeed = 8f;

		[Tooltip("Shallowest (just sticking) .. deepest (full speed) depth, in metres.")]
		public Vector2 StickDepthRange = new Vector2(0.02f, 0.2f);

		public float PenetrationFullSpeed = 60f;

		[Tooltip("Random scale of 1 +/- this on each hit.")]
		public float PenetrationVariation = 0.4f;

		[Tooltip("The tip never sinks past this share of the arrow's length.")]
		public float MaxPenetrationFraction = 0.6f;

		public float FixedPenetration = 0f;

		[Tooltip("Newtons; higher = shallower.")]
		public float SosigResistanceForce = 2000f;

		[Tooltip("Fraction of the arrow's length that always stays outside at the entry.")]
		public float MinShaftOutside = 0.2f;

		[Tooltip("Fraction of the arrow's length that shows beyond the exit on a through shot.")]
		public float MinExitProtrusion = 0.08f;

		[Tooltip("How far past the entry to look for the far side, in arrow lengths.")]
		public float SosigScanLengths = 1.6f;

		public bool BleedOnPenetration = true;

		[Tooltip("At average depth; 0.5x when shallow, 1.5x when as deep as it goes.")]
		public float PenetrationBleed = 20f;

		[Tooltip("Bleed at the exit wound on a through shot (same units as Penetration Bleed).")]
		public float ExitBleed = 20f;

		public float PullOutBleed = 25f;

		public bool PullOutDamagesSosig = true;

		[Tooltip("Blunt, cutting, piercing.")]
		public Vector3 PullOutDamageBCP = new Vector3(20f, 150f, 60f);

		[Tooltip("Never deeper than this share of the arrow's length.")]
		public float PullOutDamageSize = 0.02f;

		[Tooltip("Off for blunt / practice / stun arrows: no piercing, no sticking.")]
		public bool HasPiercingHead = true;

		public float BluntPerJoule = 0.17f;

		public float PiercingPerJoule = 1f;

		public float HeadshotMultiplier = 1.5f;

		public Vector2[] DamageByDistance = (Vector2[])(object)new Vector2[5]
		{
			new Vector2(5f, 1f),
			new Vector2(15f, 0.75f),
			new Vector2(30f, 0.48f),
			new Vector2(50f, 0.4f),
			new Vector2(100f, 0.2f)
		};

		public bool SneakAttackCritical = true;

		public float SneakAttackMultiplier = 3f;

		public float SneakAttackKnockback = 60f;

		public bool SneakAttackRagdoll = true;

		public float SneakAttackBodyPush = 4f;

		[Tooltip("Upward share of the push, as a fraction of it.")]
		public float SneakAttackBodyLift = 0.15f;

		public float SneakAttackRagdollSeconds = 2.5f;

		public bool NeverExplodeHeads = true;

		[Tooltip("Fraction of full integrity an arrow can never take a head below.")]
		public float HeadIntegrityFloor = 0.15f;

		public float HeadStunSeconds = 2f;

		public float BodyStunSeconds = 0f;

		public string[] InstantKillSpeechSets;

		public bool PoisonOnHit = false;

		public PowerUpIntensity PoisonIntensity = (PowerUpIntensity)1;

		public PowerUpDuration PoisonDuration = (PowerUpDuration)1;

		[Tooltip("Makes the sosig vomit for the duration (the poison bomb's smoke does).")]
		public bool PoisonVomit = true;

		public bool HasExplosivePayload = false;

		public float FuseSeconds = 1.5f;

		[Tooltip("The visual (and its sound), spawned where the explosion is when the fuse ends.")]
		public GameObject ExplosionVFX;

		public GameObject ExplosionPayload;

		public Transform ExplosionPoint;

		public Transform FusePoint;

		public GameObject FuseEffect;

		public AudioClip[] FuseClips;

		public float FuseVolume = 1f;

		public bool FuseLoop = true;

		public float FuseMaxDistance = 25f;

		public bool CanPin = false;

		[Tooltip("A wall / second limb must be within the arrow's length plus this (m).")]
		public float PinDistanceLimit = 2f;

		[Tooltip("First hit (the nail: 3000 piercing + kinetic).")]
		public float PinHitDamage = 3000f;

		[Tooltip("Second hit sent through the limb (the nail: 500).")]
		public float PinImpaleDamage = 500f;

		public float PinStunning = 2f;

		[Tooltip("The nail's Dimensions.x, sent as damageSize.")]
		public float PinThickness = 0.025f;

		public Vector2 LinkPenetrationRange = new Vector2(0.15f, 0.3f);

		[Tooltip("Shove along the shot when nothing is behind the limb.")]
		public float PinShoveImpulse = 30f;

		[Tooltip("The nail's LM_Env (Environment).")]
		public LayerMask PinEnvironmentMask = LayerMask.op_Implicit(524288);

		[Tooltip("The nail's LM_Agent.")]
		public LayerMask PinAgentMask = LayerMask.op_Implicit(1572864);

		private Collider[] m_cols;

		private Collider[] m_ignoredBowCols;

		private Vector3 m_lastVel;

		private float m_launchTime;

		private Vector3 m_launchPos;

		private float m_chargeDamageMult = 1f;

		private List<GameObject> m_layerSwapped = new List<GameObject>();

		private List<int> m_layerOriginal = new List<int>();

		private SosigLink m_stuckLink;

		private float m_stuckDepth;

		private FixedJoint m_pinJoint;

		private Transform m_pinWall;

		private ArrowStickAnchor m_anchor;

		private Transform m_followTarget;

		private Vector3 m_followPos;

		private Quaternion m_followRot;

		private Vector3 m_origScale = Vector3.one;

		private bool m_fuseArmed;

		private float m_fireAt;

		private AudioSource m_fuseSource;

		private GameObject m_fuseInstance;

		private static FieldInfo s_spentField;

		private static bool s_spentLooked;

		private static readonly int SweepMask = -27297537;

		private const int NailMask = 1583105;

		private List<int> m_brokenPanes = new List<int>();

		private Transform m_passedRoot;

		private float m_passedUntil;

		public ArrowState State { get; private set; }

		public Component Holder { get; private set; }

		public bool IsLoose => State == ArrowState.Loose;

		public bool FuseArmed => m_fuseArmed;

		public float Length => ArrowLength();

		public float DrawLength()
		{
			//IL_002e: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)DrawStopPoint != (Object)null && (Object)(object)NockPoint != (Object)null)
			{
				return Mathf.Max(0.01f, Vector3.Dot(DrawStopPoint.position - NockPoint.position, ((Component)this).transform.forward));
			}
			return Mathf.Max(0.01f, Length - FallbackHeadLength);
		}

		public override void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArmRound)this).Awake();
			m_origScale = ((Component)this).transform.localScale;
			if (HasExplosivePayload && (Object)(object)FuseEffect != (Object)null && !IsPrefabAsset(FuseEffect))
			{
				FuseEffect.SetActive(false);
			}
			if (MassKg > 0f && (Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.mass = MassKg;
			}
			m_cols = ((Component)this).GetComponentsInChildren<Collider>();
			Instances.Add(this);
		}

		public override void OnDestroy()
		{
			Instances.Remove(this);
			UnhookAnchor();
			RemovePin();
			StopFuseSound();
			StopFuseEffect();
			((FVRPhysicalObject)this).OnDestroy();
		}

		private void SetSpentFlag(bool spent)
		{
			if (!s_spentLooked)
			{
				s_spentLooked = true;
				s_spentField = typeof(FVRFireArmRound).GetField("m_isSpent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if ((object)s_spentField != null)
			{
				s_spentField.SetValue(this, spent);
			}
		}

		public void OnNocked(Component holder, Collider[] bowCols)
		{
			//IL_002e: 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)
			SetSpentFlag(spent: true);
			State = ArrowState.Nocked;
			Holder = holder;
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.velocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.angularVelocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = true;
			}
			SetBowCollision(bowCols, ignore: true);
		}

		public void Launch(Vector3 velocity, Collider[] bowCols, int shooterIFF, float chargeDamageMult = 1f)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			velocity *= Mathf.Max(0.05f, LaunchSpeedMultiplier);
			m_launchPos = ((Component)this).transform.position;
			m_chargeDamageMult = chargeDamageMult;
			m_brokenPanes.Clear();
			SetBowCollision(bowCols, ignore: true);
			m_launchTime = Time.time;
			SetSpentFlag(spent: false);
			State = ArrowState.Flying;
			Holder = null;
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = false;
				SwapSolidCollidersToNoCol();
				((FVRPhysicalObject)this).RootRigidbody.collisionDetectionMode = (CollisionDetectionMode)2;
				((FVRPhysicalObject)this).RootRigidbody.velocity = velocity;
				((FVRPhysicalObject)this).RootRigidbody.angularVelocity = Vector3.zero;
			}
			m_lastVel = velocity;
		}

		public void ReleaseToLoose()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			UnhookAnchor();
			RemovePin();
			ReleaseStuckJoint();
			m_stuckLink = null;
			m_pinWall = null;
			if ((Object)(object)Holder != (Object)null)
			{
				Holder.SendMessage("ArrowUnnocked", (object)this, (SendMessageOptions)1);
			}
			Holder = null;
			SetSpentFlag(spent: false);
			State = ArrowState.Loose;
			m_followTarget = null;
			((Component)this).transform.SetParent((Transform)null, true);
			((Component)this).transform.localScale = m_origScale;
			SetBowCollision(null, ignore: false);
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = false;
			}
		}

		private void SetBowCollision(Collider[] bowCols, bool ignore)
		{
			Collider[] array = ((!ignore) ? m_ignoredBowCols : bowCols);
			if (array != null && m_cols != null)
			{
				for (int i = 0; i < array.Length; i++)
				{
					if (!((Object)(object)array[i] == (Object)null))
					{
						for (int j = 0; j < m_cols.Length; j++)
						{
							Physics.IgnoreCollision(m_cols[j], array[i], ignore);
						}
					}
				}
			}
			m_ignoredBowCols = ((!ignore) ? null : bowCols);
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			if (State == ArrowState.Stuck && (Object)(object)m_stuckLink != (Object)null)
			{
				PullOutDamage(hand);
			}
			if (State == ArrowState.Nocked || State == ArrowState.Stuck || State == ArrowState.Flying)
			{
				ReleaseToLoose();
			}
			((FVRFireArmRound)this).BeginInteraction(hand);
		}

		public override void FVRFixedUpdate()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArmRound)this).FVRFixedUpdate();
			if (State != ArrowState.Flying || (Object)(object)((FVRPhysicalObject)this).RootRigidbody == (Object)null)
			{
				return;
			}
			if (m_ignoredBowCols != null && Time.time - m_launchTime > 0.25f)
			{
				SetBowCollision(null, ignore: false);
			}
			Vector3 val = ((FVRPhysicalObject)this).RootRigidbody.velocity;
			if (((Vector3)(ref val)).sqrMagnitude < 4f)
			{
				ReleaseToLoose();
			}
			else if (!SweepForHit(val))
			{
				float magnitude = ((Vector3)(ref val)).magnitude;
				val -= val * (AirDrag * magnitude * Time.fixedDeltaTime);
				if (ExtraGravity > 0f)
				{
					val += Vector3.down * (ExtraGravity * Time.fixedDeltaTime);
				}
				((FVRPhysicalObject)this).RootRigidbody.velocity = val;
				m_lastVel = val;
				Quaternion val2 = Quaternion.LookRotation(val);
				((FVRPhysicalObject)this).RootRigidbody.MoveRotation(Quaternion.RotateTowards(((FVRPhysicalObject)this).RootRigidbody.rotation, val2, AlignDegreesPerSecond * Time.fixedDeltaTime));
			}
		}

		public override void OnCollisionEnter(Collision col)
		{
			((FVRPhysicalObject)this).OnCollisionEnter(col);
		}

		private bool SweepForHit(Vector3 vel)
		{
			//IL_001b: 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)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0088: 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_0090: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Vector3)(ref vel)).magnitude;
			if (num < 0.01f)
			{
				return false;
			}
			Vector3 val = vel / num;
			Transform val2 = ((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform : TipPoint);
			float num2 = 0.05f;
			Vector3 val3 = val2.position - val * num2;
			float num3 = num * Time.fixedDeltaTime + num2;
			RaycastHit[] array = Physics.SphereCastAll(val3, SweepRadius, val, num3, SweepMask, (QueryTriggerInteraction)1);
			RaycastHit val4 = default(RaycastHit);
			RaycastHit val5 = val4;
			bool flag = false;
			List<RaycastHit> list = null;
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val6 = array[i];
				if ((Object)(object)((RaycastHit)(ref val6)).collider == (Object)null || (((RaycastHit)(ref val6)).distance <= 0f && ((RaycastHit)(ref val6)).point == Vector3.zero) || (Object)(object)((RaycastHit)(ref val6)).collider.attachedRigidbody == (Object)(object)((FVRPhysicalObject)this).RootRigidbody || ((Object)(object)m_passedRoot != (Object)null && Time.time < m_passedUntil && ((Component)((RaycastHit)(ref val6)).collider).transform.IsChildOf(m_passedRoot)) || IsBowCollider(((RaycastHit)(ref val6)).collider))
				{
					continue;
				}
				if (((1583105 >> ((Component)((RaycastHit)(ref val6)).collider).gameObject.layer) & 1) == 0)
				{
					if ((Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<UberShatterable>() != (Object)null || (Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<BreakableGlassDamager>() != (Object)null)
					{
						if (list == null)
						{
							list = new List<RaycastHit>();
						}
						list.Add(val6);
					}
				}
				else if (!flag || ((RaycastHit)(ref val6)).distance < ((RaycastHit)(ref val5)).distance)
				{
					val5 = val6;
					flag = true;
				}
			}
			if (list != null && PassThroughBreakables && (Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				list.Sort((RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance));
				for (int num4 = 0; num4 < list.Count; num4++)
				{
					if (flag)
					{
						val4 = list[num4];
						if (((RaycastHit)(ref val4)).distance >= ((RaycastHit)(ref val5)).distance)
						{
							break;
						}
					}
					RaycastHit val7 = list[num4];
					UberShatterable componentInParent = ((Component)((RaycastHit)(ref val7)).collider).GetComponentInParent<UberShatterable>();
					RaycastHit val8 = list[num4];
					BreakableGlassDamager componentInParent2 = ((Component)((RaycastHit)(ref val8)).collider).GetComponentInParent<BreakableGlassDamager>();
					int item = ((!((Object)(object)componentInParent != (Object)null)) ? ((Object)componentInParent2).GetInstanceID() : ((Object)componentInParent).GetInstanceID());
					if (!m_brokenPanes.Contains(item))
					{
						m_brokenPanes.Add(item);
						RaycastHit val9 = list[num4];
						Collider collider = ((RaycastHit)(ref val9)).collider;
						RaycastHit val10 = list[num4];
						Vector3 point = ((RaycastHit)(ref val10)).point;
						RaycastHit val11 = list[num4];
						ApplyDamage(collider, point, ((RaycastHit)(ref val11)).normal, val, num);
						num *= 1f - Mathf.Clamp01(BreakablePassThroughLoss);
						((FVRPhysicalObject)this).RootRigidbody.velocity = val * num;
						m_lastVel = val * num;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			Transform transform = ((Component)this).transform;
			transform.position += ((RaycastHit)(ref val5)).point - val2.position;
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.position = ((Component)this).transform.position;
			}
			HandleFlightHit(((RaycastHit)(ref val5)).collider, ((RaycastHit)(ref val5)).point, ((RaycastHit)(ref val5)).normal, val, num);
			return true;
		}

		private bool IsBowCollider(Collider c)
		{
			if (m_ignoredBowCols == null)
			{
				return false;
			}
			for (int i = 0; i < m_ignoredBowCols.Length; i++)
			{
				if ((Object)(object)m_ignoredBowCols[i] == (Object)(object)c)
				{
					return true;
				}
			}
			return false;
		}

		private static Transform FindBreakableGlass(Collider c, out BreakableGlassDamager damager)
		{
			damager = ((Component)c).GetComponentInParent<BreakableGlassDamager>();
			if ((Object)(object)damager == (Object)null)
			{
				return null;
			}
			return (!((Object)(object)damager.Glass != (Object)null)) ? ((Component)damager).transform : ((Component)damager.Glass).transform;
		}

		private void HandleFlightHit(Collider hitCollider, Vector3 point, Vector3 normal, Vector3 dir, float speed)
		{
			//IL_0070: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_014b: 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_0157: 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)
			if (HasPiercingHead && CanPin && speed >= StickMinSpeed && (Object)(object)hitCollider.attachedRigidbody != (Object)null)
			{
				SosigLink component = ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>();
				if ((Object)(object)component != (Object)null)
				{
					ArmPayload();
					PinSosigLink(hitCollider, component, point, normal, dir, speed);
					return;
				}
			}
			ApplyDamage(hitCollider, point, normal, dir, speed);
			if (PassThroughBreakables && (Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				UberShatterable componentInParent = ((Component)hitCollider).GetComponentInParent<UberShatterable>();
				bool flag = (Object)(object)componentInParent != (Object)null && componentInParent.m_hasShattered;
				BreakableGlassDamager damager;
				Transform val = FindBreakableGlass(hitCollider, out damager);
				if ((Object)(object)val != (Object)null)
				{
					flag = true;
				}
				if (flag)
				{
					float num = speed * (1f - Mathf.Clamp01(BreakablePassThroughLoss));
					((FVRPhysicalObject)this).RootRigidbody.velocity = dir * num;
					m_lastVel = dir * num;
					m_passedRoot = ((!((Object)(object)val != (Object)null)) ? ((Component)componentInParent).transform : val);
					m_passedUntil = Time.time + 0.5f;
					Transform transform = ((Component)this).transform;
					transform.position += dir * 0.02f;
					((FVRPhysicalObject)this).RootRigidbody.position = ((Component)this).transform.position;
					return;
				}
			}
			ArmPayload();
			if (HasPiercingHead && speed >= StickMinSpeed)
			{
				Stick(hitCollider, point, normal, dir, speed);
				return;
			}
			ReleaseToLoose();
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.velocity = Vector3.Reflect(dir * speed, normal) * 0.25f;
			}
		}

		private void ArmPayload()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!HasExplosivePayload || m_fuseArmed)
			{
				return;
			}
			m_fuseArmed = true;
			m_fireAt = Time.time + Mathf.Max(0f, FuseSeconds);
			if ((Object)(object)FuseEffect != (Object)null)
			{
				if (IsPrefabAsset(FuseEffect))
				{
					m_fuseInstance = Object.Instantiate<GameObject>(FuseEffect, FusePosition(), FuseRotation());
					m_fuseInstance.SetActive(true);
				}
				else
				{
					FuseEffect.SetActive(true);
				}
			}
			SnapFuse();
			StartFuseSound();
		}

		private void UpdateFuse()
		{
			if (m_fuseArmed)
			{
				SnapFuse();
				if (Time.time >= m_fireAt)
				{
					Detonate();
				}
			}
		}

		private static bool IsPrefabAsset(GameObject go)
		{
			//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)
			Scene scene = go.scene;
			return !((Scene)(ref scene)).IsValid();
		}

		private Vector3 FusePosition()
		{
			//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_004a: 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_0055: 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)
			if ((Object)(object)FusePoint != (Object)null)
			{
				return FusePoint.position;
			}
			return (!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform.position : TipPoint.position;
		}

		private Quaternion FuseRotation()
		{
			//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_004a: 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_0055: 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)
			if ((Object)(object)FusePoint != (Object)null)
			{
				return FusePoint.rotation;
			}
			return (!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform.rotation : TipPoint.rotation;
		}

		private void SnapFuse()
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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)
			Vector3 position = FusePosition();
			if ((Object)(object)m_fuseInstance != (Object)null)
			{
				m_fuseInstance.transform.position = position;
				m_fuseInstance.transform.rotation = FuseRotation();
			}
			else if ((Object)(object)FuseEffect != (Object)null && !IsPrefabAsset(FuseEffect) && !FuseEffect.transform.IsChildOf(((Component)this).transform) && !((Component)this).transform.IsChildOf(FuseEffect.transform))
			{
				FuseEffect.transform.position = position;
			}
			if ((Object)(object)m_fuseSource != (Object)null)
			{
				((Component)m_fuseSource).transform.position = position;
			}
		}

		private void StartFuseSound()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (FuseClips != null && FuseClips.Length != 0)
			{
				AudioClip val = FuseClips[Random.Range(0, FuseClips.Length)];
				if (!((Object)(object)val == (Object)null))
				{
					GameObject val2 = new GameObject("FuseSound");
					val2.transform.position = FusePosition();
					m_fuseSource = val2.AddComponent<AudioSource>();
					m_fuseSource.clip = val;
					m_fuseSource.loop = FuseLoop;
					m_fuseSource.volume = FuseVolume;
					m_fuseSource.spatialBlend = 1f;
					m_fuseSource.rolloffMode = (AudioRolloffMode)1;
					m_fuseSource.minDistance = 1f;
					m_fuseSource.maxDistance = Mathf.Max(2f, FuseMaxDistance);
					m_fuseSource.Play();
				}
			}
		}

		private void StopFuseEffect()
		{
			if ((Object)(object)m_fuseInstance != (Object)null)
			{
				Object.Destroy((Object)(object)m_fuseInstance);
			}
			m_fuseInstance = null;
		}

		private void StopFuseSound()
		{
			if ((Object)(object)m_fuseSource != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)m_fuseSource).gameObject);
			}
			m_fuseSource = null;
		}

		private static void SpawnExplosion(GameObject prefab, Vector3 at, int iff)
		{
			//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)
			GameObject val = Object.Instantiate<GameObject>(prefab, at, Quaternion.identity);
			Explosion component = val.GetComponent<Explosion>();
			if ((Object)(object)component != (Object)null)
			{
				component.IFF = iff;
			}
			ExplosionSound component2 = val.GetComponent<ExplosionSound>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.IFF = iff;
			}
		}

		private void Detonate()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			m_fuseArmed = false;
			StopFuseSound();
			StopFuseEffect();
			if (((FVRInteractiveObject)this).IsHeld)
			{
				((FVRInteractiveObject)this).ForceBreakInteraction();
			}
			Vector3 at = (((Object)(object)ExplosionPoint != (Object)null) ? ExplosionPoint.position : ((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform.position : TipPoint.position));
			int iff = (((Object)(object)GM.CurrentPlayerBody != (Object)null) ? GM.CurrentPlayerBody.GetPlayerIFF() : 0);
			if ((Object)(object)ExplosionVFX != (Object)null)
			{
				SpawnExplosion(ExplosionVFX, at, iff);
			}
			if ((Object)(object)ExplosionPayload != (Object)null && (Object)(object)ExplosionPayload != (Object)(object)ExplosionVFX)
			{
				SpawnExplosion(ExplosionPayload, at, iff);
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private float DistanceMultiplier(float metres)
		{
			Vector2[] damageByDistance = DamageByDistance;
			if (damageByDistance == null || damageByDistance.Length == 0)
			{
				return 1f;
			}
			if (metres <= damageByDistance[0].x)
			{
				return damageByDistance[0].y;
			}
			for (int i = 1; i < damageByDistance.Length; i++)
			{
				if (metres <= damageByDistance[i].x)
				{
					float num = Mathf.InverseLerp(damageByDistance[i - 1].x, damageByDistance[i].x, metres);
					return Mathf.Lerp(damageByDistance[i - 1].y, damageByDistance[i].y, num);
				}
			}
			return damageByDistance[^1].y;
		}

		private void ApplyDamage(Collider hitCollider, Vector3 cpPoint, Vector3 cpNormal, Vector3 dir, float speed)
		{
			//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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Invalid comparison between Unknown and I4
			IFVRDamageable val = ((Component)hitCollider).GetComponent<IFVRDamageable>();
			if (val == null && (Object)(object)hitCollider.attachedRigidbody != (Object)null)
			{
				val = ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<IFVRDamageable>();
			}
			if (val == null)
			{
				BreakableGlassDamager componentInParent = ((Component)hitCollider).GetComponentInParent<BreakableGlassDamager>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					val = (IFVRDamageable)(object)componentInParent;
				}
			}
			if (val == null)
			{
				return;
			}
			float num = ((!((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)) ? 0.05f : ((FVRPhysicalObject)this).RootRigidbody.mass);
			float num2 = 0.5f * num * speed * speed;
			float num3 = DistanceMultiplier(Vector3.Distance(m_launchPos, cpPoint)) * m_chargeDamageMult;
			float num4 = num2 * BluntPerJoule * num3;
			float num5 = ((!HasPiercingHead) ? 0f : (num2 * PiercingPerJoule * num3));
			SosigLink val2 = null;
			if ((Object)(object)hitCollider.attachedRigidbody != (Object)null)
			{
				SosigLink component = ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>();
				if ((Object)(object)component != (Object)null && (int)component.BodyPart == 0)
				{
					num4 *= HeadshotMultiplier;
					num5 *= HeadshotMultiplier;
				}
				if (SneakAttackCritical && (Object)(object)component != (Object)null && (Object)(object)component.S != (Object)null && (int)component.S.BodyState != 3 && !component.S.HasEverBeenAlerted())
				{
					num4 *= SneakAttackMultiplier;
					num5 *= SneakAttackMultiplier;
					val2 = component;
				}
			}
			Damage val3 = new Damage();
			val3.Class = (DamageClass)1;
			val3.Dam_Blunt = num4;
			val3.Dam_Piercing = num5;
			val3.Dam_TotalKinetic = num4 + num5;
			val3.point = cpPoint;
			val3.hitNormal = cpNormal;
			val3.strikeDir = dir;
			val3.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
			DamageSosigSafely(val, val3, null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.R != (Object)null && SneakAttackKnockback > 0f)
			{
				val2.R.AddForceAtPosition(dir * SneakAttackKnockback, cpPoint, (ForceMode)1);
			}
			if ((Object)(object)val2 != (Object)null && SneakAttackRagdoll)
			{
				RagdollSosig(val2.S, dir);
			}
			TryPoison(hitCollider);
			TryInstantKill(hitCollider);
		}

		private void TryPoison(Collider hitCollider)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (PoisonOnHit && !((Object)(object)hitCollider == (Object)null) && !((Object)(object)hitCollider.attachedRigidbody == (Object)null))
			{
				SosigLink component = ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.S == (Object)null) && (int)component.S.BodyState != 3)
				{
					component.S.ActivatePower((PowerupType)10, PoisonIntensity, PoisonDuration, PoisonVomit, true);
				}
			}
		}

		private void TryInstantKill(Collider hitCollider)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Invalid comparison between Unknown and I4
			if (InstantKillSpeechSets == null || InstantKillSpeechSets.Length == 0 || (Object)(object)hitCollider == (Object)null || (Object)(object)hitCollider.attachedRigidbody == (Object)null)
			{
				return;
			}
			SosigLink component = ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.S == (Object)null)
			{
				return;
			}
			Sosig s = component.S;
			string text = ((!((Object)(object)s.Speech != (Object)null)) ? null : ((Object)s.Speech).name);
			if (text == null || (int)s.BodyState == 3)
			{
				return;
			}
			for (int i = 0; i < InstantKillSpeechSets.Length; i++)
			{
				string value = InstantKillSpeechSets[i];
				if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					s.KillSosig();
					break;
				}
			}
		}

		private void RagdollSosig(Sosig s, Vector3 dir)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s == (Object)null || (int)s.BodyState == 3)
			{
				return;
			}
			s.Shudder(Mathf.Max(0.1f, SneakAttackRagdollSeconds / 1.5f));
			Vector3 val = dir + Vector3.up * SneakAttackBodyLift;
			Vector3 val2 = ((Vector3)(ref val)).normalized * SneakAttackBodyPush;
			for (int i = 0; i < s.Links.Count; i++)
			{
				SosigLink val3 = s.Links[i];
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3.R != (Object)null)
				{
					val3.R.AddForce(val2, (ForceMode)2);
				}
			}
		}

		private void DamageSosigSafely(IFVRDamageable target, Damage d, SosigLink knownLink)
		{
			//IL_0038: 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_0082: Invalid comparison between Unknown and I4
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected I4, but got Unknown
			SosigLink val = knownLink;
			if ((Object)(object)val == (Object)null)
			{
				Component val2 = (Component)(object)((target is Component) ? target : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val = val2.GetComponent<SosigLink>();
				}
			}
			if ((Object)(object)val != (Object)null && (int)val.BodyPart == 0 && d.Dam_Stunning < HeadStunSeconds)
			{
				d.Dam_Stunning = HeadStunSeconds;
			}
			if ((Object)(object)val != (Object)null && BodyStunSeconds > 0f && (int)d.Class != 3 && d.Dam_Stunning < BodyStunSeconds)
			{
				d.Dam_Stunning = BodyStunSeconds;
			}
			if (NeverExplodeHeads && (Object)(object)val != (Object)null && (int)val.BodyPart == 0)
			{
				float integrity = val.m_integrity;
				float num = (val.m_integrity = integrity + 1000f);
				if (d.Dam_Cutting > 340f)
				{
					d.Dam_Cutting = 340f;
				}
				target.Damage(d);
				if ((Object)(object)val != (Object)null)
				{
					float num2 = num - val.m_integrity;
					float num3 = Mathf.Min(integrity, val.m_fullintegrity * Mathf.Clamp01(HeadIntegrityFloor));
					val.m_integrity = Mathf.Max(integrity - num2, num3);
					if (num2 > 0f && (Object)(object)val.S != (Object)null)
					{
						val.S.UpdateRendererOnLink((int)val.BodyPart);
					}
				}
			}
			else
			{
				target.Damage(d);
			}
		}

		private void BleedInto(SosigLink link, Vector3 point, Vector3 strikeDir, float amount)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)link == (Object)null) && !((Object)(object)link.S == (Object)null) && !(amount <= 0f))
			{
				link.S.AccurueBleedingHit(link, point, strikeDir, amount);
			}
		}

		private float DepthBleedScale(float depth)
		{
			float num = Mathf.Max(0.01f, ArrowLength() * MaxPenetrationFraction);
			return Mathf.Lerp(0.5f, 1.5f, Mathf.Clamp01(depth / num));
		}

		private void PullOutDamage(FVRViveHand hand)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_00a6: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			SosigLink stuckLink = m_stuckLink;
			m_stuckLink = null;
			if (PullOutDamagesSosig && !((Object)(object)stuckLink == (Object)null))
			{
				Vector3 val = -((Component)this).transform.forward;
				Vector3 point = ((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform.position : TipPoint.position);
				float num = Mathf.Max(0.01f, ArrowLength() * MaxPenetrationFraction);
				float num2 = Mathf.Lerp(1f, 2f, Mathf.Clamp01(m_stuckDepth / num));
				Damage val2 = new Damage();
				val2.Class = (DamageClass)3;
				val2.point = point;
				val2.hitNormal = -val;
				val2.strikeDir = val;
				val2.damageSize = PullOutDamageSize;
				val2.edgeNormal = ((Component)this).transform.right;
				val2.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
				val2.Dam_Blunt = PullOutDamageBCP.x * num2;
				val2.Dam_Cutting = PullOutDamageBCP.y * num2;
				val2.Dam_Piercing = PullOutDamageBCP.z * num2;
				val2.Dam_TotalKinetic = val2.Dam_Blunt + val2.Dam_Cutting + val2.Dam_Piercing;
				DamageSosigSafely((IFVRDamageable)(object)stuckLink, val2, stuckLink);
				if (BleedOnPenetration)
				{
					BleedInto(stuckLink, point, val, PullOutBleed * DepthBleedScale(m_stuckDepth));
				}
				if ((Object)(object)hand != (Object)null)
				{
					hand.Buzz(hand.Buzzer.Buzz_GunShot);
				}
			}
		}

		private float SosigPenetration(float speed, Vector3 dir, Vector3 entry, SosigLink hitLink, out bool through, out Vector3 exitPoint, out SosigLink exitLink)
		{
			//IL_002e: 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_008a: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			float num = ((!((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)) ? 0.05f : ((FVRPhysicalObject)this).RootRigidbody.mass);
			float num2 = speed * Mathf.Max(0f, Vector3.Dot(dir, ((Component)this).transform.forward));
			float num3 = 0.5f * num * num2 * num2;
			float num4 = num3 / Mathf.Max(1f, SosigResistanceForce);
			float num5 = Mathf.Max(0.005f, ArrowLength() * (1f - MinShaftOutside));
			through = false;
			exitPoint = entry;
			exitLink = null;
			if (FixedPenetration > 0f)
			{
				return FixedPenetration;
			}
			float num6 = 0f;
			if ((Object)(object)hitLink != (Object)null && (Object)(object)hitLink.S != (Object)null)
			{
				float num7 = Mathf.Max(0.2f, ArrowLength() * SosigScanLengths);
				RaycastHit[] array = Physics.RaycastAll(entry + dir * num7, -dir, num7, -1, (QueryTriggerInteraction)1);
				float num8 = float.MaxValue;
				for (int i = 0; i < array.Length; i++)
				{
					Rigidbody attachedRigidbody = ((RaycastHit)(ref array[i])).collider.attachedRigidbody;
					if (!((Object)(object)attachedRigidbody == (Object)null))
					{
						SosigLink component = ((Component)attachedRigidbody).gameObject.GetComponent<SosigLink>();
						if (!((Object)(object)component == (Object)null) && !((Object)(object)component.S != (Object)(object)hitLink.S) && ((RaycastHit)(ref array[i])).distance < num8)
						{
							num8 = ((RaycastHit)(ref array[i])).distance;
							exitPoint = ((RaycastHit)(ref array[i])).point;
							exitLink = component;
						}
					}
				}
				if ((Object)(object)exitLink != (Object)null)
				{
					num6 = num7 - num8;
				}
			}
			float num9 = num4;
			if ((Object)(object)exitLink != (Object)null && num6 > 0.02f && num4 > num6)
			{
				num9 = Mathf.Max(num4, num6 + ArrowLength() * MinExitProtrusion);
				through = num9 <= num5 && num9 > num6;
			}
			if (!through)
			{
				exitLink = null;
			}
			return Mathf.Clamp(num9, 0.005f, num5);
		}

		private float PinDepth(float speed, Vector3 dir, Vector3 entry, SosigLink l)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			bool through;
			Vector3 exitPoint;
			SosigLink exitLink;
			return SosigPenetration(speed, dir, entry, l, out through, out exitPoint, out exitLink);
		}

		private float Depth(Vector2 range, float speed)
		{
			if (FixedPenetration > 0f)
			{
				return FixedPenetration;
			}
			float num = Mathf.InverseLerp(StickMinSpeed, Mathf.Max(StickMinSpeed + 0.01f, PenetrationFullSpeed), speed);
			float num2 = Mathf.Lerp(range.x, range.y, num) * Random.Range(1f - PenetrationVariation, 1f + PenetrationVariation);
			return Mathf.Clamp(num2, 0.005f, ArrowLength() * MaxPenetrationFraction);
		}

		private void Stick(Collider hitCollider, Vector3 cpPoint, Vector3 cpNormal, Vector3 dir, float speed)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00b7: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			State = ArrowState.Stuck;
			SetBowCollision(null, ignore: false);
			((Component)this).transform.rotation = Quaternion.LookRotation(dir);
			Transform val = ((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform : TipPoint);
			bool flag = (Object)(object)hitCollider.attachedRigidbody != (Object)null && (Object)(object)((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>() != (Object)null;
			bool through = false;
			Vector3 exitPoint = cpPoint;
			SosigLink exitLink = null;
			SosigLink val2 = ((!flag) ? null : ((Component)hitCollider.attachedRigidbody).gameObject.GetComponent<SosigLink>());
			float num = ((!flag) ? Depth(StickDepthRange, speed) : SosigPenetration(speed, dir, cpPoint, val2, out through, out exitPoint, out exitLink));
			Transform transform = ((Component)this).transform;
			transform.position += cpPoint + dir * num - val.position;
			if (flag)
			{
				m_stuckLink = val2;
				m_stuckDepth = num;
				if (BleedOnPenetration)
				{
					BleedInto(m_stuckLink, cpPoint, dir, PenetrationBleed * DepthBleedScale(num));
					if (through)
					{
						BleedInto(exitLink, exitPoint, dir, ExitBleed);
					}
				}
			}
			Rigidbody attachedRigidbody = hitCollider.attachedRigidbody;
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.velocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.angularVelocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = true;
			}
			if ((Object)(object)attachedRigidbody != (Object)null)
			{
				SwapSolidCollidersToNoCol();
			}
			Transform transform2 = ((Component)hitCollider).transform;
			if (UniformScaleChain(transform2))
			{
				((Component)this).transform.SetParent(transform2, true);
			}
			else
			{
				m_followTarget = transform2;
				m_followPos = transform2.InverseTransformPoint(((Component)this).transform.position);
				m_followRot = Quaternion.Inverse(transform2.rotation) * ((Component)this).transform.rotation;
			}
			m_anchor = ((Component)hitCollider).gameObject.GetComponent<ArrowStickAnchor>();
			if ((Object)(object)m_anchor == (Object)null)
			{
				m_anchor = ((Component)hitCollider).gameObject.AddComponent<ArrowStickAnchor>();
			}
			m_anchor.OnAnchorDestroyed += OnAnchorDestroyed;
		}

		private static bool UniformScaleChain(Transform t)
		{
			//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)
			while ((Object)(object)t != (Object)null)
			{
				Vector3 localScale = t.localScale;
				float num = Mathf.Abs(localScale.x);
				float num2 = Mathf.Abs(localScale.y);
				float num3 = Mathf.Abs(localScale.z);
				float num4 = Mathf.Max(num, Mathf.Max(num2, num3));
				float num5 = Mathf.Min(num, Mathf.Min(num2, num3));
				if (num5 < 0.0001f || num4 - num5 > 0.01f * num4)
				{
					return false;
				}
				t = t.parent;
			}
			return true;
		}

		public override void FVRUpdate()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			((FVRFireArmRound)this).FVRUpdate();
			UpdateFuse();
			if ((Object)(object)m_followTarget != (Object)null && State == ArrowState.Stuck)
			{
				((Component)this).transform.position = m_followTarget.TransformPoint(m_followPos);
				((Component)this).transform.rotation = m_followTarget.rotation * m_followRot;
			}
		}

		private void PinSosigLink(Collider hitCollider, SosigLink link, Vector3 cpPoint, Vector3 cpNormal, Vector3 dir, float speed)
		{
			//IL_0055: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00bd: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			State = ArrowState.Stuck;
			SetBowCollision(null, ignore: false);
			if ((Object)(object)((FVRPhysicalObject)this).RootRigidbody != (Object)null)
			{
				((FVRPhysicalObject)this).RootRigidbody.velocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.angularVelocity = Vector3.zero;
				((FVRPhysicalObject)this).RootRigidbody.isKinematic = true;
			}
			SwapSolidCollidersToNoCol();
			Vector3 val = cpPoint - cpNormal * 0.005f;
			DamageForPin(hitCollider, link.R, val, dir);
			Impale(link, val, dir, speed);
			m_stuckLink = link;
			m_stuckDepth = Mathf.Max(0.05f, Vector3.Distance((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform.position : TipPoint.position, val));
			if (BleedOnPenetration)
			{
				BleedInto(link, val, dir, PenetrationBleed * DepthBleedScale(m_stuckDepth));
			}
			m_anchor = ((Component)link).gameObject.GetComponent<ArrowStickAnchor>();
			if ((Object)(object)m_anchor == (Object)null)
			{
				m_anchor = ((Component)link).gameObject.AddComponent<ArrowStickAnchor>();
			}
			m_anchor.OnAnchorDestroyed += OnAnchorDestroyed;
		}

		private float ArrowLength()
		{
			//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)
			if ((Object)(object)NockPoint != (Object)null && (Object)(object)TipPoint != (Object)null)
			{
				return Vector3.Distance(NockPoint.position, TipPoint.position);
			}
			return 0.77f;
		}

		private void PlaceTip(Vector3 tipWorld)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((!((Object)(object)TipPoint != (Object)null)) ? ((Component)this).transform : TipPoint);
			Transform transform = ((Component)this).transform;
			transform.position += tipWorld - val.position;
		}

		private void DamageForPin(Collider c, Rigidbody r, Vector3 hitPoint, Vector3 castDir)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			IFVRDamageable component = ((Component)((Component)c).transform).gameObject.GetComponent<IFVRDamageable>();
			if (component == null && (Object)(object)r != (Object)null)
			{
				component = ((Component)r).gameObject.GetComponent<IFVRDamageable>();
			}
			if (component != null)
			{
				Damage val = new Damage();
				val.Class = (DamageClass)1;
				val.damageSize = PinThickness;
				val.hitNormal = -castDir;
				val.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
				val.strikeDir = castDir;
				val.point = hitPoint;
				val.Dam_Piercing = PinHitDamage;
				val.Dam_TotalKinetic = PinHitDamage;
				val.Dam_Stunning = PinStunning;
				DamageSosigSafely(component, val, null);
			}
		}

		private void Impale(SosigLink l, Vector3 hitPoint, Vector3 castDir, float speed)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0017: 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_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_0045: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: 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_0141: 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_0147: 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_0159: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Invalid comparison between Unknown and I4
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			float num = ArrowLength() + PinDistanceLimit;
			Damage val = new Damage();
			val.Class = (DamageClass)1;
			val.damageSize = PinThickness;
			val.hitNormal = -castDir;
			val.Source_IFF = GM.CurrentPlayerBody.GetPlayerIFF();
			val.strikeDir = castDir;
			val.Dam_Piercing = PinImpaleDamage;
			val.Dam_TotalKinetic = PinImpaleDamage;
			val.point = hitPoint;
			val.Dam_Stunning = PinStunning;
			Vector3 val2 = ((Component)l).transform.position + ((Component)l).transform.up * 0.15f;
			Vector3 val3 = ((Component)l).transform.position - ((Component)l).transform.up * 0.15f;
			bool flag = false;
			bool flag2 = false;
			RaycastHit val4 = default(RaycastHit);
			if (Physics.CapsuleCast(val2, val3, 0.13f, castDir, ref val4, num, LayerMask.op_Implicit(PinEnvironmentMask), (QueryTriggerInteraction)1))
			{
				RaycastHit val5 = default(RaycastHit);
				if (Physics.Raycast(hitPoint, castDir, ref val5, ((RaycastHit)(ref val4)).distance + ArrowLength(), LayerMask.op_Implicit(PinEnvironmentMask), (QueryTriggerInteraction)2) && (Object)(object)((Component)l).gameObject.GetComponent<FixedJoint>() == (Object)null)
				{
					((Component)l).transform.position = ((Component)l).transform.position + ((RaycastHit)(ref val4)).distance * castDir;
					PlaceTip(((RaycastHit)(ref val5)).point + castDir * 0.05f);
					m_pinJoint = ((Component)l).gameObject.AddComponent<FixedJoint>();
					l.S.KillSosig();
					((Component)this).transform.SetParent(((Component)l).transform);
					val.point += ((RaycastHit)(ref val4)).distance * castDir;
					flag = true;
					if ((Object)(object)((RaycastHit)(ref val5)).collider != (Object)null)
					{
						m_pinWall = ((Component)((RaycastHit)(ref val5)).collider).transform;
					}
					DamageSosigSafely((IFVRDamageable)(object)l, val, l);
				}
			}
			else if (Physics.CapsuleCast(val2, val3, 0.13f, castDir, ref val4, num, LayerMask.op_Implicit(PinAgentMask), (QueryTriggerInteraction)1) && (Object)(object)((Component)l).gameObject.GetComponent<FixedJoint>() == (Object)null)
			{
				Ray val6 = default(Ray);
				((Ray)(ref val6))..ctor(hitPoint, castDir);
				RaycastHit[] array = Physics.RaycastAll(val6, ((RaycastHit)(ref val4)).distance + ArrowLength(), LayerMask.op_Implicit(PinAgentMask), (QueryTriggerInteraction)2);
				for (int i = 0; i < array.Length; i++)
				{
					if (!((Object)(object)((RaycastHit)(ref array[i])).collider.attachedRigidbody == (Object)null))
					{
						SosigLink component = ((Component)((RaycastHit)(ref array[i])).collider.attachedRigidbody).gameObject.GetComponent<SosigLink>();
						if (!((Object)(object)component == (Object)null) && !((Object)(object)component == (Object)(object)l))
						{
							PlaceTip(hitPoint + castDir * PinDepth(speed, castDir, hitPoint, l));
							((Component)this).transform.SetParent(((Component)l).transform);
							((Component)l).transform.position = ((Component)l).transform.position + ((RaycastHit)(ref val4)).distance * castDir;
							FixedJoint val7 = ((Component)l).gameObject.AddComponent<FixedJoint>();
							((Joint)val7).connectedBody = component.R;
							m_pinJoint = val7;
							l.S.KillSosig();
							component.S.KillSosig();
							val.point += ((RaycastHit)(ref array[i])).distance * castDir;
							flag2 = true;
							DamageSosigSafely((IFVRDamageable)(object)l, val, l);
							DamageSosigSafely((IFVRDamageable)(object)component, val, component);
							break;
						}
					}
				}
			}
			if (!flag && !flag2)
			{
				PlaceTip(hitPoint + castDir * PinDepth(speed, castDir, hitPoint, l));
				((Component)this).transform.SetParent(((Component)l).transform);
				DamageSosigSafely((IFVRDamageable)(object)l, val, l);
				if ((int)l.S.BodyState != 3)
				{
					l.S.KillSosig();
				}
				l.R.AddForceAtPosition(castDir * PinShoveImpulse, hitPoint, (ForceMode)1);
			}
		}

		private void RemovePin()
		{
			if ((Object)(object)m_pinJoint != (Object)null)
			{
				Object.Destroy((Object)(object)m_pinJoint);
			}
			m_pinJoint = null;
		}

		private void SwapSolidCollidersToNoCol()
		{
			int num = LayerMask.NameToLayer("NoCol");
			if (num < 0 || m_cols == null || m_layerSwapped.Count > 0)
			{
				return;
			}
			m_layerSwapped.Clear();
			m_layerOriginal.Clear();
			for (int i = 0; i < m_cols.Length; i++)
			{
				if (!((Object)(object)m_cols[i] == (Object)null) && !m_cols[i].isTrigger)
				{
					GameObject gameObject = ((Component)m_cols[i]).gameObject;
					if (!m_layerSwapped.Contains(gameObject))
					{
						m_layerSwapped.Add(gameObject);
						m_layerOriginal.Add(gameObject.layer);
						gameObject.layer = num;
					}
				}
			}
		}

		private void ReleaseStuckJoint()
		{
			for (int i = 0; i < m_layerSwapped.Count; i++)
			{
				if ((Object)(object)m_layerSwapped[i] != (Object)null)
				{
					m_layerSwapped[i].layer = m_layerOriginal[i];
				}
			}
			m_layerSwapped.Clear();
			m_layerOriginal.Clear();
		}

		private void UnhookAnchor()
		{
			if ((Object)(object)m_anchor != (Object)null)
			{
				m_anchor.OnAnchorDestroyed -= OnAnchorDestroyed;
			}
			m_anchor = null;
		}

		private void OnAnchorDestroyed()
		{
			if ((Object)(object)this == (Object)null)
			{
				return;
			}
			m_anchor = null;
			if (State == ArrowState.Stuck)
			{
				if ((Object)(object)m_pinWall != (Object)null)
				{
					RestickToWall();
				}
				else
				{
					ReleaseToLoose();
				}
			}
		}

		private void RestickToWall()
		{
			//IL_0037: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			Transform pinWall = m_pinWall;
			m_pinWall = null;
			RemovePin();
			m_stuckLink = null;
			m_followTarget = null;
			((Component)this).transform.SetParent((Transform)null, true);
			((Component)this).transform.localScale = m_origScale;
			if (UniformScaleChain(pinWall))
			{
				((Component)this).transform.SetParent(pinWall, true);
			}
			else
			{
				m_followTarget = pinWall;
				m_followPos = pinWall.InverseTransformPoint(((Component)this).transform.position);
				m_followRot = Quaternion.Inverse(pinWall.rotation) * ((Component)this).transform.rotation;
			}
			m_anchor = ((Component)pinWall).gameObject.GetComponent<ArrowStickAnchor>();
			if ((Object)(object)m_anchor == (Object)null)
			{
				m_anchor = ((Component)pinWall).gameObject.AddComponent<ArrowStickAnchor>();
			}
			m_anchor.OnAnchorDestroyed += OnAnchorDestroyed;
		}
	}
	public class ArrowStickAnchor : MonoBehaviour
	{
		public delegate void DestroyedAction();

		public event DestroyedAction OnAnchorDestroyed;

		private void OnDestroy()
		{
			if (this.OnAnchorDestroyed != null)
			{
				this.OnAnchorDestroyed();
			}
		}
	}
}
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)(object)OwnPs == (Object)null)
		{
			OwnPs = ((Component)this).GetComponent<ParticleSystem>();
		}
		if (!((Object)(object)OwnPs == (Object)null))
		{
			UpdateParents();
			Camera val = ResolveViewerCamera();
			if (!((Object)(object)val == (Object)null))
			{
				BuildAndDraw(((Component)val).transform.position);
			}
		}
	}

	private void UpdateParents()
	{
		//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)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ParentSystem == (Object)null)
		{
			return;
		}
		MainModule main = ParentSystem.main;
		int maxParticles = ((MainModule)(ref main)).maxParticles;
		if (m_parentBuf.Length < maxParticles)
		{
			m_parentBuf = (Particle[])(object)new Particle[maxParticles];
		}
		int particles = ParentSystem.GetParticles(m_parentBuf);
		RecycleDeadSlots();
		m_seen.Clear();
		for (int i = 0; i < m_parents.Count; i++)
		{
			m_seen.Add(item: false);
		}
		for (int j = 0; j < particles; j++)
		{
			uint randomSeed = ((Particle)(ref m_parentBuf[j])).randomSeed;
			if (!m_parentIndex.TryGetValue(randomSeed, out var value))
			{
				if (m_freeSlots.Count > 0)
				{
					value = m_freeSlots[m_freeSlots.Count - 1];
					m_freeSlots.RemoveAt(m_freeSlots.Count - 1);
					m_parents[value].Seed = randomSeed;
				}
				else
				{
					ParentSlot parentSlot = new ParentSlot();
					parentSlot.Seed = randomSeed;
					value = m_parents.Count;
					m_parents.Add(parentSlot);
					m_seen.Add(item: false);
				}
				m_parentIndex[randomSeed] = value;
			}
			ParentSlot parentSlot2 = m_parents[value];
			parentSlot2.Pos = ToWorldPoint(ParentSystem, ((Particle)(ref m_parentBuf[j])).position);
			parentSlot2.Vel = ToWorldVector(ParentSystem, ((Particle)(ref m_parentBuf[j])).velocity);
			float startLifetime = ((Particle)(ref m_parentBuf[j])).startLifetime;
			float num = startLifetime - ((Particle)(ref m_parentBuf[j])).remainingLifetime;
			parentSlot2.Age01 = ((!(startLifetime > 1E-06f)) ? 1f : Mathf.Clamp01(num / startLifetime));
			parentSlot2.Dead = false;
			m_seen[value] = true;
		}
		for (int k = 0; k < m_parents.Count; k++)
		{
			if (!m_seen[k])
			{
				m_parents[k].Dead = true;
			}
		}
	}

	private void RecycleDeadSlots()
	{
		if (m_parents.Count < 32)
		{
			return;
		}
		m_slotRefs.Clear();
		foreach (KeyValuePair<uint, SeedInfo> item in m_vertSlot)
		{
			m_slotRefs[item.Value.Slot] = 1;
		}
		for (int i = 0; i < m_parents.Count; i++)
		{
			ParentSlot parentSlot = m_parents[i];
			if (parentSlot.Dead && !m_slotRefs.ContainsKey(i) && m_parentIndex.TryGetValue(parentSlot.Seed, out var value) && value == i)
			{
				m_parentIndex.Remove(parentSlot.Seed);
				m_slotBirthCount.Remove(i);
				m_freeSlots.Add(i);
			}
		}
	}

	private float ParentAge01(int slot)
	{
		if (slot < 0 || slot >= m_parents.Count)
		{
			return 1f;
		}
		return m_parents[slot].Age01;
	}

	private void BuildAndDraw(Vector3 camPos)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: 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_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0695: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		m_verts.Clear();
		m_uvs.Clear();
		m_cols.Clear();
		m_norms.Clear();
		m_tans.Clear();
		m_tris.Clear();
		MainModule main = OwnPs.main;
		int maxParticles = ((MainModule)(ref main)).maxParticles;
		if (m_ownBuf.Length < maxParticles)
		{
			m_ownBuf = (Particle[])(object)new Particle[maxParticles];
		}
		int particles = OwnPs.GetParticles(m_ownBuf);
		bool flag = m_parents.Count > 0;
		int frame = CryEditClock.Frame;
		for (int i = 0; i < particles; i++)
		{
			uint randomSeed = ((Particle)(ref m_ownBuf[i])).randomSeed;
			if (m_vertSlot.ContainsKey(randomSeed))
			{
				continue;
			}
			if (!m_seedFirstFrame.ContainsKey(randomSeed))
			{
				m_seedFirstFrame[randomSeed] = frame;
			}
			Vector3 val = ToWorldVector(OwnPs, ((Particle)(ref m_ownBuf[i])).velocity);
			bool flag2 = ((Vector3)(ref val)).sqrMagnitude > 1E-08f;
			bool flag3 = frame - m_seedFirstFrame[randomSeed] >= 3;
			if (!flag2 && !flag3 && flag)
			{
				continue;
			}
			SeedInfo value = new SeedInfo
			{
				Slot = 0,
				Fraction = 0f
			};
			if (flag)
			{
				int slot = 0;
				Vector3 val2 = ToWorldPoint(OwnPs, ((Particle)(ref m_ownBuf[i])).position);
				float num = float.MaxValue;
				float num2 = float.MaxValue;
				for (int j = 0; j < m_parents.Count; j++)
				{
					if (!m_parents[j].Dead)
					{
						Vector3 val3 = val2 - m_parents[j].Pos;
						float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
						if (sqrMagnitude < num)
						{
							num2 = num;
							num = sqrMagnitude;
							slot = j;
						}
						else if (sqrMagnitude < num2)
						{
							num2 = sqrMagnitude;
						}
					}
				}
				bool flag4 = num2 > 1E-12f && num <= num2 * 0.25f;
				if (!flag4 && flag2)
				{
					float num3 = -2f;
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					for (int k = 0; k < m_parents.Count; k++)
					{
						if (m_parents[k].Dead)
						{
							continue;
						}
						Vector3 vel = m_parents[k].Vel;
						if (!(((Vector3)(ref vel)).sqrMagnitude < 1E-08f))
						{
							float num4 = Vector3.Dot(normalized, ((Vector3)(ref vel)).normalized);
							if (num4 > num3)
							{
								num3 = num4;
								slot = k;
							}
						}
					}
					flag4 = true;
				}
				if (!flag4)
				{
					continue;
				}
				value.Slot = slot;
			}
			int value2 = 0;
			m_slotBirthCount.TryGetValue(value.Slot, out value2);
			int num5 = Mathf.Max(2, PerParentTotal);
			value.Fraction = Mathf.Clamp01((float)value2 / (float)(num5 - 1));
			m_slotBirthCount[value.Slot] = value2 + 1;
			m_vertSlot[randomSeed] = value;
		}
		m_liveSeeds.Clear();
		for (int l = 0; l < particles; l++)
		{
			m_liveSeeds.Add(((Particle)(ref m_ownBuf[l])).randomSeed);
		}
		m_prune.Clear();
		foreach (KeyValuePair<uint, SeedInfo> item in m_vertSlot)
		{
			if (!m_liveSeeds.Contains(item.Key))
			{
				m_prune.Add(item.Key);
			}
		}
		for (int m = 0; m < m_prune.Count; m++)
		{
			m_vertSl