Decompiled source of Stovepipe v3.3.4
Stovepipe.dll
Decompiled 10 months ago
The result has been truncated due to the large size, download it to view full contents!
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