Decompiled source of Stovepipe v3.3.4

Stovepipe.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using FistVR;
using HarmonyLib;
using Newtonsoft.Json;
using Stovepipe.Debug;
using Stovepipe.DoubleFeedPatches;
using Stovepipe.ModFiles;
using Stovepipe.ModFiles.BatteryFailure;
using Stovepipe.StovepipePatches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("Stovepipe")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Stovepipe")]
[assembly: AssemblyTitle("Stovepipe")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Stovepipe
{
	public class BulletDoubleFeedData : MonoBehaviour
	{
		private const float TimeUntilBulletCanBeRechamberedAfterUnDoubleFeeding = 1f;

		public DoubleFeedData gunData;

		public float timeSinceUnDoubleFed;

		public bool isThisBulletDoubleFeeding;

		private FVRFireArmRound _thisRoundScript;

		private void Start()
		{
			_thisRoundScript = ((Component)this).gameObject.GetComponent<FVRFireArmRound>();
		}

		private void Update()
		{
			if (!isThisBulletDoubleFeeding)
			{
				timeSinceUnDoubleFed += Time.deltaTime;
			}
			else
			{
				timeSinceUnDoubleFed = 0f;
			}
			if (timeSinceUnDoubleFed > 1f)
			{
				_thisRoundScript.isManuallyChamberable = true;
			}
		}
	}
	public class DoubleFeedAdjustment
	{
		public Vector3 UpperBulletLocalPos;

		public Quaternion UpperBulletDir;

		public Vector3 LowerBulletLocalPos;

		public Quaternion LowerBulletDir;

		public float BoltZ;
	}
	public class DoubleFeedData : MonoBehaviour
	{
		public bool isDoubleFeeding;

		public float bulletHeight;

		public float bulletRadius;

		public float doubleFeedChance;

		public float doubleFeedMaxChance;

		public bool hasSetDefaultChance;

		public bool usesIntegralMagazines;

		public FVRFireArmRound upperBullet;

		public FVRFireArmRound lowerBullet;

		public bool hasUpperBulletBeenRemoved;

		public bool hasLowerBulletBeenRemoved;

		public bool hasFinishedEjectingDoubleFeedRounds;

		public bool slideRackUnjamsUpperBullet;

		public bool slideRackUnjamsLowerBullet;

		public bool slideRackAndJiggleUnjamsUpperBullet;

		public bool slideRackAndJiggleUnjamsLowerBullet;

		public bool slideRackUnjamsLowerButRackAndJiggleUnjamsUpper;

		public StovepipeData thisWeaponsStovepipeData;

		public DoubleFeedAdjustment Adjustments;

		public bool hasFoundAdjustments;

		public float[,] BulletRandomness;

		public void SetProbability(bool weaponIsRifle)
		{
			if (weaponIsRifle)
			{
				doubleFeedChance = UserConfig.DoubleFeedRifleProb.Value;
				doubleFeedMaxChance = doubleFeedChance;
				hasSetDefaultChance = true;
			}
			else
			{
				doubleFeedChance = UserConfig.DoubleFeedHandgunProb.Value;
				doubleFeedMaxChance = doubleFeedChance;
				hasSetDefaultChance = true;
			}
		}

		public void SetDoubleFeedProbToMin()
		{
			doubleFeedChance = doubleFeedMaxChance / (float)UserConfig.ProbabilityCreepNumRounds.Value;
		}

		private void Start()
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			FVRFireArm component = ((Component)this).gameObject.GetComponent<FVRFireArm>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			FireArmMagazineType magazineType = component.MagazineType;
			FireArmMagazineType val = magazineType;
			if ((int)val <= 259)
			{
				if (val - 253 > 3 && val - 258 > 1)
				{
					return;
				}
			}
			else if ((int)val != 290 && (int)val != 999)
			{
				return;
			}
			usesIntegralMagazines = true;
		}
	}
	public class BulletStovepipeData : MonoBehaviour
	{
		public StovepipeData data;

		public float timeSinceStovepiped;

		private void Update()
		{
			timeSinceStovepiped += Time.deltaTime;
		}
	}
	public class StovepipeAdjustment
	{
		public Vector3 BulletLocalPos;

		public Quaternion BulletDir;

		public float BoltZ;
	}
	public class StovepipeData : MonoBehaviour
	{
		public FVRFireArmRound ejectedRound;

		public float ejectedRoundRadius;

		public float ejectedRoundHeight;

		public CapsuleCollider ejectedRoundCollider;

		public float defaultFrontPosition;

		public float[] randomPosAndRot;

		public bool hasBulletBeenStovepiped;

		public bool hasCollectedWeaponCharacteristics;

		public float timeSinceStovepiping;

		public bool ejectsToTheLeft;

		public bool hasFoundIfItEjectsUpwards;

		public bool ejectsUpwards;

		public StovepipeAdjustment Adjustments;

		public bool hasFoundAdjustments;

		public WeaponType weaponType;

		public int numOfRoundsSinceLastJam;

		public bool hasBulletsPositionBeenSet;

		public float stovepipeProb;

		public float stovepipeMaxProb;

		public DoubleFeedData thisDoubleFeedData;

		public bool isWeaponBatteryFailing;

		public float pointOfBatteryFail;

		public bool IsStovepiping { get; set; }

		public StovepipeData()
		{
			numOfRoundsSinceLastJam = UserConfig.MinRoundBeforeNextJam.Value;
		}

		public void CheckAndIncreaseProbability()
		{
			if (UserConfig.UseProbabilityCreep.Value && UserConfig.ProbabilityCreepNumRounds.Value != 0)
			{
				if (stovepipeProb < stovepipeMaxProb)
				{
					stovepipeProb += stovepipeMaxProb / (float)UserConfig.ProbabilityCreepNumRounds.Value;
				}
				CheckAndIncreaseDoubleFeedProbability();
			}
		}

		public void CheckAndIncreaseDoubleFeedProbability()
		{
			switch (weaponType)
			{
			case WeaponType.Handgun:
			{
				HandgunSlide component3 = ((Component)this).gameObject.GetComponent<HandgunSlide>();
				if (component3 == null)
				{
					break;
				}
				DoubleFeedData component4 = ((Component)component3.Handgun).GetComponent<DoubleFeedData>();
				if (component4 != null)
				{
					thisDoubleFeedData = component4;
					if (component4.doubleFeedChance < component4.doubleFeedMaxChance)
					{
						component4.doubleFeedChance += component4.doubleFeedMaxChance / (float)UserConfig.ProbabilityCreepNumRounds.Value;
					}
				}
				break;
			}
			case WeaponType.Rifle:
			{
				ClosedBolt component = ((Component)this).gameObject.GetComponent<ClosedBolt>();
				if (!((Object)(object)component == (Object)null))
				{
					DoubleFeedData component2 = ((Component)component.Weapon).GetComponent<DoubleFeedData>();
					if (component2 != null && component2.doubleFeedChance < component2.doubleFeedMaxChance)
					{
						component2.doubleFeedChance += component2.doubleFeedMaxChance / (float)UserConfig.ProbabilityCreepNumRounds.Value;
					}
				}
				break;
			}
			}
		}

		public void SetStoveProbToMin()
		{
			stovepipeProb = stovepipeMaxProb / (float)UserConfig.ProbabilityCreepNumRounds.Value;
		}

		public void SetWeaponType(WeaponType type)
		{
			weaponType = type;
			switch (type)
			{
			case WeaponType.Handgun:
				ejectsToTheLeft = StovepipeBase.FindIfGunEjectsToTheLeft(((Component)this).gameObject.GetComponent<HandgunSlide>());
				stovepipeMaxProb = UserConfig.StovepipeHandgunProb.Value;
				stovepipeProb = stovepipeMaxProb;
				break;
			case WeaponType.Rifle:
				ejectsToTheLeft = StovepipeBase.FindIfGunEjectsToTheLeft(((Component)this).gameObject.GetComponent<ClosedBolt>());
				stovepipeMaxProb = UserConfig.StovepipeRifleProb.Value;
				stovepipeProb = stovepipeMaxProb;
				break;
			case WeaponType.TubeFedShotgun:
				ejectsToTheLeft = StovepipeBase.FindIfGunEjectsToTheLeft(((Component)this).gameObject.GetComponent<TubeFedShotgunBolt>());
				stovepipeMaxProb = UserConfig.StovepipeTubeFedProb.Value;
				stovepipeProb = stovepipeMaxProb;
				break;
			case WeaponType.OpenBolt:
				ejectsToTheLeft = StovepipeBase.FindIfGunEjectsToTheLeft(((Component)this).gameObject.GetComponent<OpenBoltReceiverBolt>());
				stovepipeMaxProb = UserConfig.StovepipeOpenBoltProb.Value;
				stovepipeProb = stovepipeMaxProb;
				break;
			}
		}
	}
	public static class UserConfig
	{
		public static string DefaultStovepipeDir;

		public static string UserDefStovepipeDir;

		public static string DefaultDoubleFeedDir;

		public static string UserDefDoubleFeedDir;

		public static ConfigEntry<bool> IsDebug;

		public static ConfigEntry<bool> IsWriteToDefault;

		public static ConfigEntry<bool> IsDoubleFeedDebugMode;

		public static ConfigEntry<bool> IsStovepipeEnabled;

		public static ConfigEntry<bool> IsDoubleFeedEnabled;

		public static ConfigEntry<bool> IsBatteryFailureEnabled;

		public static ConfigEntry<float> BatteryFailureProb;

		public static ConfigEntry<float> StovepipeHandgunProb;

		public static ConfigEntry<float> StovepipeRifleProb;

		public static ConfigEntry<float> StovepipeTubeFedProb;

		public static ConfigEntry<float> StovepipeOpenBoltProb;

		public static ConfigEntry<float> StovepipeNextRoundNotChamberedProb;

		public static ConfigEntry<bool> EnableHittingStovepipedBulletOut;

		public static ConfigEntry<float> DoubleFeedHandgunProb;

		public static ConfigEntry<float> DoubleFeedRifleProb;

		public static ConfigEntry<float> LowerBulletDropoutProb;

		public static ConfigEntry<float> UpperBulletDropoutProb;

		public static ConfigEntry<float> LowerBulletShakeyProb;

		public static ConfigEntry<float> UpperBulletShakeyProb;

		public static ConfigEntry<int> MinRoundBeforeNextJam;

		public static ConfigEntry<bool> UseProbabilityCreep;

		public static ConfigEntry<int> ProbabilityCreepNumRounds;

		public static Dictionary<string, StovepipeAdjustment> DefaultStovepipeAdjustments;

		public static Dictionary<string, StovepipeAdjustment> UserDefinedStovepipeAdjustments;

		public static Dictionary<string, DoubleFeedAdjustment> DefaultDoubleFeedAdjustments;

		public static Dictionary<string, DoubleFeedAdjustment> UserDefinedDoubleFeedAdjustments;
	}
}
namespace Stovepipe.StovepipePatches
{
	public class ClosedBoltStovepipePatches : StovepipeBase
	{
		[HarmonyPatch(typeof(ClosedBoltWeapon), "EjectExtractedRound")]
		[HarmonyPrefix]
		private static bool GetBulletReference(ClosedBoltWeapon __instance)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.Chamber.IsFull)
			{
				return false;
			}
			StovepipeData stovepipeData = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if (stovepipeData == null)
			{
				stovepipeData = ((Component)__instance.Bolt).gameObject.AddComponent(typeof(StovepipeData)) as StovepipeData;
				stovepipeData.SetWeaponType(WeaponType.Rifle);
			}
			Transform transform = ((Component)__instance).transform;
			Vector3 right = transform.right;
			Vector3 up = transform.up;
			Vector3 forward = transform.forward;
			stovepipeData.ejectedRound = __instance.Chamber.EjectRound(__instance.RoundPos_Ejection.position, right * __instance.EjectionSpeed.x + up * __instance.EjectionSpeed.y + forward * __instance.EjectionSpeed.z, right * __instance.EjectionSpin.x + up * __instance.EjectionSpin.y + forward * __instance.EjectionSpin.z, __instance.RoundPos_Ejection.position, __instance.RoundPos_Ejection.rotation, false);
			if (stovepipeData.ejectedRound == null)
			{
				return false;
			}
			stovepipeData.numOfRoundsSinceLastJam++;
			stovepipeData.CheckAndIncreaseProbability();
			BulletStovepipeData bulletStovepipeData = ((Component)stovepipeData.ejectedRound).gameObject.AddComponent<BulletStovepipeData>();
			bulletStovepipeData.data = stovepipeData;
			stovepipeData.ejectedRoundCollider = ((Component)stovepipeData.ejectedRound).GetComponent<CapsuleCollider>();
			if (stovepipeData.ejectedRoundCollider == null)
			{
				return false;
			}
			stovepipeData.ejectedRoundRadius = stovepipeData.ejectedRoundCollider.radius;
			stovepipeData.ejectedRoundHeight = stovepipeData.ejectedRoundCollider.height;
			return false;
		}

		[HarmonyPatch(typeof(ClosedBolt), "BoltEvent_EjectRound")]
		[HarmonyPrefix]
		private static void StovepipeDiceroll(ClosedBolt __instance)
		{
			StovepipeData component = ((Component)__instance).gameObject.GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && !((FVRInteractiveObject)__instance).IsHeld)
			{
				ClosedBoltWeapon weapon = __instance.Weapon;
				if (!((Object)weapon).name.Contains("MX") && !component.isWeaponBatteryFailing && component.numOfRoundsSinceLastJam >= UserConfig.MinRoundBeforeNextJam.Value && weapon.Chamber.IsFull && weapon.Chamber.IsSpent && !weapon.Chamber.GetRound().IsCaseless && (!__instance.HasLastRoundBoltHoldOpen || (!((Object)(object)((FVRFireArm)weapon).Magazine == (Object)null) && ((FVRFireArm)weapon).Magazine.m_numRounds != 0)))
				{
					component.IsStovepiping = Random.Range(0f, 1f) < component.stovepipeProb;
					component.hasBulletBeenStovepiped = false;
				}
			}
		}

		[HarmonyPatch(typeof(ClosedBolt), "UpdateBolt")]
		[HarmonyPrefix]
		private static void BoltAndBulletUpdate(ClosedBolt __instance, ref float ___m_boltZ_forward, ref float ___m_boltZ_current)
		{
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: 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_0201: 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_015d: 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_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: 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_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: 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_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: 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_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance).gameObject.GetComponent<StovepipeData>();
			if (component == null)
			{
				return;
			}
			if (!component.hasCollectedWeaponCharacteristics)
			{
				component.defaultFrontPosition = ___m_boltZ_forward;
				component.hasCollectedWeaponCharacteristics = true;
			}
			if (!component.IsStovepiping && !component.isWeaponBatteryFailing)
			{
				if (!DebugMode.IsDebuggingWeapon)
				{
					___m_boltZ_forward = component.defaultFrontPosition;
				}
				return;
			}
			if (!component.hasBulletBeenStovepiped)
			{
				StovepipeBase.StartStovepipe(component);
				component.randomPosAndRot = StovepipeBase.GenerateRandomRifleNoise();
				component.Adjustments = DebugIO.ReadStovepipeAdjustment(((Object)__instance.Weapon).name);
				if (component.Adjustments != null)
				{
					component.hasFoundAdjustments = true;
				}
			}
			Transform transform = ((Component)__instance).transform;
			if (component.ejectedRound == null || component.ejectedRound.IsCaseless || (Object)(object)__instance.Weapon.Chamber.ProxyRound == (Object)null || component.hasBulletsPositionBeenSet)
			{
				return;
			}
			ClosedBoltWeapon weapon = __instance.Weapon;
			Transform transform2 = ((Component)component.ejectedRound).transform;
			if (component.hasFoundAdjustments)
			{
				transform2.localPosition = component.Adjustments.BulletLocalPos;
				transform2.localRotation = component.Adjustments.BulletDir;
				___m_boltZ_forward = component.Adjustments.BoltZ;
				component.timeSinceStovepiping += Time.deltaTime;
				component.hasBulletsPositionBeenSet = true;
				return;
			}
			Transform transform3 = ((Component)__instance.Weapon).transform;
			Vector3 val = transform3.right * weapon.EjectionSpeed.x + transform3.up * weapon.EjectionSpeed.y + transform3.forward * weapon.EjectionSpeed.z;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 forward = transform3.forward;
			if (!component.hasFoundIfItEjectsUpwards)
			{
				component.ejectsUpwards = StovepipeBase.IsRifleThatEjectsUpwards(weapon.RoundPos_Ejection, ((Component)__instance).transform, component.ejectedRound);
				component.hasFoundIfItEjectsUpwards = true;
			}
			if (component.ejectsUpwards)
			{
				transform2.rotation = Quaternion.LookRotation(transform.up, -transform.forward);
				transform2.position += forward * component.ejectedRoundRadius * 4f;
			}
			else
			{
				transform2.rotation = Quaternion.LookRotation(normalized, -transform.forward);
			}
			transform2.Rotate(transform.forward, component.randomPosAndRot[1], (Space)0);
			transform2.Rotate(transform2.right, component.randomPosAndRot[2], (Space)0);
			transform2.position = weapon.Chamber.ProxyRound.position - forward * component.ejectedRoundRadius * 4f - forward * component.ejectedRoundHeight / 2f + transform2.forward * component.ejectedRoundHeight * 0.3f + transform2.forward * component.randomPosAndRot[0];
			string name = ((Object)__instance.Weapon).name;
			bool flag = false;
			if (name.StartsWith("MP5"))
			{
				transform2.position -= transform3.forward * component.ejectedRoundRadius * 2f;
			}
			else if (name.StartsWith("AK") || __instance.UsesAKSafetyLock)
			{
				transform2.position += transform3.forward * component.ejectedRoundRadius * 3f + transform3.up * component.ejectedRoundRadius;
				flag = true;
			}
			else if (name.StartsWith("Zip"))
			{
				transform2.position += transform3.forward * component.ejectedRoundRadius * 3f;
			}
			float num = ((Component)weapon.Chamber).transform.localPosition.z - transform2.localPosition.z - component.ejectedRoundHeight / 2f;
			float num2 = component.defaultFrontPosition - num - 1.2f * component.ejectedRoundRadius;
			___m_boltZ_forward = num2;
			if (flag)
			{
				___m_boltZ_forward -= 2f * component.ejectedRoundRadius;
			}
			component.hasBulletsPositionBeenSet = true;
			component.timeSinceStovepiping += Time.deltaTime;
		}

		[HarmonyPatch(typeof(ClosedBolt), "BoltEvent_ExtractRoundFromMag")]
		[HarmonyPrefix]
		private static bool AbortExtractingMagIfStovepiping(ClosedBolt __instance)
		{
			if (!(((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData))
			{
				return true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				return true;
			}
			if (Random.Range(0f, 1f) < UserConfig.StovepipeNextRoundNotChamberedProb.Value)
			{
				((FVRFireArm)__instance.Weapon).PlayAudioEvent((FirearmAudioEventType)2, 1f);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(ClosedBoltWeapon), "Fire")]
		[HarmonyPrefix]
		private static bool StopFromFiringIfStovepiping(ClosedBoltWeapon __instance)
		{
			StovepipeData component = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(ClosedBoltWeapon), "DropHammer")]
		[HarmonyPrefix]
		private static bool StopFromDroppingHammerIfStovepiping(ClosedBoltWeapon __instance)
		{
			StovepipeData component = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(ClosedBoltHandle), "UpdateInteraction")]
		[HarmonyPostfix]
		private static void BoltHandleInteractionUnStovepipes(ClosedBoltHandle __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Weapon.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Weapon).RootRigidbody, ((Component)component.ejectedRound).transform.forward)))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Weapon).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(ClosedBolt), "UpdateInteraction")]
		[HarmonyPostfix]
		private static void BoltInteractionUnStovepipes(ClosedBolt __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Weapon.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Weapon).RootRigidbody, ((Component)component.ejectedRound).transform.forward)))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Weapon).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(ClosedBolt), "UpdateBolt")]
		[HarmonyPostfix]
		private static void UnStovepipeIfBoltIsLocked(ClosedBolt __instance)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Weapon.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && __instance.IsBoltLocked() && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Weapon).RootRigidbody, ((Component)component.ejectedRound).transform.forward)))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Weapon).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(ClosedBoltHandle), "UpdateHandle")]
		[HarmonyPostfix]
		private static void UnStovepipeIfBoltIsLockedUpwards(ClosedBoltHandle __instance, bool ___m_isAtLockAngle)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Weapon.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && ___m_isAtLockAngle && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Weapon).RootRigidbody, ((Component)component.ejectedRound).transform.forward)))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Weapon).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(ClosedBolt), "BoltEvent_EjectRound")]
		[HarmonyPrefix]
		private static bool StopEjectingRoundIfStovepiping(ClosedBolt __instance)
		{
			StovepipeData component = ((Component)__instance).GetComponent<StovepipeData>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			return __instance.Weapon.Chamber.IsSpent;
		}

		[HarmonyPatch(typeof(ClosedBolt), "BoltEvent_ExtractRoundFromMag")]
		[HarmonyPrefix]
		private static bool StopExtractingRoundIfBulletIsAlreadyInChamber(ClosedBolt __instance)
		{
			StovepipeData component = ((Component)__instance).GetComponent<StovepipeData>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			return !__instance.Weapon.Chamber.IsFull;
		}
	}
	public class HandgunStovepipePatches : StovepipeBase
	{
		[HarmonyPatch(typeof(Handgun), "EjectExtractedRound")]
		[HarmonyPrefix]
		private static bool GetBulletReference(Handgun __instance)
		{
			//IL_007e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.Chamber.IsFull)
			{
				return false;
			}
			Transform transform = ((Component)__instance).transform;
			StovepipeData stovepipeData = ((Component)__instance.Slide).GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (stovepipeData == null)
			{
				stovepipeData = ((Component)__instance.Slide).gameObject.AddComponent(typeof(StovepipeData)) as StovepipeData;
				stovepipeData.SetWeaponType(WeaponType.Handgun);
			}
			stovepipeData.ejectedRound = __instance.Chamber.EjectRound(__instance.RoundPos_Ejection.position, transform.right * __instance.RoundEjectionSpeed.x + transform.up * __instance.RoundEjectionSpeed.y + transform.forward * __instance.RoundEjectionSpeed.z, transform.right * __instance.RoundEjectionSpin.x + transform.up * __instance.RoundEjectionSpin.y + transform.forward * __instance.RoundEjectionSpin.z, __instance.RoundPos_Ejection.position, __instance.RoundPos_Ejection.rotation, false);
			if (stovepipeData.ejectedRound == null)
			{
				return false;
			}
			stovepipeData.numOfRoundsSinceLastJam++;
			stovepipeData.CheckAndIncreaseProbability();
			BulletStovepipeData bulletStovepipeData = ((Component)stovepipeData.ejectedRound).gameObject.AddComponent<BulletStovepipeData>();
			bulletStovepipeData.data = stovepipeData;
			stovepipeData.ejectedRoundCollider = ((Component)stovepipeData.ejectedRound).GetComponent<CapsuleCollider>();
			if (stovepipeData.ejectedRoundCollider == null)
			{
				return false;
			}
			stovepipeData.ejectedRoundRadius = stovepipeData.ejectedRoundCollider.radius;
			stovepipeData.ejectedRoundHeight = stovepipeData.ejectedRoundCollider.height;
			return false;
		}

		[HarmonyPatch(typeof(HandgunSlide), "SlideEvent_EjectRound")]
		[HarmonyPrefix]
		private static void StovepipeDiceroll(HandgunSlide __instance)
		{
			if (((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData && !((FVRInteractiveObject)__instance).IsHeld)
			{
				Handgun handgun = __instance.Handgun;
				if (!stovepipeData.isWeaponBatteryFailing && stovepipeData.numOfRoundsSinceLastJam >= UserConfig.MinRoundBeforeNextJam.Value && handgun.Chamber.IsFull && handgun.Chamber.IsSpent && !handgun.Chamber.GetRound().IsCaseless && (!__instance.HasLastRoundSlideHoldOpen || (!((Object)(object)((FVRFireArm)handgun).Magazine == (Object)null) && ((FVRFireArm)handgun).Magazine.m_numRounds != 0)))
				{
					stovepipeData.IsStovepiping = Random.Range(0f, 1f) < stovepipeData.stovepipeProb;
					stovepipeData.hasBulletBeenStovepiped = false;
				}
			}
		}

		[HarmonyPatch(typeof(HandgunSlide), "UpdateSlide")]
		[HarmonyPrefix]
		private static void SlideAndBulletUpdate(HandgunSlide __instance, ref float ___m_slideZ_forward, ref float ___m_slideZ_current)
		{
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01cb: 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_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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_0169: 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_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: 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)
			DoubleFeedData component = ((Component)__instance.Handgun).GetComponent<DoubleFeedData>();
			if ((Object)(object)component != (Object)null && component.isDoubleFeeding)
			{
				return;
			}
			StovepipeData component2 = ((Component)__instance).gameObject.GetComponent<StovepipeData>();
			if (component2 == null || component2.isWeaponBatteryFailing)
			{
				return;
			}
			if (!component2.hasCollectedWeaponCharacteristics)
			{
				component2.defaultFrontPosition = ___m_slideZ_forward;
				component2.hasCollectedWeaponCharacteristics = true;
			}
			if (!component2.IsStovepiping)
			{
				___m_slideZ_forward = component2.defaultFrontPosition;
				return;
			}
			float num = component2.defaultFrontPosition - component2.ejectedRoundRadius * 3f;
			___m_slideZ_forward = num;
			if (!component2.hasBulletBeenStovepiped)
			{
				StovepipeBase.StartStovepipe(component2);
				component2.randomPosAndRot = StovepipeBase.GenerateRandomHandgunNoise();
				component2.Adjustments = DebugIO.ReadStovepipeAdjustment(((Object)__instance.Handgun).name);
				component2.timeSinceStovepiping += Time.deltaTime;
				if (component2.Adjustments != null)
				{
					component2.hasFoundAdjustments = true;
				}
			}
			Transform transform = ((Component)__instance).transform;
			if (component2.ejectedRound == null || (Object)(object)__instance.Handgun.Chamber.ProxyRound == (Object)null)
			{
				return;
			}
			Transform transform2 = ((Component)component2.ejectedRound).transform;
			if (component2.hasFoundAdjustments)
			{
				transform2.localPosition = component2.Adjustments.BulletLocalPos;
				transform2.localRotation = component2.Adjustments.BulletDir;
				___m_slideZ_forward = component2.Adjustments.BoltZ;
				return;
			}
			transform2.position = __instance.Handgun.Chamber.ProxyRound.position - transform.forward * 0.5f * component2.ejectedRoundHeight - transform.forward * 1f * component2.ejectedRoundRadius + transform.up * component2.randomPosAndRot[0];
			transform2.rotation = Quaternion.LookRotation(transform.up, -transform.forward);
			transform2.Rotate(transform2.right, component2.randomPosAndRot[2], (Space)0);
			if (component2.ejectsToTheLeft)
			{
				transform2.Rotate(transform.forward, 0f - component2.randomPosAndRot[1], (Space)0);
				transform2.position -= 2f * component2.ejectedRoundRadius * transform.right * Mathf.Abs(Mathf.Sin(component2.randomPosAndRot[1]));
			}
			else
			{
				transform2.Rotate(transform.forward, component2.randomPosAndRot[1], (Space)0);
				transform2.position += 2f * component2.ejectedRoundRadius * transform.right * Mathf.Abs(Mathf.Sin(component2.randomPosAndRot[1]));
			}
			component2.timeSinceStovepiping += Time.deltaTime;
		}

		[HarmonyPatch(typeof(HandgunSlide), "UpdateSlide")]
		[HarmonyPostfix]
		private static void PhysicsSlideStovepipeCancelPatch(HandgunSlide __instance, float ___m_slideZ_current, float ___m_slideZ_forward)
		{
			StovepipeData component = ((Component)__instance).gameObject.GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && !(component.timeSinceStovepiping < 0.1f) && ___m_slideZ_current < ___m_slideZ_forward - 0.01f)
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Handgun).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(HandgunSlide), "SlideEvent_ExtractRoundFromMag")]
		[HarmonyPrefix]
		private static bool AbortExtractingMagIfStovepiping(HandgunSlide __instance)
		{
			StovepipeData stovepipeData = ((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) as StovepipeData;
			if ((Object)(object)stovepipeData == (Object)null)
			{
				return true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				return true;
			}
			if (Random.Range(0f, 1f) < UserConfig.StovepipeNextRoundNotChamberedProb.Value)
			{
				((FVRFireArm)__instance.Handgun).PlayAudioEvent((FirearmAudioEventType)2, 1f);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Handgun), "Fire")]
		[HarmonyPrefix]
		private static bool StopFromFiringIfStovepiping(Handgun __instance)
		{
			StovepipeData component = ((Component)__instance.Slide).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(Handgun), "DeCockHammer")]
		[HarmonyPatch(typeof(Handgun), "DropHammer")]
		[HarmonyPrefix]
		private static bool StopFromDroppingHammerIfStovepiping(Handgun __instance)
		{
			StovepipeData component = ((Component)__instance.Slide).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(HandgunSlide), "BeginInteraction")]
		[HarmonyPostfix]
		private static void SlideInteractionUnStovepipes(HandgunSlide __instance)
		{
			StovepipeData stovepipeData = ((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (!((Object)(object)stovepipeData == (Object)null) && stovepipeData.IsStovepiping)
			{
				StovepipeBase.UnStovepipe(stovepipeData, breakParentage: true, ((FVRPhysicalObject)__instance.Handgun).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(HandgunSlide), "SlideEvent_EjectRound")]
		[HarmonyPrefix]
		private static bool StopEjectingRoundIfStovepiping(HandgunSlide __instance)
		{
			StovepipeData component = ((Component)__instance).GetComponent<StovepipeData>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			return __instance.Handgun.Chamber.IsSpent;
		}

		[HarmonyPatch(typeof(HandgunSlide), "SlideEvent_ExtractRoundFromMag")]
		[HarmonyPrefix]
		private static bool StopExtractingRoundIfBulletIsAlreadyInChamber(HandgunSlide __instance)
		{
			StovepipeData component = ((Component)__instance).GetComponent<StovepipeData>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			return !__instance.Handgun.Chamber.IsFull;
		}
	}
	public class OpenBoltStovepipePatches : StovepipeBase
	{
		[HarmonyPatch(typeof(OpenBoltReceiver), "EjectExtractedRound")]
		[HarmonyPrefix]
		private static bool GetBulletReference(OpenBoltReceiver __instance)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d9: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.Chamber.IsFull)
			{
				return false;
			}
			StovepipeData stovepipeData = ((Component)__instance.Bolt).GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (stovepipeData == null)
			{
				stovepipeData = ((Component)__instance.Bolt).gameObject.AddComponent(typeof(StovepipeData)) as StovepipeData;
				stovepipeData.SetWeaponType(WeaponType.OpenBolt);
			}
			Transform transform = ((Component)__instance).transform;
			Vector3 right = transform.right;
			Vector3 up = transform.up;
			Vector3 forward = transform.forward;
			stovepipeData.ejectedRound = __instance.Chamber.EjectRound(__instance.RoundPos_Ejection.position, right * __instance.EjectionSpeed.x + up * __instance.EjectionSpeed.y + forward * __instance.EjectionSpeed.z, right * __instance.EjectionSpin.x + up * __instance.EjectionSpin.y + forward * __instance.EjectionSpin.z, __instance.RoundPos_Ejection.position, __instance.RoundPos_Ejection.rotation, false);
			if (stovepipeData.ejectedRound == null)
			{
				return false;
			}
			stovepipeData.numOfRoundsSinceLastJam++;
			stovepipeData.CheckAndIncreaseProbability();
			BulletStovepipeData bulletStovepipeData = ((Component)stovepipeData.ejectedRound).gameObject.AddComponent<BulletStovepipeData>();
			bulletStovepipeData.data = stovepipeData;
			stovepipeData.ejectedRoundCollider = ((Component)stovepipeData.ejectedRound).GetComponent<CapsuleCollider>();
			if (stovepipeData.ejectedRoundCollider == null)
			{
				return false;
			}
			stovepipeData.ejectedRoundRadius = stovepipeData.ejectedRoundCollider.radius;
			stovepipeData.ejectedRoundHeight = stovepipeData.ejectedRoundCollider.height;
			return false;
		}

		[HarmonyPatch(typeof(OpenBoltReceiverBolt), "BoltEvent_EjectRound")]
		[HarmonyPrefix]
		private static void StovepipeDiceroll(OpenBoltReceiverBolt __instance)
		{
			StovepipeData stovepipeData = ((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (!((Object)(object)stovepipeData == (Object)null) && !((FVRInteractiveObject)__instance).IsHeld)
			{
				OpenBoltReceiver receiver = __instance.Receiver;
				if (!((Object)receiver).name.Contains("MX") && !receiver.FireSelector_Modes.All((FireSelectorMode x) => (int)x.ModeType != 1) && !stovepipeData.isWeaponBatteryFailing && stovepipeData.numOfRoundsSinceLastJam >= UserConfig.MinRoundBeforeNextJam.Value && receiver.Chamber.IsFull && receiver.Chamber.IsSpent && !receiver.Chamber.GetRound().IsCaseless && (!__instance.HasLastRoundBoltHoldOpen || (!((Object)(object)((FVRFireArm)receiver).Magazine == (Object)null) && ((FVRFireArm)receiver).Magazine.m_numRounds != 0)))
				{
					stovepipeData.IsStovepiping = Random.Range(0f, 1f) < stovepipeData.stovepipeProb;
					stovepipeData.hasBulletBeenStovepiped = false;
				}
			}
		}

		[HarmonyPatch(typeof(OpenBoltReceiverBolt), "UpdateBolt")]
		[HarmonyPrefix]
		private static void BoltAndBulletUpdate(OpenBoltReceiverBolt __instance, ref float ___m_boltZ_forward, ref float ___m_boltZ_current)
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData))
			{
				return;
			}
			if (!stovepipeData.hasCollectedWeaponCharacteristics)
			{
				stovepipeData.defaultFrontPosition = ___m_boltZ_forward;
				stovepipeData.hasCollectedWeaponCharacteristics = true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				if (!DebugMode.IsDebuggingWeapon)
				{
					___m_boltZ_forward = stovepipeData.defaultFrontPosition;
				}
				return;
			}
			if (!stovepipeData.hasBulletBeenStovepiped)
			{
				StovepipeBase.StartStovepipe(stovepipeData);
				stovepipeData.randomPosAndRot = StovepipeBase.GenerateRandomRifleNoise();
				stovepipeData.Adjustments = DebugIO.ReadStovepipeAdjustment(((Object)__instance.Receiver).name);
				if (stovepipeData.Adjustments != null)
				{
					stovepipeData.hasFoundAdjustments = true;
				}
			}
			Transform transform = ((Component)__instance).transform;
			if (stovepipeData.ejectedRound == null || (Object)(object)__instance.Receiver.Chamber.ProxyRound == (Object)null)
			{
				return;
			}
			OpenBoltReceiver receiver = __instance.Receiver;
			Transform transform2 = ((Component)stovepipeData.ejectedRound).transform;
			if (stovepipeData.hasFoundAdjustments)
			{
				transform2.localPosition = stovepipeData.Adjustments.BulletLocalPos;
				transform2.localRotation = stovepipeData.Adjustments.BulletDir;
				___m_boltZ_forward = stovepipeData.Adjustments.BoltZ;
				stovepipeData.timeSinceStovepiping += Time.deltaTime;
				return;
			}
			Transform transform3 = ((Component)__instance.Receiver).transform;
			Vector3 val = transform3.right * receiver.EjectionSpeed.x + transform3.up * receiver.EjectionSpeed.y + transform3.forward * receiver.EjectionSpeed.z;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 forward = transform3.forward;
			if (!stovepipeData.hasFoundIfItEjectsUpwards)
			{
				stovepipeData.ejectsUpwards = StovepipeBase.IsRifleThatEjectsUpwards(receiver.RoundPos_Ejection, ((Component)__instance).transform, stovepipeData.ejectedRound);
				stovepipeData.hasFoundIfItEjectsUpwards = true;
			}
			if (stovepipeData.ejectsUpwards)
			{
				transform2.rotation = Quaternion.LookRotation(transform.up, -transform.forward);
				transform2.position += forward * stovepipeData.ejectedRoundRadius * 4f;
			}
			else
			{
				transform2.rotation = Quaternion.LookRotation(normalized, -transform.forward);
			}
			transform2.Rotate(transform.forward, stovepipeData.randomPosAndRot[1], (Space)0);
			transform2.Rotate(transform2.right, stovepipeData.randomPosAndRot[2], (Space)0);
			transform2.position = receiver.Chamber.ProxyRound.position - forward * stovepipeData.ejectedRoundRadius * 3.5f + transform2.forward * stovepipeData.ejectedRoundHeight * 0.3f + transform2.forward * stovepipeData.randomPosAndRot[0];
			float num = ((Component)receiver.Chamber).transform.localPosition.z - transform2.localPosition.z - stovepipeData.ejectedRoundHeight / 2f;
			float num2 = stovepipeData.defaultFrontPosition - num - 1f * stovepipeData.ejectedRoundRadius;
			___m_boltZ_forward = num2;
			stovepipeData.timeSinceStovepiping += Time.deltaTime;
		}

		[HarmonyPatch(typeof(OpenBoltReceiver), "EjectExtractedRound")]
		[HarmonyPrefix]
		private static bool AbortExtractingMagIfStovepiping(OpenBoltReceiver __instance)
		{
			if (!(((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData))
			{
				return true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				return true;
			}
			((FVRFireArm)__instance).PlayAudioEvent((FirearmAudioEventType)2, 1f);
			return false;
		}

		[HarmonyPatch(typeof(OpenBoltReceiverBolt), "UpdateBolt")]
		[HarmonyPostfix]
		private static void UnStovepipeIfBoltNotJammedAgainstBullet(OpenBoltReceiverBolt __instance, float ___m_boltZ_forward, float ___m_boltZ_current)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Receiver.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && __instance.Receiver.IsBoltCatchEngaged() && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Receiver).RootRigidbody, ((Component)component.ejectedRound).transform.forward)) && !(___m_boltZ_current - ___m_boltZ_forward > -0.005f) && !(((Component)component.ejectedRound).GetComponent<BulletStovepipeData>().timeSinceStovepiped < 0.2f))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Receiver).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(OpenBoltReceiver), "BeginChamberingRound")]
		[HarmonyPrefix]
		private static bool StopFromChamberingRoundIfStovepiping(OpenBoltReceiver __instance)
		{
			StovepipeData component = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			if (component.ejectedRound == null)
			{
				return true;
			}
			return false;
		}
	}
	public class StovepipeBase
	{
		protected const float TimeUntilCanPhysicsSlideUnStovepipe = 0.1f;

		protected static float[] GenerateRandomHandgunNoise()
		{
			return new float[3]
			{
				Random.Range(0.003f, 0.012f),
				-35f + Random.Range(-15f, 20f),
				Random.Range(0f, 15f)
			};
		}

		protected static float[] GenerateRandomRifleNoise()
		{
			return new float[3]
			{
				Random.Range(0.005f, 0.011f),
				Random.Range(0f, -20f),
				Random.Range(0f, 15f)
			};
		}

		protected static void StartStovepipe(StovepipeData data)
		{
			//IL_000c: 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)
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.velocity = Vector3.zero;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.angularVelocity = Vector3.zero;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.maxAngularVelocity = 0f;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.useGravity = false;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.detectCollisions = false;
			data.hasBulletBeenStovepiped = true;
			data.timeSinceStovepiping = 0f;
			data.numOfRoundsSinceLastJam = 0;
			data.SetStoveProbToMin();
			if ((Object)(object)data.thisDoubleFeedData != (Object)null)
			{
				data.thisDoubleFeedData.SetDoubleFeedProbToMin();
			}
			((FVRPhysicalObject)data.ejectedRound).StoreAndDestroyRigidbody();
			((Collider)data.ejectedRoundCollider).isTrigger = false;
			switch (data.weaponType)
			{
			case WeaponType.Handgun:
				((FVRPhysicalObject)data.ejectedRound).SetParentage(((Component)((Component)data).GetComponent<HandgunSlide>().Handgun).transform);
				break;
			case WeaponType.Rifle:
				((FVRPhysicalObject)data.ejectedRound).SetParentage(((Component)((Component)data).GetComponent<ClosedBolt>().Weapon).transform);
				break;
			case WeaponType.TubeFedShotgun:
				((FVRPhysicalObject)data.ejectedRound).SetParentage(((Component)((Component)data).GetComponent<TubeFedShotgunBolt>().Shotgun).transform);
				break;
			case WeaponType.OpenBolt:
				((FVRPhysicalObject)data.ejectedRound).SetParentage(((Component)((Component)data).GetComponent<OpenBoltReceiverBolt>().Receiver).transform);
				break;
			}
		}

		public static void UnStovepipe(StovepipeData data, bool breakParentage, Rigidbody weaponRb)
		{
			//IL_00a0: 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)
			((FVRPhysicalObject)data.ejectedRound).RecoverRigidbody();
			((Collider)data.ejectedRoundCollider).isTrigger = true;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.useGravity = true;
			data.hasBulletBeenStovepiped = false;
			data.IsStovepiping = false;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.maxAngularVelocity = 1000f;
			((FVRPhysicalObject)data.ejectedRound).RootRigidbody.detectCollisions = true;
			data.timeSinceStovepiping = 0f;
			data.hasBulletsPositionBeenSet = false;
			if (breakParentage)
			{
				((FVRPhysicalObject)data.ejectedRound).SetParentage((Transform)null);
			}
			if (!((Object)(object)weaponRb == (Object)null))
			{
				((FVRPhysicalObject)data.ejectedRound).RootRigidbody.velocity = weaponRb.velocity;
				((FVRPhysicalObject)data.ejectedRound).RootRigidbody.angularVelocity = weaponRb.angularVelocity;
			}
		}

		protected static Vector3 GetVectorThatPointsOutOfEjectionPort(HandgunSlide slide)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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)
			Vector3 val = slide.Handgun.RoundPos_Ejection.position - ((Component)slide).transform.position;
			float num = Vector3.Dot(((Component)slide).transform.forward, val);
			val -= num * ((Component)slide).transform.forward;
			return ((Vector3)(ref val)).normalized;
		}

		protected static Vector3 GetVectorThatPointsOutOfEjectionPort(ClosedBolt bolt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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)
			Vector3 val = bolt.Weapon.RoundPos_Ejection.position - ((Component)bolt).transform.position;
			float num = Vector3.Dot(((Component)bolt).transform.forward, val);
			val -= num * ((Component)bolt).transform.forward;
			return ((Vector3)(ref val)).normalized;
		}

		protected static Vector3 GetVectorThatPointsOutOfEjectionPort(TubeFedShotgunBolt bolt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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)
			Vector3 val = bolt.Shotgun.RoundPos_Ejection.position - ((Component)bolt).transform.position;
			float num = Vector3.Dot(((Component)bolt).transform.forward, val);
			val -= num * ((Component)bolt).transform.forward;
			return ((Vector3)(ref val)).normalized;
		}

		protected static Vector3 GetVectorThatPointsOutOfEjectionPort(OpenBoltReceiverBolt bolt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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)
			Vector3 val = bolt.Receiver.RoundPos_Ejection.position - ((Component)bolt).transform.position;
			float num = Vector3.Dot(((Component)bolt).transform.forward, val);
			val -= num * ((Component)bolt).transform.forward;
			return ((Vector3)(ref val)).normalized;
		}

		public static bool FindIfGunEjectsToTheLeft(HandgunSlide slide)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vectorThatPointsOutOfEjectionPort = GetVectorThatPointsOutOfEjectionPort(slide);
			float num = Vector3.Dot(vectorThatPointsOutOfEjectionPort, ((Component)slide).transform.right);
			return num < -0.005f;
		}

		public static bool FindIfGunEjectsToTheLeft(ClosedBolt bolt)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vectorThatPointsOutOfEjectionPort = GetVectorThatPointsOutOfEjectionPort(bolt);
			float num = Vector3.Dot(vectorThatPointsOutOfEjectionPort, ((Component)bolt).transform.right);
			return num < -0.005f;
		}

		public static bool FindIfGunEjectsToTheLeft(TubeFedShotgunBolt bolt)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vectorThatPointsOutOfEjectionPort = GetVectorThatPointsOutOfEjectionPort(bolt);
			float num = Vector3.Dot(vectorThatPointsOutOfEjectionPort, ((Component)bolt).transform.right);
			return num < -0.005f;
		}

		public static bool FindIfGunEjectsToTheLeft(OpenBoltReceiverBolt bolt)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 vectorThatPointsOutOfEjectionPort = GetVectorThatPointsOutOfEjectionPort(bolt);
			float num = Vector3.Dot(vectorThatPointsOutOfEjectionPort, ((Component)bolt).transform.right);
			return num < -0.005f;
		}

		[HarmonyPatch(typeof(FVRFireArmRound), "FVRUpdate")]
		[HarmonyPostfix]
		private static void BulletDecayPatch(ref float ___m_killAfter, FVRFireArmRound __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected I4, but got Unknown
			BulletStovepipeData component = ((Component)__instance).gameObject.GetComponent<BulletStovepipeData>();
			if (component != null && component.data.IsStovepiping)
			{
				SpentShellDespawnTime shellTime = GM.Options.SimulationOptions.ShellTime;
				SpentShellDespawnTime val = shellTime;
				switch ((int)val)
				{
				case 0:
					___m_killAfter = 5f;
					break;
				case 1:
					___m_killAfter = 10f;
					break;
				case 2:
					___m_killAfter = 30f;
					break;
				case 3:
					___m_killAfter = 999999f;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(FVRFireArmRound), "BeginInteraction")]
		[HarmonyPrefix]
		private static void UnstovepipeWhenGrabbed(FVRFireArmRound __instance)
		{
			BulletStovepipeData component = ((Component)__instance).GetComponent<BulletStovepipeData>();
			if (component == null)
			{
				return;
			}
			StovepipeData data = component.data;
			if (data.IsStovepiping)
			{
				UnStovepipe(data, breakParentage: true, null);
				switch (data.weaponType)
				{
				case WeaponType.Handgun:
					((FVRFireArm)((Component)data).GetComponent<HandgunSlide>().Handgun).PlayAudioEvent((FirearmAudioEventType)0, 1f);
					break;
				case WeaponType.Rifle:
					((FVRFireArm)((Component)data).GetComponent<ClosedBolt>().Weapon).PlayAudioEvent((FirearmAudioEventType)0, 1f);
					break;
				case WeaponType.TubeFedShotgun:
					((FVRFireArm)((Component)data).GetComponent<TubeFedShotgunBolt>().Shotgun).PlayAudioEvent((FirearmAudioEventType)0, 1f);
					break;
				case WeaponType.OpenBolt:
					((FVRFireArm)((Component)data).GetComponent<OpenBoltReceiverBolt>().Receiver).PlayAudioEvent((FirearmAudioEventType)0, 1f);
					break;
				default:
					throw new Exception("Sound for bullet grab not found!");
				}
			}
		}

		protected static bool DoesBulletAimAtFloor(FVRFireArmRound round)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Dot(((Component)round).transform.forward, Vector3.down) > 0f;
		}

		protected static bool IsRifleThatEjectsUpwards(Transform ejectionPos, Transform boltTransform, FVRFireArmRound round)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			return Vector3.Dot(ejectionPos.position - ((Component)boltTransform).transform.position, ((Component)boltTransform).transform.up) > 0.017f && (int)round.RoundType != 18 && (int)round.RoundType != 61;
		}

		protected static bool CouldBulletFallOutGunHorizontally(Rigidbody weaponRb, Vector3 bulletDirection)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Dot(weaponRb.velocity - ((Component)GM.CurrentPlayerBody.Hitboxes[1]).GetComponent<Rigidbody>().velocity, bulletDirection) > 0.5f;
		}
	}
	public class StovepipeHandGrabPatches
	{
		[HarmonyPatch(typeof(FVRViveHand), "TestCollider")]
		[HarmonyPostfix]
		private static void UnStovepipeBulletIfHitWithHand(FVRViveHand __instance, Collider collider, bool isEnter)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (!isEnter)
			{
				return;
			}
			BulletStovepipeData component = ((Component)collider).GetComponent<BulletStovepipeData>();
			if ((Object)(object)component == (Object)null || !component.data.IsStovepiping)
			{
				return;
			}
			Rigidbody component2 = ((Component)__instance).GetComponent<Rigidbody>();
			StovepipeData data = component.data;
			FVRFireArmRound ejectedRound = data.ejectedRound;
			Rigidbody component3 = ((Component)((Component)ejectedRound).transform.parent).GetComponent<Rigidbody>();
			Vector3 val = component2.velocity - component3.velocity;
			if (!((Object)(object)__instance.CurrentInteractable != (Object)null) && __instance.Input.GripPressed)
			{
				if (((Vector3)(ref val)).magnitude < 0.03f)
				{
					SM.PlayHandlingGrabSound(((FVRInteractiveObject)ejectedRound).HandlingGrabSound, ((Component)ejectedRound).transform.position, false);
					return;
				}
				SM.PlayHandlingGrabSound(((FVRInteractiveObject)ejectedRound).HandlingGrabSound, ((Component)ejectedRound).transform.position, true);
				Transform transform = ((Component)ejectedRound).transform;
				transform.position += ((Component)ejectedRound).transform.up * 0.1f;
				StovepipeBase.UnStovepipe(data, breakParentage: true, component3);
				Rigidbody component4 = ((Component)ejectedRound).GetComponent<Rigidbody>();
				((FVRInteractiveObject)ejectedRound).SetAllCollidersToLayer(true, "Water");
				component4.AddForce(val * 2f, (ForceMode)1);
			}
		}

		private static Transform FindRoundEjectionPositionGeneric(FVRFireArm fireArm)
		{
			ClosedBoltWeapon val = (ClosedBoltWeapon)(object)((fireArm is ClosedBoltWeapon) ? fireArm : null);
			if (val == null)
			{
				Handgun val2 = (Handgun)(object)((fireArm is Handgun) ? fireArm : null);
				if (val2 == null)
				{
					OpenBoltReceiver val3 = (OpenBoltReceiver)(object)((fireArm is OpenBoltReceiver) ? fireArm : null);
					if (val3 == null)
					{
						TubeFedShotgun val4 = (TubeFedShotgun)(object)((fireArm is TubeFedShotgun) ? fireArm : null);
						if (val4 != null)
						{
							return val4.RoundPos_Ejection;
						}
						throw new ArgumentOutOfRangeException("fireArm");
					}
					return val3.RoundPos_Ejection;
				}
				return val2.RoundPos_Ejection;
			}
			return val.RoundPos_Ejection;
		}
	}
	public class TubeFedStovepipePatches : StovepipeBase
	{
		[HarmonyPatch(typeof(TubeFedShotgun), "EjectExtractedRound")]
		[HarmonyPrefix]
		private static bool GetBulletReference(TubeFedShotgun __instance)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d9: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.Chamber.IsFull)
			{
				return false;
			}
			StovepipeData stovepipeData = ((Component)__instance.Bolt).GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (stovepipeData == null)
			{
				stovepipeData = ((Component)__instance.Bolt).gameObject.AddComponent(typeof(StovepipeData)) as StovepipeData;
				stovepipeData.SetWeaponType(WeaponType.TubeFedShotgun);
			}
			Transform transform = ((Component)__instance).transform;
			Vector3 right = transform.right;
			Vector3 up = transform.up;
			Vector3 forward = transform.forward;
			stovepipeData.ejectedRound = __instance.Chamber.EjectRound(__instance.RoundPos_Ejection.position, right * __instance.RoundEjectionSpeed.x + up * __instance.RoundEjectionSpeed.y + forward * __instance.RoundEjectionSpeed.z, right * __instance.RoundEjectionSpeed.x + up * __instance.RoundEjectionSpeed.y + forward * __instance.RoundEjectionSpeed.z, __instance.RoundPos_Ejection.position, __instance.RoundPos_Ejection.rotation, false);
			if (stovepipeData.ejectedRound == null)
			{
				return false;
			}
			stovepipeData.numOfRoundsSinceLastJam++;
			stovepipeData.CheckAndIncreaseProbability();
			BulletStovepipeData bulletStovepipeData = ((Component)stovepipeData.ejectedRound).gameObject.AddComponent<BulletStovepipeData>();
			bulletStovepipeData.data = stovepipeData;
			stovepipeData.ejectedRoundCollider = ((Component)stovepipeData.ejectedRound).GetComponent<CapsuleCollider>();
			if (stovepipeData.ejectedRoundCollider == null)
			{
				return false;
			}
			stovepipeData.ejectedRoundRadius = stovepipeData.ejectedRoundCollider.radius;
			stovepipeData.ejectedRoundHeight = stovepipeData.ejectedRoundCollider.height;
			return false;
		}

		[HarmonyPatch(typeof(TubeFedShotgunBolt), "BoltEvent_EjectRound")]
		[HarmonyPrefix]
		private static void StovepipeDiceroll(TubeFedShotgunBolt __instance)
		{
			StovepipeData stovepipeData = ((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) as StovepipeData;
			if (!((Object)(object)stovepipeData == (Object)null) && !((FVRInteractiveObject)__instance).IsHeld)
			{
				TubeFedShotgun shotgun = __instance.Shotgun;
				if (!stovepipeData.isWeaponBatteryFailing && stovepipeData.numOfRoundsSinceLastJam >= UserConfig.MinRoundBeforeNextJam.Value && shotgun.Chamber.IsFull && shotgun.Chamber.IsSpent && !shotgun.Chamber.GetRound().IsCaseless && (!__instance.HasLastRoundBoltHoldOpen || (!((Object)(object)((FVRFireArm)shotgun).Magazine == (Object)null) && ((FVRFireArm)shotgun).Magazine.m_numRounds != 0)))
				{
					stovepipeData.IsStovepiping = Random.Range(0f, 1f) < stovepipeData.stovepipeProb;
					stovepipeData.hasBulletBeenStovepiped = false;
				}
			}
		}

		[HarmonyPatch(typeof(TubeFedShotgunBolt), "UpdateBolt")]
		[HarmonyPrefix]
		private static void BoltAndBulletUpdate(TubeFedShotgunBolt __instance, ref float ___m_boltZ_forward)
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData))
			{
				return;
			}
			if (!stovepipeData.hasCollectedWeaponCharacteristics)
			{
				stovepipeData.defaultFrontPosition = ___m_boltZ_forward;
				stovepipeData.hasCollectedWeaponCharacteristics = true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				if (!DebugMode.IsDebuggingWeapon)
				{
					___m_boltZ_forward = stovepipeData.defaultFrontPosition;
				}
				return;
			}
			if (!stovepipeData.hasBulletBeenStovepiped)
			{
				StovepipeBase.StartStovepipe(stovepipeData);
				stovepipeData.randomPosAndRot = StovepipeBase.GenerateRandomRifleNoise();
				stovepipeData.Adjustments = DebugIO.ReadStovepipeAdjustment(((Object)__instance.Shotgun).name);
				if (stovepipeData.Adjustments != null)
				{
					stovepipeData.hasFoundAdjustments = true;
				}
			}
			Transform transform = ((Component)__instance).transform;
			if (stovepipeData.ejectedRound == null || (Object)(object)__instance.Shotgun.Chamber.ProxyRound == (Object)null)
			{
				return;
			}
			TubeFedShotgun shotgun = __instance.Shotgun;
			Transform transform2 = ((Component)stovepipeData.ejectedRound).transform;
			if (stovepipeData.hasFoundAdjustments)
			{
				transform2.localPosition = stovepipeData.Adjustments.BulletLocalPos;
				transform2.localRotation = stovepipeData.Adjustments.BulletDir;
				___m_boltZ_forward = stovepipeData.Adjustments.BoltZ;
				stovepipeData.timeSinceStovepiping += Time.deltaTime;
				return;
			}
			Transform transform3 = ((Component)__instance.Shotgun).transform;
			Vector3 val = transform3.right * shotgun.RoundEjectionSpeed.x + transform3.up * shotgun.RoundEjectionSpeed.y + transform3.forward * shotgun.RoundEjectionSpeed.z;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 forward = transform3.forward;
			if (!stovepipeData.hasFoundIfItEjectsUpwards)
			{
				stovepipeData.ejectsUpwards = StovepipeBase.IsRifleThatEjectsUpwards(shotgun.RoundPos_Ejection, ((Component)__instance).transform, stovepipeData.ejectedRound);
				stovepipeData.hasFoundIfItEjectsUpwards = true;
			}
			if (stovepipeData.ejectsUpwards)
			{
				transform2.rotation = Quaternion.LookRotation(transform.up, -transform.forward);
				transform2.position += forward * stovepipeData.ejectedRoundRadius * 4f;
			}
			else
			{
				transform2.rotation = Quaternion.LookRotation(normalized, -transform.forward);
			}
			transform2.Rotate(transform.forward, stovepipeData.randomPosAndRot[1], (Space)0);
			transform2.Rotate(transform2.right, stovepipeData.randomPosAndRot[2], (Space)0);
			transform2.position = shotgun.Chamber.ProxyRound.position - forward * stovepipeData.ejectedRoundRadius * 4f + transform2.forward * stovepipeData.ejectedRoundHeight * 0.3f + transform2.forward * stovepipeData.randomPosAndRot[0];
			float num = ((Component)shotgun.Chamber).transform.localPosition.z - transform2.localPosition.z - stovepipeData.ejectedRoundHeight / 2f;
			float num2 = stovepipeData.defaultFrontPosition - num - 1.2f * stovepipeData.ejectedRoundRadius;
			___m_boltZ_forward = num2;
			stovepipeData.timeSinceStovepiping += Time.deltaTime;
		}

		[HarmonyPatch(typeof(TubeFedShotgunBolt), "BoltEvent_ExtractRoundFromMag")]
		[HarmonyPrefix]
		private static bool AbortExtractingMagIfStovepiping(TubeFedShotgunBolt __instance)
		{
			if (!(((Component)__instance).gameObject.GetComponent(typeof(StovepipeData)) is StovepipeData stovepipeData))
			{
				return true;
			}
			if (!stovepipeData.IsStovepiping)
			{
				return true;
			}
			if (Random.Range(0f, 1f) < UserConfig.StovepipeNextRoundNotChamberedProb.Value)
			{
				((FVRFireArm)__instance.Shotgun).PlayAudioEvent((FirearmAudioEventType)2, 1f);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(TubeFedShotgunBolt), "UpdateBolt")]
		[HarmonyPostfix]
		private static void UnStovepipeIfBoltIsLockedOrBack(TubeFedShotgunBolt __instance, bool ___m_isBoltLocked, float ___m_boltZ_current, float ___m_boltZ_forward)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			StovepipeData component = ((Component)__instance.Shotgun.Bolt).GetComponent<StovepipeData>();
			if (!((Object)(object)component == (Object)null) && component.IsStovepiping && component.ejectedRound != null && !(((Component)component.ejectedRound).GetComponent<BulletStovepipeData>().timeSinceStovepiped < 0.5f) && (___m_isBoltLocked || !(___m_boltZ_current - ___m_boltZ_forward > -0.01f)) && (StovepipeBase.DoesBulletAimAtFloor(component.ejectedRound) || StovepipeBase.CouldBulletFallOutGunHorizontally(((FVRPhysicalObject)__instance.Shotgun).RootRigidbody, ((Component)component.ejectedRound).transform.forward)))
			{
				StovepipeBase.UnStovepipe(component, breakParentage: true, ((FVRPhysicalObject)__instance.Shotgun).RootRigidbody);
			}
		}

		[HarmonyPatch(typeof(TubeFedShotgun), "Fire")]
		[HarmonyPrefix]
		private static bool StopFromFiringIfStovepiping(TubeFedShotgun __instance)
		{
			StovepipeData component = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(TubeFedShotgun), "ReleaseHammer")]
		[HarmonyPrefix]
		private static bool StopFromDroppingHammerIfStovepiping(TubeFedShotgun __instance)
		{
			StovepipeData component = ((Component)__instance.Bolt).GetComponent<StovepipeData>();
			if (component == null)
			{
				return true;
			}
			return !component.IsStovepiping;
		}

		[HarmonyPatch(typeof(TubeFedShotgunBolt), "BoltEvent_EjectRound")]
		[HarmonyPrefix]
		private static bool StopFromEjectingIfStovepiping(TubeFedShotgunBolt __instance)
		{
			StovepipeData component = ((Component)__instance).GetComponent<StovepipeData>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			if (!component.IsStovepiping)
			{
				return true;
			}
			return __instance.Shotgun.Chamber.IsSpent;
		}
	}
}
namespace Stovepipe.DoubleFeedPatches
{
	public class ClosedBoltDoubleFeedPatches : DoubleFeedBase
	{
		[HarmonyPatch(typeof(ClosedBolt), "BoltEvent_ExtractRoundFromMag")]
		[HarmonyPostfix]
		private static void DoubleFeedDiceroll(ClosedBolt __instance, ref float ___m_boltZ_forward)
		{
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			if (((FVRInteractiveObject)__instance).IsHeld || ((Object)(object)__instance.Weapon.Handle != (Object)null && ((FVRInteractiveObject)__instance.Weapon.Handle).IsHeld) || (Object)(object)((FVRFireArm)__instance.Weapon).Magazine == (Object)null || ((FVRFireArm)__instance.Weapon).Magazine.m_numRounds < 2 || (Object)(object)__instance.Weapon.Chamber.GetRound() != (Object)null)
			{
				return;
			}
			StovepipeData component = ((Component)__instance.Weapon.Bolt).GetComponent<StovepipeData>();
			if ((Object)(object)component != (Object)null && (component.IsStovepiping || component.numOfRoundsSinceLastJam < UserConfig.MinRoundBeforeNextJam.Value || component.isWeaponBatteryFailing))
			{
				return;
			}
			DoubleFeedData doubleFeedData = ((Component)__instance.Weapon).gameObject.GetComponent<DoubleFeedData>() ?? ((Component)__instance.Weapon).gameObject.AddComponent<DoubleFeedData>();
			if (!doubleFeedData.hasSetDefaultChance)
			{
				doubleFeedData.SetProbability(weaponIsRifle: true);
			}
			doubleFeedData.thisWeaponsStovepipeData = component;
			if (doubleFeedData.isDoubleFeeding)
			{
				return;
			}
			doubleFeedData.hasUpperBulletBeenRemoved = false;
			doubleFeedData.hasLowerBulletBeenRemoved = false;
			GameObject gameObject = ((AnvilAsset)AM.GetRoundSelfPrefab(__instance.Weapon.Chamber.RoundType, AM.GetDefaultRoundClass(__instance.Weapon.Chamber.RoundType))).GetGameObject();
			if (gameObject.GetComponent<FVRFireArmRound>().IsCaseless)
			{
				return;
			}
			doubleFeedData.isDoubleFeeding = Random.Range(0f, 1f) < doubleFeedData.doubleFeedChance;
			if (doubleFeedData.isDoubleFeeding)
			{
				doubleFeedData.BulletRandomness = DoubleFeedBase.GenerateRandomOffsets();
				DoubleFeedBase.GenerateUnJammingProbs(doubleFeedData, isRifle: true);
				doubleFeedData.hasFinishedEjectingDoubleFeedRounds = false;
				doubleFeedData.Adjustments = DebugIO.ReadDoubleFeedAdjustment(((Object)__instance.Weapon).name);
				if (doubleFeedData.Adjustments != null)
				{
					doubleFeedData.hasFoundAdjustments = true;
				}
				if (!__instance.Weapon.ChamberRound())
				{
					__instance.Weapon.BeginChamberingRound();
					__instance.Weapon.ChamberRound();
				}
				doubleFeedData.upperBullet = __instance.Weapon.Chamber.EjectRound(__instance.Weapon.RoundPos_Ejection.position, Vector3.zero, Vector3.zero, false);
				__instance.Weapon.BeginChamberingRound();
				__instance.Weapon.ChamberRound();
				doubleFeedData.lowerBullet = __instance.Weapon.Chamber.EjectRound(__instance.Weapon.RoundPos_Ejection.position + Vector3.down * 0.3f, Vector3.zero, Vector3.zero, false);
				doubleFeedData.hasFinishedEjectingDoubleFeedRounds = true;
				CapsuleCollider component2 = ((Component)doubleFeedData.upperBullet).gameObject.GetComponent<CapsuleCollider>();
				doubleFeedData.bulletHeight = component2.height;
				doubleFeedData.bulletRadius = component2.radius;
				BulletDoubleFeedData bulletDoubleFeedData = ((Component)doubleFeedData.upperBullet).GetComponent<BulletDoubleFeedData>() ?? ((Component)doubleFeedData.upperBullet).gameObject.AddComponent<BulletDoubleFeedData>();
				BulletDoubleFeedData bulletDoubleFeedData2 = ((Component)doubleFeedData.lowerBullet).GetComponent<BulletDoubleFeedData>() ?? ((Component)doubleFeedData.lowerBullet).gameObject.AddComponent<BulletDoubleFeedData>();
				bulletDoubleFeedData.gunData = doubleFeedData;
				bulletDoubleFeedData2.gunData = doubleFeedData;
				DoubleFeedBase.SetBulletToNonInteracting(doubleFeedData.upperBullet, doubleFeedData, setParentToWeapon: true, ((Component)__instance.Weapon).transform);
				DoubleFeedBase.SetBulletToNonInteracting(doubleFeedData.lowerBullet, doubleFeedData, setParentToWeapon: true, ((Component)__instance.Weapon).transform);
				Transform transform = ((Component)doubleFeedData.upperBullet).transform;
				Transform transform2 = ((Component)doubleFeedData.lowerBullet).transform;
				if (doubleFeedData.hasFoundAdjustments)
				{
					transform.localPosition = doubleFeedData.Adjustments.UpperBulletLocalPos;
					transform.localRotation = doubleFeedData.Adjustments.UpperBulletDir;
					transform2.localPosition = doubleFeedData.Adjustments.LowerBulletLocalPos;
					transform2.localRotation = doubleFeedData.Adjustments.LowerBullet