using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using FistVR; using HarmonyLib; using ModularWorkshop; using OpenScripts2; using OtherLoader; using Sodalite.Api; using UnityEngine; using UnityEngine.UI; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] public class ForwardAssist : FVRInteractiveObject { [Header("Animation Settings")] public Transform TargetTransform; public Vector3 StartPosition; public Vector3 EndPosition; public Vector3 StartRotation; public Vector3 EndRotation; public float MoveSpeed = 10f; public float ResetDelay = 0.2f; [Header("Audio Settings")] public AudioEvent PokeAudioEvent; public FVRPooledAudioType AudioType = (FVRPooledAudioType)0; private float m_animFloat = 0f; private bool m_isPoked = false; private float m_resetTimer = 0f; protected void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) ((FVRInteractiveObject)this).Awake(); if ((Object)(object)TargetTransform == (Object)null) { TargetTransform = ((Component)this).transform; } if (StartPosition == Vector3.zero) { StartPosition = TargetTransform.localPosition; } if (StartRotation == Vector3.zero) { StartRotation = TargetTransform.localEulerAngles; } } public override void Poke(FVRViveHand hand) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (PokeAudioEvent != null) { SM.PlayCoreSound(AudioType, PokeAudioEvent, ((Component)this).transform.position); } m_isPoked = true; m_resetTimer = ResetDelay; } private void Update() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) if (m_isPoked) { m_animFloat = Mathf.MoveTowards(m_animFloat, 1f, Time.deltaTime * MoveSpeed); m_resetTimer -= Time.deltaTime; if (m_resetTimer <= 0f) { m_isPoked = false; } } else { m_animFloat = Mathf.MoveTowards(m_animFloat, 0f, Time.deltaTime * MoveSpeed); } if ((Object)(object)TargetTransform != (Object)null) { TargetTransform.localPosition = Vector3.Lerp(StartPosition, EndPosition, m_animFloat); TargetTransform.localEulerAngles = Vector3.Lerp(StartRotation, EndRotation, m_animFloat); } } } public class AudioConsistencyEnforcer : MonoBehaviour { [Header("Audio Profiles")] public FVRFirearmAudioSet BaseHandlingAudioProfile; private FVRFireArm _firearm; private FVRFirearmAudioSet _lastAudioClipSet; private void Awake() { _firearm = ((Component)this).GetComponent(); if ((Object)(object)_firearm != (Object)null && (Object)(object)_firearm.AudioClipSet != (Object)null) { _lastAudioClipSet = _firearm.AudioClipSet; BaseHandlingAudioProfile = ScriptableObject.CreateInstance(); SaveBaseHandlingAudio(_lastAudioClipSet); } } private void LateUpdate() { if ((Object)(object)_firearm == (Object)null) { return; } FVRFirearmAudioSet audioClipSet = _firearm.AudioClipSet; if (!((Object)(object)audioClipSet == (Object)null)) { if ((Object)(object)audioClipSet != (Object)(object)_lastAudioClipSet) { _lastAudioClipSet = audioClipSet; } EnforceHandlingSounds(audioClipSet); } } private void SaveBaseHandlingAudio(FVRFirearmAudioSet source) { BaseHandlingAudioProfile.BoltRelease = source.BoltRelease; BaseHandlingAudioProfile.BoltSlideBack = source.BoltSlideBack; BaseHandlingAudioProfile.BoltSlideForward = source.BoltSlideForward; BaseHandlingAudioProfile.BoltSlideBackHeld = source.BoltSlideBackHeld; BaseHandlingAudioProfile.BoltSlideBackLocked = source.BoltSlideBackLocked; BaseHandlingAudioProfile.BreachOpen = source.BreachOpen; BaseHandlingAudioProfile.BreachClose = source.BreachClose; BaseHandlingAudioProfile.CatchOnSear = source.CatchOnSear; BaseHandlingAudioProfile.ChamberManual = source.ChamberManual; BaseHandlingAudioProfile.FireSelector = source.FireSelector; BaseHandlingAudioProfile.HammerHit = source.HammerHit; BaseHandlingAudioProfile.HandleBack = source.HandleBack; BaseHandlingAudioProfile.HandleBackEmpty = source.HandleBackEmpty; BaseHandlingAudioProfile.HandleForward = source.HandleForward; BaseHandlingAudioProfile.HandleForwardEmpty = source.HandleForwardEmpty; BaseHandlingAudioProfile.HandleUp = source.HandleUp; BaseHandlingAudioProfile.HandleDown = source.HandleDown; BaseHandlingAudioProfile.HandleGrab = source.HandleGrab; BaseHandlingAudioProfile.Prefire = source.Prefire; BaseHandlingAudioProfile.Safety = source.Safety; BaseHandlingAudioProfile.TriggerReset = source.TriggerReset; BaseHandlingAudioProfile.TopCoverRelease = source.TopCoverRelease; BaseHandlingAudioProfile.TopCoverUp = source.TopCoverUp; BaseHandlingAudioProfile.TopCoverDown = source.TopCoverDown; BaseHandlingAudioProfile.StockOpen = source.StockOpen; BaseHandlingAudioProfile.StockClosed = source.StockClosed; BaseHandlingAudioProfile.BipodOpen = source.BipodOpen; BaseHandlingAudioProfile.BipodClosed = source.BipodClosed; BaseHandlingAudioProfile.BeltGrab = source.BeltGrab; BaseHandlingAudioProfile.BeltRelease = source.BeltRelease; BaseHandlingAudioProfile.BeltSeat = source.BeltSeat; BaseHandlingAudioProfile.BeltSettle = source.BeltSettle; } private void EnforceHandlingSounds(FVRFirearmAudioSet targetProfile) { targetProfile.BoltRelease = BaseHandlingAudioProfile.BoltRelease; targetProfile.BoltSlideBack = BaseHandlingAudioProfile.BoltSlideBack; targetProfile.BoltSlideForward = BaseHandlingAudioProfile.BoltSlideForward; targetProfile.BoltSlideBackHeld = BaseHandlingAudioProfile.BoltSlideBackHeld; targetProfile.BoltSlideBackLocked = BaseHandlingAudioProfile.BoltSlideBackLocked; targetProfile.BreachOpen = BaseHandlingAudioProfile.BreachOpen; targetProfile.BreachClose = BaseHandlingAudioProfile.BreachClose; targetProfile.CatchOnSear = BaseHandlingAudioProfile.CatchOnSear; targetProfile.ChamberManual = BaseHandlingAudioProfile.ChamberManual; targetProfile.FireSelector = BaseHandlingAudioProfile.FireSelector; targetProfile.HammerHit = BaseHandlingAudioProfile.HammerHit; targetProfile.HandleBack = BaseHandlingAudioProfile.HandleBack; targetProfile.HandleBackEmpty = BaseHandlingAudioProfile.HandleBackEmpty; targetProfile.HandleForward = BaseHandlingAudioProfile.HandleForward; targetProfile.HandleForwardEmpty = BaseHandlingAudioProfile.HandleForwardEmpty; targetProfile.HandleUp = BaseHandlingAudioProfile.HandleUp; targetProfile.HandleDown = BaseHandlingAudioProfile.HandleDown; targetProfile.HandleGrab = BaseHandlingAudioProfile.HandleGrab; targetProfile.Prefire = BaseHandlingAudioProfile.Prefire; targetProfile.Safety = BaseHandlingAudioProfile.Safety; targetProfile.TriggerReset = BaseHandlingAudioProfile.TriggerReset; targetProfile.TopCoverRelease = BaseHandlingAudioProfile.TopCoverRelease; targetProfile.TopCoverUp = BaseHandlingAudioProfile.TopCoverUp; targetProfile.TopCoverDown = BaseHandlingAudioProfile.TopCoverDown; targetProfile.StockOpen = BaseHandlingAudioProfile.StockOpen; targetProfile.StockClosed = BaseHandlingAudioProfile.StockClosed; targetProfile.BipodOpen = BaseHandlingAudioProfile.BipodOpen; targetProfile.BipodClosed = BaseHandlingAudioProfile.BipodClosed; targetProfile.BeltGrab = BaseHandlingAudioProfile.BeltGrab; targetProfile.BeltRelease = BaseHandlingAudioProfile.BeltRelease; targetProfile.BeltSeat = BaseHandlingAudioProfile.BeltSeat; targetProfile.BeltSettle = BaseHandlingAudioProfile.BeltSettle; } } public class SecondaryMagSupport : ModularBarrelExtension { [Header("Secondary Magazine Configuration")] public bool ChangesSecondaryMagazine = false; public FireArmMagazineType SecondaryMagazineType; public Transform CustomSecondaryMagMountPoint; public Transform CustomSecondaryMagEjectPoint; private FVRFireArm _firearm; private Transform _origSecMagMountPos; private Transform _origSecMagEjectPos; private FireArmMagazineType _origSecondaryMagazineType; private bool _hasCachedOriginals = false; public override void EnablePart() { ((ModularBarrelExtension)this).EnablePart(); if (UnityEngineExtensions.TryGetComponentInParent((Component)(object)((Component)this).transform, ref _firearm) && ChangesSecondaryMagazine) { CacheOriginalSecondaryMagSettings(_firearm); UpdateSecondaryMagazine(_firearm); } else { Debug.LogWarning((object)"SecondaryMagSupport: Firearm not found or ChangesSecondaryMagazine is false!"); } } public override void DisablePart() { ((ModularBarrelExtension)this).DisablePart(); if ((Object)(object)_firearm != (Object)null && ChangesSecondaryMagazine) { ResetSecondaryMagazine(_firearm); } } private void CacheOriginalSecondaryMagSettings(FVRFireArm firearm) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!_hasCachedOriginals && firearm.SecondaryMagazineSlots.Length != 0) { _origSecMagMountPos = firearm.SecondaryMagazineSlots[0].MagazineMountPos; _origSecMagEjectPos = firearm.SecondaryMagazineSlots[0].MagazineEjectPos; if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null) { _origSecondaryMagazineType = firearm.SecondaryMagazineSlots[0].Magazine.MagazineType; } _hasCachedOriginals = true; } } private void UpdateSecondaryMagazine(FVRFireArm firearm) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (firearm.SecondaryMagazineSlots.Length != 0) { firearm.SecondaryMagazineSlots[0].MagazineMountPos = CustomSecondaryMagMountPoint; firearm.SecondaryMagazineSlots[0].MagazineEjectPos = CustomSecondaryMagEjectPoint; if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null) { firearm.SecondaryMagazineSlots[0].Magazine.MagazineType = SecondaryMagazineType; } Debug.Log((object)"SecondaryMagSupport: Secondary magazine settings updated."); } } private void ResetSecondaryMagazine(FVRFireArm firearm) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (_hasCachedOriginals && firearm.SecondaryMagazineSlots.Length != 0) { firearm.SecondaryMagazineSlots[0].MagazineMountPos = _origSecMagMountPos; firearm.SecondaryMagazineSlots[0].MagazineEjectPos = _origSecMagEjectPos; if ((Object)(object)firearm.SecondaryMagazineSlots[0].Magazine != (Object)null) { firearm.SecondaryMagazineSlots[0].Magazine.MagazineType = _origSecondaryMagazineType; } Debug.Log((object)"SecondaryMagSupport: Secondary magazine settings reset."); } } } public class ObservedObjectEnabler : MonoBehaviour { [Header("Observed Target")] [Tooltip("The GameObject mesh or joint to observe.")] public Transform ObservedObject; [Header("Tracking Mode")] public bool ObservePosition = false; public bool ObserveRotation = true; [Header("Target Values")] [Tooltip("The local position target to reach.")] public Vector3 TargetPosition = Vector3.zero; [Tooltip("The local rotation target to reach (Euler angles).")] public Vector3 TargetRotation = new Vector3(90f, 0f, 0f); [Header("Tolerance Settings")] [Tooltip("Distance in meters to consider the position reached.")] public float DistanceTolerance = 0.05f; [Tooltip("Angle in degrees to consider the rotation reached.")] public float AngleTolerance = 1f; [Header("Trigger Actions")] [Tooltip("The GameObject to enable or disable when the target is reached.")] public GameObject TargetObject; [Tooltip("Should the TargetObject be set Active (true) or Inactive (false) when reached?")] public bool SetObjectActiveOnReach = true; [Tooltip("The Collider to enable or disable when the target is reached.")] public Collider TargetCollider; [Tooltip("Should the TargetCollider be set Enabled (true) or Disabled (false) when reached?")] public bool SetColliderEnabledOnReach = true; [Header("Behavior Settings")] [Tooltip("If true, the target object/collider will revert to their opposite state when the observed object moves away from the target values.")] public bool ResetWhenLeavingTarget = true; private bool m_isTargetReached = false; private bool m_hasTriggered = false; private void Update() { //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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ObservedObject == (Object)null) { return; } bool flag = true; bool flag2 = true; if (ObservePosition) { float num = Vector3.Distance(ObservedObject.localPosition, TargetPosition); flag = num <= DistanceTolerance; } if (ObserveRotation) { Quaternion localRotation = ObservedObject.localRotation; Quaternion val = Quaternion.Euler(TargetRotation); float num2 = Quaternion.Angle(localRotation, val); flag2 = num2 <= AngleTolerance; } bool flag3 = true; if (ObservePosition && !flag) { flag3 = false; } if (ObserveRotation && !flag2) { flag3 = false; } if (flag3) { if (!m_isTargetReached) { m_isTargetReached = true; if (!m_hasTriggered || ResetWhenLeavingTarget) { ApplyTriggerState(targetReached: true); m_hasTriggered = true; } } } else if (m_isTargetReached) { m_isTargetReached = false; if (ResetWhenLeavingTarget) { ApplyTriggerState(targetReached: false); m_hasTriggered = false; } } } private void ApplyTriggerState(bool targetReached) { if ((Object)(object)TargetObject != (Object)null) { bool active = ((!targetReached) ? (!SetObjectActiveOnReach) : SetObjectActiveOnReach); TargetObject.SetActive(active); } if ((Object)(object)TargetCollider != (Object)null) { bool enabled = ((!targetReached) ? (!SetColliderEnabledOnReach) : SetColliderEnabledOnReach); TargetCollider.enabled = enabled; } } } public class HeatEffectToggleObject : FirearmHeatingEffect { [Header("Explosion Spawn")] public GameObject PrefabToSpawn; public Transform SpawnPoint; public float ToggleHeatThreshold = 0.95f; private bool hasSpawned = false; public void Update() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) ((FirearmHeatingEffect)this).Update(); if (hasSpawned || !(base.Heat >= ToggleHeatThreshold)) { return; } if ((Object)(object)PrefabToSpawn != (Object)null) { if ((Object)(object)SpawnPoint != (Object)null) { Object.Instantiate(PrefabToSpawn, SpawnPoint.position, SpawnPoint.rotation); } else { Object.Instantiate(PrefabToSpawn, ((Component)this).transform.position, ((Component)this).transform.rotation); } } hasSpawned = true; } } public class MGBarrel : MuzzleDevice { [Header("MGBarrel Lock Settings")] public float CatchRot; public bool IsLocked = false; public AudioSource AudSourceLock; public AudioClip AudClipLock; public Vector3 LockedLocalPosition; public Vector3 LockedLocalEulerAngles; public float LockAngle = 90f; public bool HasPlayedLockSound = false; [Header("Loose Barrel Settings")] public int ShotsUntilFallOff = 3; [HideInInspector] public int ShotsFiredWhileLoose = 0; protected void Awake() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) ((MuzzleDevice)this).Awake(); ((FVRFireArmAttachment)this).Type = (FVRFireArmAttachementMountType)2; } public override void AttachToMount(FVRFireArmAttachmentMount m, bool playSound) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) ((FVRFireArmAttachment)this).AttachToMount(m, playSound); ((Component)this).transform.localEulerAngles = new Vector3(0f, 0f, CatchRot); } public override void OnShot(FVRFireArm f, FVRTailSoundClass tailClass) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!IsLocked && (Object)(object)((FVRFireArmAttachment)this).curMount != (Object)null) { ShotsFiredWhileLoose++; if (ShotsFiredWhileLoose >= ShotsUntilFallOff) { ((FVRFireArmAttachment)this).DetachFromMount(); } } else { ShotsFiredWhileLoose = 0; } ((MuzzleDevice)this).OnShot(f, tailClass); } } public class MGBarrelInterface : MuzzleDeviceInterface { private MGBarrel tempBarrel; private Vector3 lastHandForward = Vector3.zero; private Vector3 lastMountForward = Vector3.zero; public AudioClip AudClipUnlock; public AudioSource AudSourceUnlock; private const float lockThreshold = 2f; private const float unlockThreshold = 2f; private float lockCooldownTime = 0f; private float lockCooldownTimer = 0f; public float LockSnapBuffer = 3f; public float LockedPreventDetachTime = 0.35f; private float lockedGraceTimer = 0f; public float UnlockAllowDetachTime = 0.5f; private float canBePulledTimer = 0f; private Vector3 mountedLocalPosition = Vector3.zero; private bool mountedLocalPositionRecorded = false; public float DetachDistanceThreshold = 0.08f; private bool m_isInSnappingMode = false; private bool hasPlayedUnlockSoundThisUnlock = false; public float IgnoreDetachOnGrabTime = 0.12f; private float ignoreDetachTimer = 0f; public override void Awake() { ((FVRFireArmAttachmentInterface)this).Awake(); tempBarrel = ((FVRFireArmAttachmentInterface)this).Attachment as MGBarrel; } public override void OnAttach() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) ((MuzzleDeviceInterface)this).OnAttach(); tempBarrel = ((FVRFireArmAttachmentInterface)this).Attachment as MGBarrel; if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) { mountedLocalPosition = ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition; mountedLocalPositionRecorded = true; ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, (!((Object)(object)tempBarrel != (Object)null)) ? 0f : tempBarrel.CatchRot); } if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null && ((FVRInteractiveObject)this).IsHeld && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null) { SetSnapping(b: true); lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up; lastMountForward = ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up; lockCooldownTimer = 0f; lockedGraceTimer = 0f; canBePulledTimer = 0f; hasPlayedUnlockSoundThisUnlock = false; TryLockImmediateOnAttach(); } } private void TryLockImmediateOnAttach() { if ((Object)(object)tempBarrel == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount == (Object)null) { return; } float lockAngle = tempBarrel.LockAngle; float num = 2f + LockSnapBuffer; if (tempBarrel.IsLocked) { return; } if (lockAngle >= 0f) { if (tempBarrel.CatchRot >= lockAngle - num) { DoLock(lockAngle); } } else if (tempBarrel.CatchRot <= lockAngle + num) { DoLock(lockAngle); } } private void DoLock(float target) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) tempBarrel.CatchRot = target; tempBarrel.IsLocked = true; lockedGraceTimer = LockedPreventDetachTime; lockCooldownTimer = lockCooldownTime; if (mountedLocalPositionRecorded) { ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition + tempBarrel.LockedLocalPosition; } else { ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition + tempBarrel.LockedLocalPosition; } ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, target); if (!tempBarrel.HasPlayedLockSound && (Object)(object)tempBarrel.AudSourceLock != (Object)null && (Object)(object)tempBarrel.AudClipLock != (Object)null) { tempBarrel.AudSourceLock.PlayOneShot(tempBarrel.AudClipLock); tempBarrel.HasPlayedLockSound = true; } canBePulledTimer = 0f; hasPlayedUnlockSoundThisUnlock = false; } private void DoUnlock() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) tempBarrel.IsLocked = false; tempBarrel.HasPlayedLockSound = false; tempBarrel.CatchRot = 0f; ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, 0f); if (mountedLocalPositionRecorded) { ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition; } canBePulledTimer = UnlockAllowDetachTime; if (!hasPlayedUnlockSoundThisUnlock && (Object)(object)AudSourceUnlock != (Object)null && (Object)(object)AudClipUnlock != (Object)null) { AudSourceUnlock.PlayOneShot(AudClipUnlock); hasPlayedUnlockSoundThisUnlock = true; } } public override void OnDetach() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tempBarrel != (Object)null && mountedLocalPositionRecorded && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) { ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localPosition = mountedLocalPosition; } if ((Object)(object)tempBarrel != (Object)null) { tempBarrel.IsLocked = false; tempBarrel.HasPlayedLockSound = false; tempBarrel.CatchRot = 0f; } ((MuzzleDeviceInterface)this).OnDetach(); mountedLocalPositionRecorded = false; canBePulledTimer = 0f; hasPlayedUnlockSoundThisUnlock = false; } public override void BeginInteraction(FVRViveHand hand) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ((FVRInteractiveObject)this).BeginInteraction(hand); lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up; lastMountForward = ((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? Vector3.up : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up); lockCooldownTimer = 0f; lockedGraceTimer = 0f; canBePulledTimer = 0f; hasPlayedUnlockSoundThisUnlock = false; ignoreDetachTimer = IgnoreDetachOnGrabTime; } public override void UpdateInteraction(FVRViveHand hand) { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: 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_02c9: 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_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) ((FVRFireArmAttachmentInterface)this).UpdateInteraction(hand); if (lockedGraceTimer > 0f) { lockedGraceTimer -= Time.deltaTime; if (lockedGraceTimer < 0f) { lockedGraceTimer = 0f; } } if (lockCooldownTimer > 0f) { lockCooldownTimer -= Time.deltaTime; if (lockCooldownTimer < 0f) { lockCooldownTimer = 0f; } } if (canBePulledTimer > 0f) { canBePulledTimer -= Time.deltaTime; if (canBePulledTimer <= 0f) { canBePulledTimer = 0f; } } if (ignoreDetachTimer > 0f) { ignoreDetachTimer -= Time.deltaTime; if (ignoreDetachTimer < 0f) { ignoreDetachTimer = 0f; } } UpdateSnappingBasedOnDistance(); if (((FVRInteractiveObject)this).IsHeld && (Object)(object)tempBarrel != (Object)null) { ((Component)((FVRFireArmAttachmentInterface)this).Attachment).transform.localEulerAngles = new Vector3(0f, 0f, tempBarrel.CatchRot); } if ((Object)(object)tempBarrel == (Object)null) { return; } float lockAngle = tempBarrel.LockAngle; float num = 2f + LockSnapBuffer; if (!tempBarrel.IsLocked) { if (lockAngle >= 0f) { if (tempBarrel.CatchRot >= lockAngle - num) { DoLock(lockAngle); } } else if (tempBarrel.CatchRot <= lockAngle + num) { DoLock(lockAngle); } } else if (Mathf.Abs(tempBarrel.CatchRot) <= 2f && lockedGraceTimer <= 0f) { DoUnlock(); } if (tempBarrel.IsLocked || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) { return; } FVRFireArmAttachmentMount rootMount = ((FVRFireArmAttachmentInterface)this).Attachment.curMount.GetRootMount(); Transform val = ((!((Object)(object)rootMount != (Object)null) || !(rootMount.MyObject is FVRFireArm)) ? null : ((FVRFireArm)rootMount.MyObject).MuzzlePos); if (!((Object)(object)val != (Object)null)) { return; } Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Front.position, val.position, ((Component)this).transform.position); float num2 = Vector3.Distance(((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Pos, closestValidPoint); if (canBePulledTimer > 0f) { if (num2 > DetachDistanceThreshold) { canBePulledTimer = 0f; ((FVRInteractiveObject)this).EndInteraction(hand); hand.ForceSetInteractable((FVRInteractiveObject)(object)((FVRFireArmAttachmentInterface)this).Attachment); ((FVRInteractiveObject)((FVRFireArmAttachmentInterface)this).Attachment).BeginInteraction(hand); } } else if (ignoreDetachTimer <= 0f && num2 > DetachDistanceThreshold) { ((FVRInteractiveObject)this).EndInteraction(hand); hand.ForceSetInteractable((FVRInteractiveObject)(object)((FVRFireArmAttachmentInterface)this).Attachment); ((FVRInteractiveObject)((FVRFireArmAttachmentInterface)this).Attachment).BeginInteraction(hand); } } public override void FVRFixedUpdate() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tempBarrel == (Object)null) { ((FVRInteractiveObject)this).FVRFixedUpdate(); return; } if (((FVRInteractiveObject)this).IsHeld && m_isInSnappingMode && lockCooldownTimer <= 0f && lockedGraceTimer <= 0f) { Vector3 val = Vector3.ProjectOnPlane(((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up, ((Component)this).transform.forward); Vector3 val2 = Vector3.ProjectOnPlane(lastHandForward, ((Component)this).transform.forward); float num = Mathf.Atan2(Vector3.Dot(((Component)this).transform.forward, Vector3.Cross(val, val2)), Vector3.Dot(val, val2)) * 57.29578f; Vector3 val3 = Vector3.ProjectOnPlane((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? Vector3.up : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up, ((Component)this).transform.forward); Vector3 val4 = Vector3.ProjectOnPlane(lastMountForward, ((Component)this).transform.forward); float num2 = Mathf.Atan2(Vector3.Dot(((Component)this).transform.forward, Vector3.Cross(val3, val4)), Vector3.Dot(val3, val4)) * 57.29578f; tempBarrel.CatchRot -= num; tempBarrel.CatchRot += num2; float lockAngle = tempBarrel.LockAngle; float num3 = Mathf.Min(0f, lockAngle); float num4 = Mathf.Max(0f, lockAngle); tempBarrel.CatchRot = Mathf.Clamp(tempBarrel.CatchRot, num3, num4); lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up; lastMountForward = ((!((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null) || !((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null)) ? lastMountForward : ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up); } ((FVRInteractiveObject)this).FVRFixedUpdate(); } public override void EndInteraction(FVRViveHand hand) { if (!tempBarrel.IsLocked && Mathf.Abs(tempBarrel.CatchRot) <= 2f && lockedGraceTimer <= 0f) { ((FVRInteractiveObject)this).EndInteraction(hand); } } private void UpdateSnappingBasedOnDistance() { //IL_005e: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment == (Object)null || (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount == (Object)null) { SetSnapping(b: false); return; } if (((FVRInteractiveObject)this).IsHeld) { SetSnapping(b: true); return; } Vector3 closestValidPoint = ((FVRInteractiveObject)this).GetClosestValidPoint(((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Front.position, ((FVRFireArmAttachmentInterface)this).Attachment.curMount.Point_Rear.position, ((Component)this).transform.position); if (Vector3.Distance(closestValidPoint, ((Component)this).transform.position) < DetachDistanceThreshold || ((Object)(object)tempBarrel != (Object)null && Mathf.Abs(tempBarrel.CatchRot) > 1f)) { SetSnapping(b: true); } else { SetSnapping(b: false); } } private void SetSnapping(bool b) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (m_isInSnappingMode == b) { return; } m_isInSnappingMode = b; if (m_isInSnappingMode) { ((FVRInteractiveObject)this).SetAllCollidersToLayer(false, "NoCol"); if ((Object)(object)((FVRInteractiveObject)this).m_hand != (Object)null) { lastHandForward = ((HandInput)(ref ((FVRInteractiveObject)this).m_hand.Input)).Up; } if ((Object)(object)((FVRFireArmAttachmentInterface)this).Attachment != (Object)null && (Object)(object)((FVRFireArmAttachmentInterface)this).Attachment.curMount != (Object)null) { lastMountForward = ((Component)((FVRFireArmAttachmentInterface)this).Attachment.curMount).transform.up; } } else { ((FVRInteractiveObject)this).SetAllCollidersToLayer(false, "Default"); } } } namespace Volks.ModulSKS_Redux; [BepInPlugin("Volks.ModulSKS_Redux", "ModulSKS_Redux", "1.0.0")] [BepInProcess("h3vr.exe")] [Description("Built with MeatKit")] [BepInDependency("h3vr.otherloader", "1.3.0")] [BepInDependency("h3vr.cityrobo.ModularWorkshopManager", "1.0.0")] [BepInDependency("nrgill28.Sodalite", "1.4.2")] public class ModulSKS_ReduxPlugin : BaseUnityPlugin { private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); internal static ManualLogSource Logger; private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; LoadAssets(); } private void LoadAssets() { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Volks.ModulSKS_Redux"); OtherLoader.RegisterDirectLoad(BasePath, "Volks.ModulSKS_Redux", "", "", "modulsks_redux", ""); GameAPI.PreloadAllAssets(Path.Combine(BasePath, "mw_modulsks_redux")); } } [RequireComponent(typeof(FVRFireArmMagazine))] public class BeltMagazinePhysics : MonoBehaviour { [Header("Debugging")] [Tooltip("Enable to print diagnostic logs to the BepInEx / Unity developer console.")] public bool EnableDebug = false; [Header("Compatibility")] [Tooltip("If checked, the belt will bypass all magazine type checks and attempt to load into ANY belt-fed gun.")] public bool BypassTypeMatching = false; [Tooltip("Allows this belt to load into weapons of specific MagazineType enums (e.g. base-game M249 types).")] public FireArmMagazineType[] CompatibleMagazineTypes; [Header("Belt Chain")] [Tooltip("The point where the belt exits the magazine when NOT loaded. Its forward axis defines the exit direction.")] public Transform BeltExitPoint; [Tooltip("Number of physics nodes rigidly locked along the anchor's exit axis before free simulation begins. Increase this to prevent sagging into the gun.")] public int PinnedNodes = 3; [Tooltip("Total number of simulation nodes in the chain. More = smoother but more expensive.")] public int ChainNodeCount = 8; [Tooltip("Distance between each chain node in metres. Set this to match your link spacing (e.g., 0.018 to 0.02 for 5.56 ammo).")] public float NodeDistance = 0.02f; [Tooltip("Velocity damping per frame when NOT loaded. Lower values (e.g. 0.90) make the belt stiffer and reduce swinging.")] [Range(0f, 1f)] public float Damping = 0.95f; [Tooltip("Gravity scale applied to chain nodes.")] public float GravityScale = 1f; [Tooltip("Number of constraint solving iterations per frame. More = more stable.")] public int ConstraintIterations = 3; [Header("Loaded Physics Override")] [Range(0f, 1f)] [Tooltip("How rigid the belt becomes when loaded into the gun. 0 = fully floppy world physics, 1 = completely frozen straight. Adjust this to eliminate physics jitter when moving with the gun.")] public float LoadedRigidity = 0.5f; [Range(0f, 1f)] [Tooltip("Damping applied strictly when the belt is loaded into the gun. Lower values (e.g. 0.80) heavily slow down the swinging and absorb movement jitter.")] public float LoadedDamping = 0.9f; [Header("Bending Stiffness")] [Range(0f, 1f)] [Tooltip("How much the belt resists folding/bending. Higher values (e.g. 0.7) make the belt hang like a heavy, rigid metal belt rather than floppy cloth. Prevents wild swinging with zero jitter.")] public float BendingStiffness = 0.6f; [Header("Bullet Orientation & Constraints")] [Tooltip("Euler rotation offset applied strictly to the flat bullets sitting on the gun's feed tray.")] public Vector3 FeedTrayRotationOffset = Vector3.zero; [Tooltip("Euler rotation offset applied strictly to the dangling/simulated bullets hanging down.")] public Vector3 HangingRotationOffset = Vector3.zero; [Tooltip("The name of the child GameObject inside your bullet prefab that represents the metal link (case-insensitive). If found, only the link will bend, while the cartridge stays parallel.")] public string LinkChildName = "link"; [Tooltip("The local direction of the gun's proxy round that the hanging belt should flow out from.")] public Vector3 LoadedExitDirection = new Vector3(-1f, 0f, 0f); [Tooltip("The local direction the belt exits from when NOT loaded (held in hand). Lies on the local X-Y plane to prevent squashing.")] public Vector3 UnloadedExitDirection = new Vector3(0f, -1f, 0f); [Header("Snapped Feed Tray Rounds")] [Tooltip("How many bullets sit rigidly flat on the gun's top feed tray cover before the belt hangs down dynamically. (Usually 3 to 5 on an M249).")] public int SnappedFeedTrayRounds = 4; [Header("Loading")] [Tooltip("Detection radius around BeltExitPoint for feed tray detection.")] public float LoadDetectionRadius = 0.12f; [Tooltip("After ejecting or removing the belt, how many seconds to wait before it can be loaded again. Prevents instant re-insertion.")] public float ReinsertCooldown = 1f; private FVRFireArmMagazine _magazine; private Vector3[] _positions; private Vector3[] _prevPositions; private bool _chainInitialized = false; private bool _wasLoadedLastFrame = false; private FVRFireArm _lastLoadedFireArm = null; private float _cooldownTimer = 0f; private void Awake() { _magazine = ((Component)this).GetComponent(); if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Awake called on custom belt."); } _magazine.HidesAllDisplayBulletsWhenGrabbed = false; FVRFireArmReloadTriggerMag[] componentsInChildren = ((Component)this).GetComponentsInChildren(); if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Found " + componentsInChildren.Length + " FVRFireArmReloadTriggerMag components to disable.")); } FVRFireArmReloadTriggerMag[] array = componentsInChildren; foreach (FVRFireArmReloadTriggerMag val in array) { if (!((Object)(object)val != (Object)null)) { continue; } ((Behaviour)val).enabled = false; Collider component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Successfully disabled trigger well collider on sub-object: " + ((Object)val).name)); } } } } private void Start() { InitChain(); } private void OnEnable() { if (_chainInitialized) { InitChain(); } } private void FixedUpdate() { if (_cooldownTimer > 0f) { _cooldownTimer -= Time.fixedDeltaTime; } else { _cooldownTimer = 0f; } if (_cooldownTimer <= 0f) { HandleFeedTrayDetection(); } if ((Object)(object)_magazine.FireArm != (Object)null) { _magazine.FireArm.ConnectedToBox = true; _magazine.FireArm.HasBelt = true; } if (_chainInitialized) { UpdateChain(); } } private void Update() { if ((Object)(object)_magazine != (Object)null && (Object)(object)_magazine.FireArm != (Object)null) { _magazine.FireArm.ConnectedToBox = true; _magazine.FireArm.HasBelt = true; } } private void HandleFeedTrayDetection() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Invalid comparison between Unknown and I4 //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: 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_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) if (!((FVRInteractiveObject)_magazine).IsHeld || (int)_magazine.State != 0 || (Object)(object)BeltExitPoint == (Object)null) { return; } float num = 0.25f; Collider[] array = Physics.OverlapSphere(BeltExitPoint.position, num, -1, (QueryTriggerInteraction)2); Collider[] array2 = array; foreach (Collider val in array2) { FVRFireArm componentInParent = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || !componentInParent.UsesBelts || (Object)(object)componentInParent.BeltDD == (Object)null || (Object)(object)componentInParent.Magazine != (Object)null) { continue; } bool flag = !componentInParent.UsesTopCover || componentInParent.IsTopCoverUp; if (componentInParent.UsesTopCover && !flag) { FVRFireArmTopCover componentInChildren = ((Component)componentInParent).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { float num2 = ((Component)componentInChildren).transform.localEulerAngles.x; if (num2 > 180f) { num2 -= 360f; } if (Mathf.Abs(num2) > 15f || ((FVRInteractiveObject)componentInChildren).IsHeld) { flag = true; } } else { flag = true; if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Gun uses top cover, but FVRFireArmTopCover component was not found in hierarchy. Defaulting to Open."); } } } if (!flag) { if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Found gun " + ((Object)componentInParent).name + ", but top cover is closed. Cannot load.")); } continue; } FireArmMagazineType val2 = componentInParent.MagazineType; FVRFireArmReloadTriggerWell[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren(true); FVRFireArmReloadTriggerWell[] array3 = componentsInChildren; foreach (FVRFireArmReloadTriggerWell val3 in array3) { if ((Object)(object)val3 != (Object)null && ((_magazine.IsBeltBox && val3.IsBeltBox) || (val3.UsesTypeOverride && val3.TypeOverride == _magazine.MagazineType))) { val2 = val3.TypeOverride; break; } } bool flag2 = BypassTypeMatching || val2 == _magazine.MagazineType; if (!flag2 && CompatibleMagazineTypes != null) { for (int k = 0; k < CompatibleMagazineTypes.Length; k++) { if ((int)val2 == (int)CompatibleMagazineTypes[k]) { flag2 = true; break; } } } if (!flag2) { if (EnableDebug) { Debug.Log((object)string.Concat("[BeltPhysicsDebug] Type Mismatch! Gun expects: ", val2, ", but this belt is: ", _magazine.MagazineType, ".")); } } else { if (componentInParent.EjectDelay > 0f && (Object)(object)_magazine == (Object)(object)componentInParent.LastEjectedMag) { continue; } Vector3 val4 = Vector3.zero; bool flag3 = false; List proxyRounds = componentInParent.BeltDD.ProxyRounds; if (proxyRounds != null && proxyRounds.Count > 0 && (Object)(object)proxyRounds[0] != (Object)null) { val4 = proxyRounds[0].position; flag3 = true; } else { FVRFireArmBeltRemovalTrigger componentInChildren2 = ((Component)componentInParent).GetComponentInChildren(true); if ((Object)(object)componentInChildren2 != (Object)null) { val4 = ((Component)componentInChildren2).transform.position; flag3 = true; } } if (!flag3) { FVRFireArmTopCover componentInChildren3 = ((Component)componentInParent).GetComponentInChildren(true); if ((Object)(object)componentInChildren3 != (Object)null) { val4 = ((Component)componentInChildren3).transform.position; flag3 = true; } } if (!flag3) { continue; } float num3 = Vector3.Distance(BeltExitPoint.position, val4); if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Found Compatible Gun: " + ((Object)componentInParent).name + " | Distance to Feed Tray Trigger: " + num3 + "m")); } if (num3 <= LoadDetectionRadius) { if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Loading belt directly into feed tray trigger of " + ((Object)componentInParent).name + "!")); } _magazine.Load(componentInParent); break; } } } } private void LateUpdate() { //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) if (!_chainInitialized) { return; } bool flag = (Object)(object)_magazine.FireArm != (Object)null; int num = _magazine.m_numRounds; if (flag && (Object)(object)_magazine.FireArm.BeltDD != (Object)null) { num += _magazine.FireArm.BeltDD.m_roundsOnBelt; } if (flag && num == 0) { if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Belt is completely empty. Auto-ejecting and deleting empty belt GameObject!"); } FVRFireArm fireArm = _magazine.FireArm; SetGunProxyRenderersEnabled(enabled: true, fireArm); if ((Object)(object)fireArm.BeltDD != (Object)null) { fireArm.ConnectedToBox = false; fireArm.HasBelt = false; fireArm.BeltDD.PullPushBelt((FVRFireArmMagazine)null, 0); } fireArm.EjectMag(true); Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (flag && !_wasLoadedLastFrame) { if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Belt just loaded into weapon. Bypassing ForceMount bug, disabling static proxies and setting colliders to 'NoCol'."); } FVRFireArm fireArm2 = _magazine.FireArm; if ((Object)(object)fireArm2.BeltDD != (Object)null) { fireArm2.ConnectedToBox = true; fireArm2.HasBelt = true; fireArm2.BeltDD.PullPushBelt(_magazine, fireArm2.BeltDD.BeltCapacity); } SetGunProxyRenderersEnabled(enabled: false, fireArm2); ((FVRInteractiveObject)_magazine).SetAllCollidersToLayer(false, "NoCol"); _lastLoadedFireArm = fireArm2; _wasLoadedLastFrame = true; } else if (!flag && _wasLoadedLastFrame) { if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Belt just removed from weapon. Re-enabling static proxies and restoring colliders to 'Default'."); } if ((Object)(object)_lastLoadedFireArm != (Object)null && (Object)(object)_lastLoadedFireArm.BeltDD != (Object)null) { _lastLoadedFireArm.BeltDD.PullPushBelt(_magazine, 0); _lastLoadedFireArm.ConnectedToBox = false; _lastLoadedFireArm.HasBelt = false; _lastLoadedFireArm.BeltDD.PullPushBelt((FVRFireArmMagazine)null, 0); } _lastLoadedFireArm = null; ((FVRInteractiveObject)_magazine).SetAllCollidersToLayer(false, "Default"); _wasLoadedLastFrame = false; } if (flag && (Object)(object)_magazine.BeltGrabTrigger != (Object)null && ((FVRInteractiveObject)_magazine.BeltGrabTrigger).IsHeld) { if (EnableDebug) { Debug.Log((object)"[BeltPhysicsDebug] Hand grab detected on BeltGrabTrigger! Ejecting belt cleanly."); } FVRViveHand hand = ((FVRInteractiveObject)_magazine.BeltGrabTrigger).m_hand; if ((Object)(object)hand != (Object)null) { FVRFireArm fireArm3 = _magazine.FireArm; if ((Object)(object)fireArm3.BeltDD != (Object)null) { fireArm3.BeltDD.PullPushBelt(_magazine, 0); } fireArm3.EjectMag(false); ((FVRInteractiveObject)_magazine.BeltGrabTrigger).ForceBreakInteraction(); hand.ForceSetInteractable((FVRInteractiveObject)(object)_magazine); ((FVRInteractiveObject)_magazine).BeginInteraction(hand); flag = false; } } if (flag && (Object)(object)_magazine.FireArm != (Object)null) { _magazine.FireArm.ConnectedToBox = true; _magazine.FireArm.HasBelt = true; } if (flag) { Transform anchorTransform = GetAnchorTransform(); if ((Object)(object)anchorTransform != (Object)null) { ((Component)this).transform.position = anchorTransform.position; ((Component)this).transform.rotation = ((Component)_magazine.FireArm).transform.rotation; } } PositionBullets(); } private void InitChain() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) _positions = (Vector3[])(object)new Vector3[ChainNodeCount]; _prevPositions = (Vector3[])(object)new Vector3[ChainNodeCount]; Vector3 val = ((!((Object)(object)BeltExitPoint != (Object)null)) ? ((Component)this).transform.position : BeltExitPoint.position); Vector3 val2 = ((!((Object)(object)BeltExitPoint != (Object)null)) ? Vector3.down : BeltExitPoint.TransformDirection(((Vector3)(ref UnloadedExitDirection)).normalized)); for (int i = 0; i < ChainNodeCount; i++) { ref Vector3 reference = ref _positions[i]; reference = val + val2 * (NodeDistance * (float)i); ref Vector3 reference2 = ref _prevPositions[i]; reference2 = _positions[i]; } _chainInitialized = true; if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Verlet Chain initialized with " + ChainNodeCount + " nodes.")); } } private void UpdateChain() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: 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_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: 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_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031c: 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_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) Transform anchorTransform = GetAnchorTransform(); if ((Object)(object)anchorTransform == (Object)null) { return; } bool flag = (Object)(object)((FVRPhysicalObject)_magazine).QuickbeltSlot != (Object)null; Vector3 position = anchorTransform.position; Vector3 val = ((!((Object)(object)_magazine.FireArm != (Object)null)) ? anchorTransform.TransformDirection(((Vector3)(ref UnloadedExitDirection)).normalized) : anchorTransform.TransformDirection(((Vector3)(ref LoadedExitDirection)).normalized)); int num = Mathf.Clamp(PinnedNodes, 1, ChainNodeCount); if (flag) { for (int i = 0; i < ChainNodeCount; i++) { ref Vector3 reference = ref _positions[i]; reference = position + val * (NodeDistance * (float)i); ref Vector3 reference2 = ref _prevPositions[i]; reference2 = _positions[i]; } return; } for (int j = 0; j < num; j++) { ref Vector3 reference3 = ref _positions[j]; reference3 = position + val * (NodeDistance * (float)j); ref Vector3 reference4 = ref _prevPositions[j]; reference4 = _positions[j]; } float num2 = ((!((Object)(object)_magazine.FireArm != (Object)null)) ? Damping : LoadedDamping); float fixedDeltaTime = Time.fixedDeltaTime; for (int k = num; k < ChainNodeCount; k++) { Vector3 val2 = (_positions[k] - _prevPositions[k]) * num2; ref Vector3 reference5 = ref _prevPositions[k]; reference5 = _positions[k]; ref Vector3 reference6 = ref _positions[k]; reference6 += val2 + Physics.gravity * GravityScale * fixedDeltaTime * fixedDeltaTime; } for (int l = 0; l < ConstraintIterations; l++) { for (int m = 0; m < num; m++) { ref Vector3 reference7 = ref _positions[m]; reference7 = position + val * (NodeDistance * (float)m); } for (int n = 0; n < ChainNodeCount - 1; n++) { if (n + 1 < num) { continue; } Vector3 val3 = _positions[n + 1] - _positions[n]; float magnitude = ((Vector3)(ref val3)).magnitude; if (!(magnitude < 0.0001f)) { float num3 = (magnitude - NodeDistance) / magnitude; if (n < num) { ref Vector3 reference8 = ref _positions[n + 1]; reference8 -= val3 * num3; continue; } ref Vector3 reference9 = ref _positions[n]; reference9 += val3 * num3 * 0.5f; ref Vector3 reference10 = ref _positions[n + 1]; reference10 -= val3 * num3 * 0.5f; } } for (int num4 = num; num4 < ChainNodeCount; num4++) { Vector3 val4 = anchorTransform.InverseTransformPoint(_positions[num4]); val4.z = 0f; ref Vector3 reference11 = ref _positions[num4]; reference11 = anchorTransform.TransformPoint(val4); } for (int num5 = 0; num5 < ChainNodeCount - 2; num5++) { if (num5 + 2 < num) { continue; } Vector3 val5 = _positions[num5 + 2] - _positions[num5]; float magnitude2 = ((Vector3)(ref val5)).magnitude; float num6 = NodeDistance * 2f; if (!(magnitude2 < 0.0001f)) { float num7 = (magnitude2 - num6) / magnitude2; if (num5 < num) { ref Vector3 reference12 = ref _positions[num5 + 2]; reference12 -= val5 * num7 * BendingStiffness; continue; } ref Vector3 reference13 = ref _positions[num5]; reference13 += val5 * num7 * BendingStiffness * 0.5f; ref Vector3 reference14 = ref _positions[num5 + 2]; reference14 -= val5 * num7 * BendingStiffness * 0.5f; } } } if ((Object)(object)_magazine.FireArm != (Object)null && LoadedRigidity > 0f) { for (int num8 = num; num8 < ChainNodeCount; num8++) { Vector3 val6 = position + val * (NodeDistance * (float)num8); ref Vector3 reference15 = ref _positions[num8]; reference15 = Vector3.Lerp(_positions[num8], val6, LoadedRigidity); } } } private Transform GetLinkChild(Transform bulletParent) { if ((Object)(object)bulletParent == (Object)null || string.IsNullOrEmpty(LinkChildName)) { return null; } for (int i = 0; i < bulletParent.childCount; i++) { Transform child = bulletParent.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name.ToLower().Contains(LinkChildName.ToLower())) { return child; } } return null; } private void PositionBullets() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: 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_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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_03b8: 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_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: 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_037d: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: 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_029a: 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_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0471: 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_0474: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: 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_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: 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) if (_magazine.DisplayBullets == null || _magazine.DisplayBullets.Length == 0) { return; } Quaternion val = Quaternion.Euler(FeedTrayRotationOffset); Quaternion val2 = Quaternion.Euler(HangingRotationOffset); Transform anchorTransform = GetAnchorTransform(); if ((Object)(object)anchorTransform == (Object)null) { return; } Vector3 val3 = ((!((Object)(object)_magazine.FireArm != (Object)null)) ? anchorTransform.TransformDirection(((Vector3)(ref UnloadedExitDirection)).normalized) : anchorTransform.TransformDirection(((Vector3)(ref LoadedExitDirection)).normalized)); List list = ((!((Object)(object)_magazine.FireArm != (Object)null) || !((Object)(object)_magazine.FireArm.BeltDD != (Object)null)) ? null : _magazine.FireArm.BeltDD.ProxyRounds); int num = 0; if ((Object)(object)_magazine.FireArm != (Object)null && list != null) { num = Mathf.Min(new int[3] { SnappedFeedTrayRounds, _magazine.FireArm.BeltDD.m_roundsOnBelt, list.Count }); } int num2 = _magazine.m_numRounds; if ((Object)(object)_magazine.FireArm != (Object)null && (Object)(object)_magazine.FireArm.BeltDD != (Object)null) { num2 += _magazine.FireArm.BeltDD.m_roundsOnBelt; } int num3 = 0; Quaternion val4 = ((Component)_magazine).transform.rotation * val2; Quaternion rotation = ((!((Object)(object)_magazine.FireArm != (Object)null)) ? (anchorTransform.rotation * val) : (((Component)_magazine.FireArm).transform.rotation * val)); for (int i = 0; i < _magazine.DisplayBullets.Length; i++) { if ((Object)(object)_magazine.DisplayBullets[i] == (Object)null) { continue; } bool flag = num3 < num2; _magazine.DisplayBullets[i].SetActive(flag); if (!flag) { continue; } if (num3 < num && list != null && num3 < list.Count && (Object)(object)list[num3] != (Object)null) { Transform val5 = list[num3]; _magazine.DisplayBullets[i].transform.position = val5.position; _magazine.DisplayBullets[i].transform.rotation = rotation; Transform linkChild = GetLinkChild(_magazine.DisplayBullets[i].transform); if ((Object)(object)linkChild != (Object)null) { linkChild.localRotation = Quaternion.identity; } } else { int num4 = num3 - num; if (num4 >= ChainNodeCount) { num4 = ChainNodeCount - 1; } _magazine.DisplayBullets[i].transform.position = _positions[num4]; Transform linkChild2 = GetLinkChild(_magazine.DisplayBullets[i].transform); Vector3 normalized; if (num4 < ChainNodeCount - 1) { Vector3 val6 = _positions[num4 + 1] - _positions[num4]; normalized = ((Vector3)(ref val6)).normalized; } else { Vector3 val7 = _positions[num4] - _positions[Mathf.Max(num4 - 1, 0)]; normalized = ((Vector3)(ref val7)).normalized; } if ((Object)(object)linkChild2 != (Object)null) { _magazine.DisplayBullets[i].transform.rotation = val4; if (normalized != Vector3.zero) { Quaternion val8 = Quaternion.FromToRotation(val3, normalized); Quaternion val9 = val8 * val4; linkChild2.rotation = Quaternion.Slerp(linkChild2.rotation, val9, Time.deltaTime * 20f); } } else if (normalized != Vector3.zero) { Quaternion val10 = Quaternion.FromToRotation(val3, normalized); Quaternion val11 = val10 * val4; _magazine.DisplayBullets[i].transform.rotation = Quaternion.Slerp(_magazine.DisplayBullets[i].transform.rotation, val11, Time.deltaTime * 20f); } } num3++; } } private Transform GetAnchorTransform() { if ((Object)(object)_magazine.FireArm != (Object)null && (Object)(object)_magazine.FireArm.BeltDD != (Object)null && _magazine.FireArm.BeltDD.ProxyRounds != null) { List proxyRounds = _magazine.FireArm.BeltDD.ProxyRounds; int roundsOnBelt = _magazine.FireArm.BeltDD.m_roundsOnBelt; int num = Mathf.Clamp(SnappedFeedTrayRounds - 1, 0, proxyRounds.Count - 1); if (num >= 0 && num < proxyRounds.Count && (Object)(object)proxyRounds[num] != (Object)null) { return proxyRounds[num]; } } return BeltExitPoint; } private void SetGunProxyRenderersEnabled(bool enabled, FVRFireArm gunContext) { if ((Object)(object)gunContext == (Object)null || (Object)(object)gunContext.BeltDD == (Object)null || gunContext.BeltDD.ProxyRounds == null) { return; } List proxyRounds = gunContext.BeltDD.ProxyRounds; if (EnableDebug) { Debug.Log((object)("[BeltPhysicsDebug] Toggling renderers of " + proxyRounds.Count + " gun proxies to: " + enabled)); } for (int i = 0; i < proxyRounds.Count; i++) { if (!((Object)(object)proxyRounds[i] != (Object)null)) { continue; } Renderer[] componentsInChildren = ((Component)proxyRounds[i]).GetComponentsInChildren(); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null) { componentsInChildren[j].enabled = enabled; } } } } [ContextMenu("Reset Chain")] public void ResetChain() { //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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)BeltExitPoint == (Object)null) && _positions != null) { Vector3 forward = BeltExitPoint.forward; for (int i = 0; i < ChainNodeCount; i++) { ref Vector3 reference = ref _positions[i]; reference = BeltExitPoint.position + forward * (NodeDistance * (float)i); ref Vector3 reference2 = ref _prevPositions[i]; reference2 = _positions[i]; } } } private void OnDrawGizmos() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_0141: 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_00c4: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)BeltExitPoint == (Object)null)) { Vector3 position = BeltExitPoint.position; Vector3 forward = BeltExitPoint.forward; bool flag = _chainInitialized && Application.isPlaying; int num = Mathf.Clamp(PinnedNodes, 1, ChainNodeCount); Gizmos.color = Color.green; Gizmos.DrawSphere(position, 0.01f); Gizmos.color = new Color(0f, 1f, 0f, 0.15f); Gizmos.DrawSphere(position, LoadDetectionRadius); Vector3 val = position; for (int i = 1; i < ChainNodeCount; i++) { Vector3 val2 = ((!flag) ? (position + forward * (NodeDistance * (float)i)) : (position + _positions[i])); Gizmos.color = ((i >= num) ? Color.yellow : Color.green); Gizmos.DrawLine(val, val2); Gizmos.color = ((i >= num) ? Color.cyan : Color.green); Gizmos.DrawSphere(val2, 0.005f); val = val2; } Gizmos.color = Color.red; Gizmos.DrawSphere(val, 0.008f); } } } public class MagazineLoadToggle : MonoBehaviour { [Header("Target")] public GameObject TargetObject; [Header("Specific Trigger Well")] public FVRFireArmReloadTriggerWell ReloadTriggerWell; private bool _lastMagLoaded; private void Update() { if (!((Object)(object)ReloadTriggerWell == (Object)null) && !((Object)(object)TargetObject == (Object)null)) { bool flag = (Object)(object)ReloadTriggerWell.FireArm != (Object)null && (Object)(object)ReloadTriggerWell.FireArm.Magazine != (Object)null; if (flag != _lastMagLoaded) { TargetObject.SetActive(!flag); _lastMagLoaded = flag; } } } } public class PartRecoilImpulse : MonoBehaviour { public enum ImpulseMode { Rotation, Translation } public enum ImpulseAxis { X, Y, Z } [Serializable] public class RecoilPart { public Transform Piece; public ImpulseMode Mode = ImpulseMode.Rotation; public ImpulseAxis Axis = ImpulseAxis.X; public Vector2 Range = new Vector2(0f, 45f); public float ReturnSpeed = 5f; public float ImpulseStrength = 1f; [NonSerialized] public float CurrentLerp = 0f; } [Header("Parts")] public List Parts = new List(); private FVRFireArm m_firearm; private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown GM.CurrentSceneSettings.ShotFiredEvent += new ShotFired(OnShotFired); } private void OnDestroy() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if ((Object)(object)GM.CurrentSceneSettings != (Object)null) { GM.CurrentSceneSettings.ShotFiredEvent -= new ShotFired(OnShotFired); } } private void Start() { m_firearm = ((Component)this).GetComponentInParent(); if ((Object)(object)m_firearm == (Object)null) { Debug.LogWarning((object)"[PartRecoilImpulse] No FVRFireArm found in parent hierarchy.", (Object)(object)this); } for (int i = 0; i < Parts.Count; i++) { ApplyToPart(Parts[i]); } } private void OnShotFired(FVRFireArm firearm) { if (!((Object)(object)firearm != (Object)(object)m_firearm)) { for (int i = 0; i < Parts.Count; i++) { Parts[i].CurrentLerp = Mathf.Clamp01(Parts[i].ImpulseStrength); ApplyToPart(Parts[i]); } } } private void Update() { for (int i = 0; i < Parts.Count; i++) { RecoilPart recoilPart = Parts[i]; if (recoilPart.CurrentLerp > 0f) { recoilPart.CurrentLerp = Mathf.MoveTowards(recoilPart.CurrentLerp, 0f, Time.deltaTime * recoilPart.ReturnSpeed); ApplyToPart(recoilPart); } } } private void ApplyToPart(RecoilPart part) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)part.Piece == (Object)null) { return; } float num = Mathf.Lerp(part.Range.x, part.Range.y, part.CurrentLerp); if (part.Mode == ImpulseMode.Rotation) { Vector3 localEulerAngles = part.Piece.localEulerAngles; if (part.Axis == ImpulseAxis.X) { localEulerAngles.x = num; } else if (part.Axis == ImpulseAxis.Y) { localEulerAngles.y = num; } else { localEulerAngles.z = num; } part.Piece.localEulerAngles = localEulerAngles; } else { Vector3 localPosition = part.Piece.localPosition; if (part.Axis == ImpulseAxis.X) { localPosition.x = num; } else if (part.Axis == ImpulseAxis.Y) { localPosition.y = num; } else { localPosition.z = num; } part.Piece.localPosition = localPosition; } } } [RequireComponent(typeof(ModularWeaponPart))] public class BayonetAddon : MonoBehaviour, IPartFireArmRequirement { [Header("Bayonet Config")] public MeleeParams MeleeParams; private MeleeParams _origMeleeParams; private FVRFireArm _firearm; public FVRFireArm FireArm { get { return _firearm; } set { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)value != (Object)null) { _firearm = value; _origMeleeParams = new MeleeParams(); CopyMeleeParams(((FVRPhysicalObject)_firearm).MP, _origMeleeParams); CopyMeleeParams(MeleeParams, ((FVRPhysicalObject)_firearm).MP); } else if ((Object)(object)value == (Object)null && (Object)(object)_firearm != (Object)null) { if (_origMeleeParams != null) { CopyMeleeParams(_origMeleeParams, ((FVRPhysicalObject)_firearm).MP); } _firearm = null; } } } private void CopyMeleeParams(MeleeParams source, MeleeParams destination) { if (source == null || destination == null) { return; } Type typeFromHandle = typeof(MeleeParams); FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if ((object)fieldInfo.FieldType == typeof(FVRPhysicalObject) || (object)fieldInfo.FieldType == typeof(FVRInteractiveObject) || fieldInfo.Name == "HandPoint") { continue; } if ((object)fieldInfo.FieldType == typeof(List)) { try { List list = (List)fieldInfo.GetValue(source); if (list != null) { List value = new List(list); fieldInfo.SetValue(destination, value); } } catch (Exception ex) { Debug.LogError((object)("[BayonetAddon] Failed to clone list field " + fieldInfo.Name + ": " + ex.Message)); } continue; } try { object value2 = fieldInfo.GetValue(source); if (value2 != null) { fieldInfo.SetValue(destination, value2); } } catch (Exception ex2) { Debug.LogError((object)("[BayonetAddon] Failed to copy field " + fieldInfo.Name + ": " + ex2.Message)); } } PropertyInfo[] properties = typeFromHandle.GetProperties(BindingFlags.Instance | BindingFlags.Public); PropertyInfo[] array2 = properties; foreach (PropertyInfo propertyInfo in array2) { if (!propertyInfo.CanRead || !propertyInfo.CanWrite || (object)propertyInfo.PropertyType == typeof(FVRPhysicalObject) || (object)propertyInfo.PropertyType == typeof(FVRInteractiveObject) || propertyInfo.Name == "HandPoint") { continue; } if ((object)propertyInfo.PropertyType == typeof(List)) { try { List list2 = (List)propertyInfo.GetValue(source, null); if (list2 != null) { List value3 = new List(list2); propertyInfo.SetValue(destination, value3, null); } } catch (Exception ex3) { Debug.LogError((object)("[BayonetAddon] Failed to clone list property " + propertyInfo.Name + ": " + ex3.Message)); } continue; } try { object value4 = propertyInfo.GetValue(source, null); if (value4 != null) { propertyInfo.SetValue(destination, value4, null); } } catch (Exception ex4) { Debug.LogError((object)("[BayonetAddon] Failed to copy property " + propertyInfo.Name + ": " + ex4.Message)); } } } } [DefaultExecutionOrder(-200)] [RequireComponent(typeof(ModularWeaponPart))] public class FirearmMagazineAddons : MonoBehaviour, IPartFireArmRequirement { [Header("Debug Settings")] [Tooltip("Enable detailed console logs to track component auto-detection and linking.")] public bool EnableDebugLogging = true; [Header("Detachable Magazine Settings")] [Tooltip("Does this part alter the firearm's detachable magazine parameters?")] public bool OverridesExternalMagazines = false; [Tooltip("The detachable magazine type accepted by this well.")] public FireArmMagazineType MagazineTypeOverride; [Tooltip("Local transform where the detachable magazine mounts on this part.")] public Transform MagazineMountPos; [Tooltip("Local transform where the detachable magazine ejects on this part.")] public Transform MagazineEjectPos; [Tooltip("Optional: The FVRFireArmReloadTriggerWell component on this part prefab.")] public FVRFireArmReloadTriggerWell MagazineWellTrigger; [Tooltip("Optional: The UniversalMagGrabTrigger component on this part prefab.")] public UniversalMagGrabTrigger MagGrabTrigger; [Tooltip("Optional: The UniversalAdvancedMagazineGrabTrigger component on this part prefab.")] public UniversalAdvancedMagazineGrabTrigger AdvancedMagGrabTrigger; [Tooltip("Optional: Manual AudioEvent to play when a magazine is inserted.")] public AudioEvent CustomMagazineInAudio; [Tooltip("Optional: Manual AudioEvent to play when a magazine is ejected.")] public AudioEvent CustomMagazineOutAudio; [Header("Integrated/Internal Magazine Settings")] [Tooltip("Does this part feature a built-in internal magazine (like a tube or fixed box)?")] public bool EnablesInternalMagazine = false; [Tooltip("The FVRFireArmMagazine component representing the internal feed system on this part.")] public FVRFireArmMagazine InternalMagazine; [Tooltip("Does this part override the base firearm's physical magazine release button behavior?")] public bool OverridesMagReleaseButton = false; [Tooltip("Should the physical magazine release button on the base receiver be enabled (true) or disabled (false)?")] public bool NewMagReleaseButtonState = true; [Header("Stripper Clip Settings")] [Tooltip("Does this part alter the firearm's stripper clip parameters?")] public bool OverridesStripperClips = false; [Tooltip("The stripper clip type accepted by this clip guide.")] public FireArmClipType ClipTypeOverride; [Tooltip("Local transform where the clip mounts on this part.")] public Transform ClipMountPos; [Tooltip("Local transform where the clip ejects on this part.")] public Transform ClipEjectPos; [Tooltip("Optional: The FVRFireArmClipTriggerWell component on this part prefab.")] public FVRFireArmClipTriggerWell ClipWellTrigger; [Tooltip("Optional: The clip trigger GameObject on this part.")] public GameObject ClipTrigger; [Header("Top Cover Settings")] [Tooltip("Does this part feature a functional top cover?")] public bool OverridesTopCover = false; [Tooltip("Should the top cover start in the open (up) state when equipped?")] public bool StartTopCoverUp = false; [Tooltip("Optional: The FVRFireArmTopCover component on this part prefab.")] public FVRFireArmTopCover TopCoverScript; [Header("Caliber Conversion Settings")] [Tooltip("Does this part perform a caliber conversion?")] public bool OverridesRoundType = false; [Tooltip("The round type accepted by the weapon with this part equipped.")] public FireArmRoundType RoundTypeOverride; [Header("Belt-Fed (LMG) Settings")] [Tooltip("Does this part convert the firearm to a belt-fed system?")] public bool OverridesBeltFed = false; [Tooltip("The Belt Display Data component on this part.")] public FVRFirearmBeltDisplayData BeltDisplayData; [Tooltip("Local transform where the belt box mounts on this part.")] public Transform BeltBoxMountPos; [Tooltip("Local transform where the belt box ejects on this part.")] public Transform BeltBoxEjectPos; [Tooltip("Does the belt system require the bolt to be back to seat the belt?")] public bool RequiresBoltBackToSeatBelt = false; [Tooltip("Optional: The FVRFireArmBeltRemovalTrigger component on this part prefab.")] public FVRFireArmBeltRemovalTrigger BeltRemovalTrigger; [Tooltip("Optional: The ParticleSystem that ejects links when firing.")] public ParticleSystem DelinkerSystemOverride; [Tooltip("Optional: The GameObject prefab containing your pre-combined bullet + link models.")] public GameObject CustomProxyPrefab; [Tooltip("Where the ammo belt physically exits your part (used if no magazine is loaded).")] public Transform BeltExitPointOverride; [Tooltip("Where the ammo belt physically enters the gun's feed tray.")] public Transform FeedTrayEntPos; [Tooltip("How far down (in meters) the ammo belt sags between the box and the gun.")] public float BeltGravitySag = 0.15f; [Tooltip("Rotate the bullet model in the Inspector if it is facing the wrong direction.")] public Vector3 BulletRotationOffset = Vector3.zero; private FVRFireArm _mainFireArm; private bool _originalUsesMagazines; private FireArmMagazineType _originalMagazineType; private Transform _originalMagazineMountPos; private Transform _originalMagazineEjectPos; private bool _originalUsesClips; private FireArmClipType _originalClipType; private Transform _originalClipMountPos; private Transform _originalClipEjectPos; private GameObject _originalClipTrigger; private bool _originalUsesTopCover; private bool _originalIsTopCoverUp; private FireArmRoundType _originalRoundType; private bool _originalUsesBelts; private FVRFirearmBeltDisplayData _originalBeltDD; private Transform _originalBeltBoxMountPos; private Transform _originalBeltBoxEjectPos; private bool _originalRequiresBoltBack; private bool _origUsesDelinker; private ParticleSystem _origDelinkerSystem; private bool _origMagReleaseState; private AudioEvent _originalMagazineInAudio; private AudioEvent _originalMagazineOutAudio; private List _disabledReceiverGrabTriggers = new List(); private FVRFireArmMagazine _originalReceiverMagazine; private FVRFireArmMagazine _lastMagazine; private Transform _currentGrabPointBox; private Transform _currentHiddenInBoxSpot; private bool _needsInternalMagRestore = false; private Vector3 _internalMagLocalPos; private Quaternion _internalMagLocalRot; private Transform _internalMagOriginalParent; private AttachableFirearm _underbarrelFirearm; private AttachableFirearmPhysicalObject _underbarrelPhysical; private AttachableFirearmInterface _underbarrelInterface; public FVRFireArm FireArm { get { return _mainFireArm; } set { //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_0655: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_06ea: Unknown result type (might be due to invalid IL or missing references) //IL_074b: Unknown result type (might be due to invalid IL or missing references) //IL_0750: Unknown result type (might be due to invalid IL or missing references) //IL_0712: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_08a7: Unknown result type (might be due to invalid IL or missing references) //IL_08ac: Unknown result type (might be due to invalid IL or missing references) //IL_08b0: Unknown result type (might be due to invalid IL or missing references) //IL_08b5: Unknown result type (might be due to invalid IL or missing references) //IL_08b7: Unknown result type (might be due to invalid IL or missing references) //IL_08b9: Unknown result type (might be due to invalid IL or missing references) //IL_08c0: Unknown result type (might be due to invalid IL or missing references) //IL_08c5: Unknown result type (might be due to invalid IL or missing references) //IL_08d0: Unknown result type (might be due to invalid IL or missing references) //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e3: Unknown result type (might be due to invalid IL or missing references) //IL_08e5: Unknown result type (might be due to invalid IL or missing references) //IL_090c: Unknown result type (might be due to invalid IL or missing references) //IL_090e: Unknown result type (might be due to invalid IL or missing references) //IL_0924: Unknown result type (might be due to invalid IL or missing references) //IL_0926: Unknown result type (might be due to invalid IL or missing references) //IL_092b: Unknown result type (might be due to invalid IL or missing references) //IL_0935: Unknown result type (might be due to invalid IL or missing references) //IL_0937: Unknown result type (might be due to invalid IL or missing references) //IL_093c: Unknown result type (might be due to invalid IL or missing references) //IL_0941: Unknown result type (might be due to invalid IL or missing references) //IL_0945: Unknown result type (might be due to invalid IL or missing references) //IL_0947: Unknown result type (might be due to invalid IL or missing references) //IL_0951: Unknown result type (might be due to invalid IL or missing references) //IL_0953: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)value != (Object)null) { _mainFireArm = value; if (EnableDebugLogging) { Debug.Log((object)$"[FirearmMagazineAddons] Equipping - Main Firearm assigned: {((Object)value).name}"); } if ((Object)(object)value.Magazine != (Object)null) { if (value.Magazine.IsIntegrated) { if (EnableDebugLogging) { Debug.Log((object)$"[FirearmMagazineAddons] Equipping - Silently destroying internal magazine: {((Object)value.Magazine).name}"); } FVRFireArmMagazine magazine = value.Magazine; value.Magazine = null; if ((Object)(object)magazine != (Object)null) { magazine.SetMagChild((FVRFireArmMagazine)null); magazine.SetMagParent((FVRFireArmMagazine)null); Object.Destroy((Object)(object)((Component)magazine).gameObject); } } else { if (EnableDebugLogging) { Debug.Log((object)$"[FirearmMagazineAddons] Equipping - Ejecting and preserving currently loaded external magazine: {((Object)value.Magazine).name}"); } value.EjectMag(true); } } if ((Object)(object)value.Clip != (Object)null) { if (EnableDebugLogging) { Debug.Log((object)"[FirearmMagazineAddons] Equipping - Ejecting currently loaded stripper clip."); } value.EjectClip(); } if (OverridesRoundType) { List chambers = value.GetChambers(); if (chambers != null) { for (int i = 0; i < chambers.Count; i++) { chambers[i].Unload(); } } } if ((Object)(object)MagazineWellTrigger != (Object)null) { MagazineWellTrigger.FireArm = value; ((Component)MagazineWellTrigger).gameObject.SetActive(true); ((Behaviour)MagazineWellTrigger).enabled = true; ((Component)MagazineWellTrigger).gameObject.tag = "FVRFireArmReloadTriggerWell"; } if ((Object)(object)ClipWellTrigger != (Object)null) { ClipWellTrigger.FireArm = value; ((Component)ClipWellTrigger).gameObject.SetActive(true); ((Behaviour)ClipWellTrigger).enabled = true; ((Component)ClipWellTrigger).gameObject.tag = "FVRFireArmClipReloadTriggerWell"; } if ((Object)(object)TopCoverScript != (Object)null) { TopCoverScript.FireArm = value; ((Component)TopCoverScript).gameObject.SetActive(true); ((Behaviour)TopCoverScript).enabled = true; } if ((Object)(object)BeltRemovalTrigger != (Object)null) { BeltRemovalTrigger.FireArm = value; ((Component)BeltRemovalTrigger).gameObject.SetActive(true); ((Behaviour)BeltRemovalTrigger).enabled = true; } if ((Object)(object)MagGrabTrigger == (Object)null) { MagGrabTrigger = ((Component)this).GetComponentInChildren(true); } if ((Object)(object)MagGrabTrigger != (Object)null) { MagGrabTrigger.FireArm = value; ((Component)MagGrabTrigger).gameObject.SetActive(true); ((Behaviour)MagGrabTrigger).enabled = true; MagGrabTrigger.IsBeltBox = OverridesBeltFed; } if ((Object)(object)AdvancedMagGrabTrigger == (Object)null) { AdvancedMagGrabTrigger = ((Component)this).GetComponentInChildren(true); } if ((Object)(object)AdvancedMagGrabTrigger != (Object)null) { AdvancedMagGrabTrigger.FireArm = value; ((Component)AdvancedMagGrabTrigger).gameObject.SetActive(true); ((Behaviour)AdvancedMagGrabTrigger).enabled = true; AdvancedMagGrabTrigger.IsBeltBoxGrabTrigger = OverridesBeltFed; } FirearmMagazineAddonStateTracker firearmMagazineAddonStateTracker = ((Component)value).GetComponent(); if ((Object)(object)firearmMagazineAddonStateTracker == (Object)null) { firearmMagazineAddonStateTracker = ((Component)value).gameObject.AddComponent(); firearmMagazineAddonStateTracker.CacheReceiverOriginalStates(value); } firearmMagazineAddonStateTracker.ActiveAddonCount++; if (OverridesExternalMagazines) { value.UsesMagazines = true; value.MagazineType = MagazineTypeOverride; if ((Object)(object)MagazineMountPos != (Object)null) { value.MagazineMountPos = MagazineMountPos; } if ((Object)(object)MagazineEjectPos != (Object)null) { value.MagazineEjectPos = MagazineEjectPos; } } if (EnablesInternalMagazine && (Object)(object)InternalMagazine != (Object)null) { value.UsesMagazines = true; if ((Object)(object)value.MagazineMountPos == (Object)null) { value.MagazineMountPos = ((Component)InternalMagazine).transform; } if ((Object)(object)value.MagazineEjectPos == (Object)null) { value.MagazineEjectPos = ((Component)InternalMagazine).transform; } _internalMagLocalPos = ((Component)InternalMagazine).transform.localPosition; _internalMagLocalRot = ((Component)InternalMagazine).transform.localRotation; _internalMagOriginalParent = ((Component)InternalMagazine).transform.parent; InternalMagazine.Load(value); _needsInternalMagRestore = true; FVRFireArmMagazineReloadTrigger[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { componentsInChildren[j].Magazine = InternalMagazine; ((Component)componentsInChildren[j]).gameObject.SetActive(true); ((Behaviour)componentsInChildren[j]).enabled = true; if (EnableDebugLogging) { Debug.Log((object)$"[FirearmMagazineAddons] Equipping - Linked internal reload trigger: {((Object)((Component)componentsInChildren[j]).gameObject).name}"); } } _disabledReceiverGrabTriggers.Clear(); UniversalMagGrabTrigger[] componentsInChildren2 = ((Component)value).GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren2.Length; k++) { if ((Object)(object)((Component)componentsInChildren2[k]).transform.parent != (Object)(object)((Component)this).transform && ((Component)componentsInChildren2[k]).gameObject.activeSelf) { ((Component)componentsInChildren2[k]).gameObject.SetActive(false); firearmMagazineAddonStateTracker.DisabledReceiverGrabTriggers.Add(((Component)componentsInChildren2[k]).gameObject); } } UniversalAdvancedMagazineGrabTrigger[] componentsInChildren3 = ((Component)value).GetComponentsInChildren(true); for (int l = 0; l < componentsInChildren3.Length; l++) { if ((Object)(object)((Component)componentsInChildren3[l]).transform.parent != (Object)(object)((Component)this).transform && ((Component)componentsInChildren3[l]).gameObject.activeSelf) { ((Component)componentsInChildren3[l]).gameObject.SetActive(false); firearmMagazineAddonStateTracker.DisabledReceiverGrabTriggers.Add(((Component)componentsInChildren3[l]).gameObject); } } } if (OverridesMagReleaseButton) { ModifyMagReleaseButton(value, NewMagReleaseButtonState, firearmMagazineAddonStateTracker); } if (OverridesStripperClips) { value.UsesClips = true; value.ClipType = ClipTypeOverride; if ((Object)(object)ClipMountPos != (Object)null) { value.ClipMountPos = ClipMountPos; } if ((Object)(object)ClipEjectPos != (Object)null) { value.ClipEjectPos = ClipEjectPos; } if ((Object)(object)ClipTrigger != (Object)null) { value.ClipTrigger = ClipTrigger; } } if (OverridesTopCover) { value.UsesTopCover = true; value.IsTopCoverUp = StartTopCoverUp; } if (OverridesRoundType) { value.RoundType = RoundTypeOverride; List chambers2 = value.GetChambers(); if (chambers2 != null) { for (int m = 0; m < chambers2.Count; m++) { chambers2[m].RoundType = RoundTypeOverride; } } if ((Object)(object)((FVRPhysicalObject)value).ObjectWrapper != (Object)null) { ((FVRPhysicalObject)value).ObjectWrapper.RoundType = RoundTypeOverride; } } if ((Object)(object)value.AudioClipSet != (Object)null) { if (CustomMagazineInAudio != null) { value.AudioClipSet.MagazineIn = CustomMagazineInAudio; } if (CustomMagazineOutAudio != null) { value.AudioClipSet.MagazineOut = CustomMagazineOutAudio; } } if (OverridesBeltFed) { value.UsesBelts = true; value.RequiresBoltBackToSeatBelt = RequiresBoltBackToSeatBelt; if ((Object)(object)BeltDisplayData != (Object)null) { value.BeltDD = BeltDisplayData; BeltDisplayData.Firearm = value; if (value.BeltDD.ProxyRounds == null) { value.BeltDD.ProxyRounds = new List(); } if (value.BeltDD.ProxyRounds.Count == 0 && (Object)(object)CustomProxyPrefab != (Object)null) { Transform val = ((!((Object)(object)BeltExitPointOverride != (Object)null)) ? value.BeltDD.GrabPoint_Box : BeltExitPointOverride); Transform val2 = ((!((Object)(object)FeedTrayEntPos != (Object)null)) ? value.BeltDD.GrabPoint_Gun : FeedTrayEntPos); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { Vector3 position = val.position; Vector3 position2 = val2.position; Vector3 val3 = Vector3.Lerp(position, position2, 0.5f) + Vector3.down * BeltGravitySag; float num = 0f; Vector3 val4 = position; for (int n = 1; n <= 10; n++) { float num2 = (float)n / 10f; Vector3 val5 = (1f - num2) * (1f - num2) * position + 2f * (1f - num2) * num2 * val3 + num2 * num2 * position2; num += Vector3.Distance(val4, val5); val4 = val5; } float num3 = value.BeltDD.DistanceBetweenRounds; if (num3 <= 0f) { num3 = 0.03f; } int num4 = Mathf.CeilToInt(num / num3); value.BeltDD.BeltCapacity = num4; for (int num5 = 0; num5 < num4; num5++) { GameObject val6 = Object.Instantiate(CustomProxyPrefab); ((Object)val6).name = "ProxyRound_Procedural_" + num5; val6.transform.SetParent(((Component)value.BeltDD).transform, false); value.BeltDD.ProxyRounds.Add(val6.transform); } Type type = ((object)value.BeltDD).GetType(); FieldInfo field = type.GetField("m_proxyRends", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("m_proxyMeshes", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)field != null && (object)field2 != null) { List list = (List)field.GetValue(value.BeltDD); List list2 = (List)field2.GetValue(value.BeltDD); list.Clear(); list2.Clear(); for (int num6 = 0; num6 < value.BeltDD.ProxyRounds.Count; num6++) { list.Add(((Component)value.BeltDD.ProxyRounds[num6]).gameObject.GetComponentInChildren()); list2.Add(((Component)value.BeltDD.ProxyRounds[num6]).gameObject.GetComponentInChildren()); } } } } } if ((Object)(object)BeltBoxMountPos != (Object)null) { value.BeltBoxMountPos = BeltBoxMountPos; } if ((Object)(object)BeltBoxEjectPos != (Object)null) { value.BeltBoxEjectPos = BeltBoxEjectPos; } if ((Object)(object)DelinkerSystemOverride != (Object)null) { ModifyDelinker(value, enableDelinker: true, DelinkerSystemOverride, firearmMagazineAddonStateTracker); } } ((Behaviour)this).enabled = true; } else { CleanupAddon(_mainFireArm); } } } private void Awake() { _underbarrelFirearm = ((Component)this).GetComponentInChildren(true); _underbarrelPhysical = ((Component)this).GetComponentInChildren(true); _underbarrelInterface = ((Component)this).GetComponentInChildren(true); if ((Object)(object)_underbarrelFirearm != (Object)null) { _underbarrelFirearm.Attachment = _underbarrelPhysical; _underbarrelFirearm.Interface = _underbarrelInterface; } if ((Object)(object)_underbarrelPhysical != (Object)null) { ((FVRFireArmAttachment)_underbarrelPhysical).AttachmentInterface = (FVRFireArmAttachmentInterface)(object)_underbarrelInterface; } if ((Object)(object)_underbarrelInterface != (Object)null) { _underbarrelInterface.FA = _underbarrelFirearm; ((FVRFireArmAttachmentInterface)_underbarrelInterface).Attachment = (FVRFireArmAttachment)(object)_underbarrelPhysical; } } private void Update() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: 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_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: 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_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_046c: 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_0494: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: 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_04ef: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0541: 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_0548: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05ab: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05c7: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) if (_needsInternalMagRestore && (Object)(object)_mainFireArm != (Object)null && (Object)(object)InternalMagazine != (Object)null) { _needsInternalMagRestore = false; ((Component)InternalMagazine).transform.SetParent(_internalMagOriginalParent, false); ((Component)InternalMagazine).transform.localPosition = _internalMagLocalPos; ((Component)InternalMagazine).transform.localRotation = _internalMagLocalRot; if (EnableDebugLogging) { Debug.Log((object)"[FirearmMagazineAddons] Update - Deferred internal magazine position and parentage restoration executed."); } } if ((Object)(object)_mainFireArm == (Object)null || !OverridesBeltFed || (Object)(object)_mainFireArm.BeltDD == (Object)null) { return; } if ((Object)(object)_mainFireArm.Magazine != (Object)(object)_lastMagazine) { _lastMagazine = _mainFireArm.Magazine; if ((Object)(object)_lastMagazine != (Object)null) { _currentGrabPointBox = ((Component)_lastMagazine).transform.Find("GrabPoint_Box"); _currentHiddenInBoxSpot = ((Component)_lastMagazine).transform.Find("HiddenInBoxSpot"); if ((Object)(object)_currentGrabPointBox != (Object)null) { _mainFireArm.BeltDD.GrabPoint_Box = _currentGrabPointBox; } if ((Object)(object)_currentHiddenInBoxSpot != (Object)null) { _mainFireArm.BeltDD.HiddenInBoxSpot = _currentHiddenInBoxSpot; } if ((Object)(object)_mainFireArm.AudioClipSet != (Object)null && (Object)(object)_lastMagazine.Profile != (Object)null) { _mainFireArm.AudioClipSet.MagazineIn = _lastMagazine.Profile.MagazineIn; _mainFireArm.AudioClipSet.MagazineOut = _lastMagazine.Profile.MagazineOut; } } else { _currentGrabPointBox = null; _currentHiddenInBoxSpot = null; } } Transform val = ((!((Object)(object)_currentGrabPointBox != (Object)null)) ? BeltExitPointOverride : _currentGrabPointBox); Transform val2 = ((!((Object)(object)FeedTrayEntPos != (Object)null)) ? _mainFireArm.BeltDD.GrabPoint_Gun : FeedTrayEntPos); if (!((Object)(object)val != (Object)null) || !((Object)(object)val2 != (Object)null)) { return; } Vector3 position = val.position; Vector3 position2 = val2.position; Vector3 val3 = Vector3.Lerp(position, position2, 0.5f) + Vector3.down * BeltGravitySag; int count = _mainFireArm.BeltDD.ProxyRounds.Count; if (count <= 0) { return; } int num = count + 1; while (_mainFireArm.BeltDD.Chain_In.localPosList.Count < num) { _mainFireArm.BeltDD.Chain_In.localPosList.Add(Vector3.zero); _mainFireArm.BeltDD.Chain_In.localRotList.Add(Quaternion.identity); } while (_mainFireArm.BeltDD.Chain_Out.localPosList.Count < num) { _mainFireArm.BeltDD.Chain_Out.localPosList.Add(Vector3.zero); _mainFireArm.BeltDD.Chain_Out.localRotList.Add(Quaternion.identity); } while (_mainFireArm.BeltDD.ChainInterpolatedInOut.localPosList.Count < num) { _mainFireArm.BeltDD.ChainInterpolatedInOut.localPosList.Add(Vector3.zero); _mainFireArm.BeltDD.ChainInterpolatedInOut.localRotList.Add(Quaternion.identity); } while (_mainFireArm.BeltDD.ChainInterpolated01.localPosList.Count < count) { _mainFireArm.BeltDD.ChainInterpolated01.localPosList.Add(Vector3.zero); _mainFireArm.BeltDD.ChainInterpolated01.localRotList.Add(Quaternion.identity); } Vector3 val4 = position; for (int i = 0; i < num; i++) { float num2 = (float)i / (float)(num - 1); Vector3 val5 = (1f - num2) * (1f - num2) * position + 2f * (1f - num2) * num2 * val3 + num2 * num2 * position2; Vector3 val6 = 2f * (1f - num2) * (val3 - position) + 2f * num2 * (position2 - val3); Vector3 val7 = ((Vector3)(ref val6)).normalized; if (val7 == Vector3.zero) { val7 = ((Component)_mainFireArm.BeltDD).transform.forward; } Vector3 val8 = ((Component)_mainFireArm.BeltDD).transform.up; if (Mathf.Abs(Vector3.Dot(val7, val8)) > 0.95f) { val8 = ((Component)_mainFireArm.BeltDD).transform.forward; } Quaternion val9 = Quaternion.LookRotation(val7, val8) * Quaternion.Euler(BulletRotationOffset); Vector3 value = ((Component)_mainFireArm.BeltDD).transform.InverseTransformPoint(val5); Quaternion value2 = Quaternion.Inverse(((Component)_mainFireArm.BeltDD).transform.rotation) * val9; _mainFireArm.BeltDD.Chain_In.localPosList[i] = value; _mainFireArm.BeltDD.Chain_In.localRotList[i] = value2; _mainFireArm.BeltDD.Chain_Out.localPosList[i] = value; _mainFireArm.BeltDD.Chain_Out.localRotList[i] = value2; val4 = val5; } } private void OnDestroy() { CleanupAddon(_mainFireArm); } private void CleanupAddon(FVRFireArm firearm) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)firearm == (Object)null) { return; } if (EnableDebugLogging) { Debug.Log((object)"[FirearmMagazineAddons] Swapping away - Starting decentralized cleanup."); } _needsInternalMagRestore = false; FirearmMagazineAddonStateTracker component = ((Component)firearm).GetComponent(); if ((Object)(object)component != (Object)null) { if (OverridesExternalMagazines) { firearm.UsesMagazines = component.OriginalUsesMagazines; firearm.MagazineType = component.OriginalMagazineType; firearm.MagazineMountPos = component.OriginalMagazineMountPos; firearm.MagazineEjectPos = component.OriginalMagazineEjectPos; if ((Object)(object)MagazineWellTrigger != (Object)null) { MagazineWellTrigger.FireArm = null; } if ((Object)(object)MagGrabTrigger != (Object)null) { ((Component)MagGrabTrigger).gameObject.SetActive(false); MagGrabTrigger.FireArm = null; } if ((Object)(object)AdvancedMagGrabTrigger != (Object)null) { ((Component)AdvancedMagGrabTrigger).gameObject.SetActive(false); AdvancedMagGrabTrigger.FireArm = null; } if ((Object)(object)firearm.AudioClipSet != (Object)null) { firearm.AudioClipSet.MagazineIn = component.OriginalMagazineInAudio; firearm.AudioClipSet.MagazineOut = component.OriginalMagazineOutAudio; } } if (EnablesInternalMagazine && (Object)(object)InternalMagazine != (Object)null) { Object.Destroy((Object)(object)((Component)InternalMagazine).gameObject); } if (OverridesMagReleaseButton) { RestoreMagReleaseButton(firearm, component); } if (OverridesStripperClips) { firearm.UsesClips = component.OriginalUsesClips; firearm.ClipType = component.OriginalClipType; firearm.ClipMountPos = component.OriginalClipMountPos; firearm.ClipEjectPos = component.OriginalClipEjectPos; firearm.ClipTrigger = component.OriginalClipTrigger; if ((Object)(object)ClipWellTrigger != (Object)null) { ClipWellTrigger.FireArm = null; } } if (OverridesTopCover) { firearm.UsesTopCover = component.OriginalUsesTopCover; firearm.IsTopCoverUp = component.OriginalIsTopCoverUp; if ((Object)(object)TopCoverScript != (Object)null) { TopCoverScript.FireArm = null; } } if (OverridesRoundType) { firearm.RoundType = component.OriginalRoundType; List chambers = firearm.GetChambers(); if (chambers != null) { for (int i = 0; i < chambers.Count; i++) { if (OverridesRoundType) { chambers[i].Unload(); } chambers[i].RoundType = component.OriginalRoundType; } } if ((Object)(object)((FVRPhysicalObject)firearm).ObjectWrapper != (Object)null) { ((FVRPhysicalObject)firearm).ObjectWrapper.RoundType = component.OriginalRoundType; } } if (OverridesBeltFed) { if (firearm.UsesBelts && (Object)(object)firearm.BeltDD != (Object)null) { firearm.BeltDD.ForceRelease(); firearm.BeltDD.BeltRounds.Clear(); firearm.BeltDD.UpdateProxyRounds(0); } firearm.UsesBelts = component.OriginalUsesBelts; firearm.BeltDD = component.OriginalBeltDD; firearm.BeltBoxMountPos = component.OriginalBeltBoxMountPos; firearm.BeltBoxEjectPos = component.OriginalBeltBoxEjectPos; firearm.RequiresBoltBackToSeatBelt = component.OriginalRequiresBoltBack; RestoreDelinker(firearm, component); if ((Object)(object)BeltRemovalTrigger != (Object)null) { BeltRemovalTrigger.FireArm = null; } } component.ActiveAddonCount--; if (component.ActiveAddonCount <= 0) { for (int j = 0; j < component.DisabledReceiverGrabTriggers.Count; j++) { if ((Object)(object)component.DisabledReceiverGrabTriggers[j] != (Object)null) { component.DisabledReceiverGrabTriggers[j].SetActive(true); } } component.DisabledReceiverGrabTriggers.Clear(); if ((Object)(object)component.OriginalReceiverMagazine != (Object)null) { ((Component)component.OriginalReceiverMagazine).gameObject.SetActive(true); firearm.Magazine = component.OriginalReceiverMagazine; FVRFireArmMagazineReloadTrigger[] componentsInChildren = ((Component)firearm).GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren.Length; k++) { componentsInChildren[k].Magazine = component.OriginalReceiverMagazine; ((Component)componentsInChildren[k]).gameObject.SetActive(true); ((Behaviour)componentsInChildren[k]).enabled = true; } component.OriginalReceiverMagazine = null; } if (EnableDebugLogging) { Debug.Log((object)"[FirearmMagazineAddons] Cleanup - Restored all native receiver baselines. Destroying state tracker."); } Object.Destroy((Object)(object)component); } } _mainFireArm = null; _lastMagazine = null; _currentGrabPointBox = null; _currentHiddenInBoxSpot = null; } private void ModifyMagReleaseButton(FVRFireArm firearm, bool enableButton, FirearmMagazineAddonStateTracker tracker) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown if (firearm is ClosedBoltWeapon) { ClosedBoltWeapon val = (ClosedBoltWeapon)firearm; tracker.OrigMagReleaseState = val.HasMagReleaseButton; val.HasMagReleaseButton = enableButton; } else if (firearm is OpenBoltReceiver) { OpenBoltReceiver val2 = (OpenBoltReceiver)firearm; tracker.OrigMagReleaseState = val2.HasMagReleaseButton; val2.HasMagReleaseButton = enableButton; } else if (firearm is Handgun) { Handgun val3 = (Handgun)firearm; tracker.OrigMagReleaseState = val3.HasMagReleaseButton; val3.HasMagReleaseButton = enableButton; } else if (firearm is BoltActionRifle) { BoltActionRifle val4 = (BoltActionRifle)firearm; tracker.OrigMagReleaseState = val4.HasMagEjectionButton; val4.HasMagEjectionButton = enableButton; } } private void RestoreMagReleaseButton(FVRFireArm firearm, FirearmMagazineAddonStateTracker tracker) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown if (firearm is ClosedBoltWeapon) { ClosedBoltWeapon val = (ClosedBoltWeapon)firearm; val.HasMagReleaseButton = tracker.OrigMagReleaseState; } else if (firearm is OpenBoltReceiver) { OpenBoltReceiver val2 = (OpenBoltReceiver)firearm; val2.HasMagReleaseButton = tracker.OrigMagReleaseState; } else if (firearm is Handgun) { Handgun val3 = (Handgun)firearm; val3.HasMagReleaseButton = tracker.OrigMagReleaseState; } else if (firearm is BoltActionRifle) { BoltActionRifle val4 = (BoltActionRifle)firearm; val4.HasMagEjectionButton = tracker.OrigMagReleaseState; } } private void ModifyDelinker(FVRFireArm firearm, bool enableDelinker, ParticleSystem customSystem, FirearmMagazineAddonStateTracker tracker) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (firearm is ClosedBoltWeapon) { ClosedBoltWeapon val = (ClosedBoltWeapon)firearm; tracker.OrigUsesDelinker = val.UsesDelinker; tracker.OrigDelinkerSystem = val.DelinkerSystem; val.UsesDelinker = enableDelinker; if ((Object)(object)customSystem != (Object)null) { val.DelinkerSystem = customSystem; } } else if (firearm is OpenBoltReceiver) { OpenBoltReceiver val2 = (OpenBoltReceiver)firearm; tracker.OrigUsesDelinker = val2.UsesDelinker; tracker.OrigDelinkerSystem = val2.DelinkerSystem; val2.UsesDelinker = enableDelinker; if ((Object)(object)customSystem != (Object)null) { val2.DelinkerSystem = customSystem; } } } private void RestoreDelinker(FVRFireArm firearm, FirearmMagazineAddonStateTracker tracker) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown if (firearm is ClosedBoltWeapon) { ClosedBoltWeapon val = (ClosedBoltWeapon)firearm; val.UsesDelinker = tracker.OrigUsesDelinker; val.DelinkerSystem = tracker.OrigDelinkerSystem; } else if (firearm is OpenBoltReceiver) { OpenBoltReceiver val2 = (OpenBoltReceiver)firearm; val2.UsesDelinker = tracker.OrigUsesDelinker; val2.DelinkerSystem = tracker.OrigDelinkerSystem; } } private void OnDrawGizmos() { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_021b: 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_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: 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_027d: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_0292: 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_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: 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_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_0315: 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_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0300: 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_0304: 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) //IL_032e: Unknown result type (might be due to invalid IL or missing references) if (!OverridesBeltFed || !((Object)(object)BeltExitPointOverride != (Object)null) || !((Object)(object)FeedTrayEntPos != (Object)null) || !((Object)(object)BeltDisplayData != (Object)null)) { return; } Mesh val = null; if ((Object)(object)CustomProxyPrefab != (Object)null) { MeshFilter componentInChildren = CustomProxyPrefab.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { val = componentInChildren.sharedMesh; } } else if (BeltDisplayData.ProxyRounds != null && BeltDisplayData.ProxyRounds.Count > 0 && (Object)(object)BeltDisplayData.ProxyRounds[0] != (Object)null) { MeshFilter[] componentsInChildren = ((Component)BeltDisplayData.ProxyRounds[0]).GetComponentsInChildren(true); if (componentsInChildren.Length > 0) { val = componentsInChildren[0].sharedMesh; } } Vector3 position = BeltExitPointOverride.position; Vector3 position2 = FeedTrayEntPos.position; Vector3 val2 = Vector3.Lerp(position, position2, 0.5f) + Vector3.down * BeltGravitySag; float num = 0f; Vector3 val3 = position; for (int i = 1; i <= 10; i++) { float num2 = (float)i / 10f; Vector3 val4 = (1f - num2) * (1f - num2) * position + 2f * (1f - num2) * num2 * val2 + num2 * num2 * position2; num += Vector3.Distance(val3, val4); val3 = val4; } float num3 = BeltDisplayData.DistanceBetweenRounds; if (num3 <= 0f) { num3 = 0.03f; } int num4 = Mathf.CeilToInt(num / num3); Vector3 val5 = position; for (int j = 0; j < num4; j++) { float num5 = (float)j / (float)(num4 - 1); Vector3 val6 = (1f - num5) * (1f - num5) * position + 2f * (1f - num5) * num5 * val2 + num5 * num5 * position2; Vector3 val7 = 2f * (1f - num5) * (val2 - position) + 2f * num5 * (position2 - val2); Vector3 val8 = ((Vector3)(ref val7)).normalized; if (val8 == Vector3.zero) { val8 = ((Component)this).transform.forward; } Vector3 val9 = ((Component)this).transform.up; if (Mathf.Abs(Vector3.Dot(val8, val9)) > 0.95f) { val9 = ((Component)this).transform.forward; } Quaternion val10 = Quaternion.LookRotation(val8, val9) * Quaternion.Euler(BulletRotationOffset); if ((Object)(object)val != (Object)null) { Gizmos.color = Color.white; Gizmos.DrawMesh(val, val6, val10, Vector3.one); } else { Gizmos.color = Color.green; Gizmos.DrawSphere(val6, 0.012f); } val5 = val6; } } } public class FirearmMagazineAddonStateTracker : MonoBehaviour { public int ActiveAddonCount = 0; public bool OriginalUsesMagazines; public FireArmMagazineType OriginalMagazineType; public Transform OriginalMagazineMountPos; public Transform OriginalMagazineEjectPos; public bool OriginalUsesClips; public FireArmClipType OriginalClipType; public Transform OriginalClipMountPos; public Transform OriginalClipEjectPos; public GameObject OriginalClipTrigger; public bool OriginalUsesTopCover; public bool OriginalIsTopCoverUp; public FireArmRoundType OriginalRoundType; public bool OriginalUsesBelts; public FVRFirearmBeltDisplayData OriginalBeltDD; public Transform OriginalMagazineMountPosFallback; public Transform OriginalMagazineEjectPosFallback; public Transform OriginalBeltBoxMountPos; public Transform OriginalBeltBoxEjectPos; public bool OriginalRequiresBoltBack; public bool OrigUsesDelinker; public ParticleSystem OrigDelinkerSystem; public bool OrigMagReleaseState; public AudioEvent OriginalMagazineInAudio; public AudioEvent OriginalMagazineOutAudio; public FVRFireArmMagazine OriginalReceiverMagazine; public List DisabledReceiverGrabTriggers = new List(); public void CacheReceiverOriginalStates(FVRFireArm value) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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) OriginalUsesMagazines = value.UsesMagazines; OriginalMagazineType = value.MagazineType; OriginalMagazineMountPos = value.MagazineMountPos; OriginalMagazineEjectPos = value.MagazineEjectPos; OriginalUsesClips = value.UsesClips; OriginalClipType = value.ClipType; OriginalClipMountPos = value.ClipMountPos; OriginalClipEjectPos = value.ClipEjectPos; OriginalClipTrigger = value.ClipTrigger; OriginalUsesTopCover = value.UsesTopCover; OriginalIsTopCoverUp = value.IsTopCoverUp; OriginalRoundType = value.RoundType; OriginalUsesBelts = value.UsesBelts; OriginalBeltDD = value.BeltDD; OriginalBeltBoxMountPos = value.BeltBoxMountPos; OriginalBeltBoxEjectPos = value.BeltBoxEjectPos; OriginalRequiresBoltBack = value.RequiresBoltBackToSeatBelt; if ((Object)(object)value.AudioClipSet != (Object)null) { OriginalMagazineInAudio = value.AudioClipSet.MagazineIn; OriginalMagazineOutAudio = value.AudioClipSet.MagazineOut; } OriginalReceiverMagazine = value.Magazine; } } public class AttachableMeleeStock : FVRFireArmAttachmentInterface { public Transform Point_Stock; public override void OnAttach() { ((FVRFireArmAttachmentInterface)this).OnAttach(); FVRFireArmAttachmentMount val = ((!((Object)(object)base.Attachment != (Object)null)) ? null : base.Attachment.curMount); if ((Object)(object)val == (Object)null) { return; } FVRFireArmAttachmentMount rootMount = val.GetRootMount(); FVRPhysicalObject obj = ((!((Object)(object)rootMount != (Object)null)) ? val.Parent : rootMount.Parent); FVRFireArm val2 = (FVRFireArm)(object)((obj is FVRFireArm) ? obj : null); if (!((Object)(object)val2 == (Object)null)) { FVRFireArmAttachment attachment = base.Attachment; AttachableMeleeWeapon val3 = (AttachableMeleeWeapon)(object)((attachment is AttachableMeleeWeapon) ? attachment : null); if ((Object)(object)val3 != (Object)null) { val2.RegisterAttachedMeleeWeapon(val3); } if ((Object)(object)Point_Stock != (Object)null) { val2.StockPos = Point_Stock; val2.HasActiveShoulderStock = true; } } } public override void OnDetach() { FVRFireArmAttachmentMount val = ((!((Object)(object)base.Attachment != (Object)null)) ? null : base.Attachment.curMount); if ((Object)(object)val != (Object)null) { FVRFireArmAttachmentMount rootMount = val.GetRootMount(); FVRPhysicalObject obj = ((!((Object)(object)rootMount != (Object)null)) ? val.Parent : rootMount.Parent); FVRFireArm val2 = (FVRFireArm)(object)((obj is FVRFireArm) ? obj : null); if ((Object)(object)val2 != (Object)null) { if (base.Attachment is AttachableMeleeWeapon) { val2.RegisterAttachedMeleeWeapon((AttachableMeleeWeapon)null); } if ((Object)(object)Point_Stock != (Object)null) { val2.StockPos = null; val2.HasActiveShoulderStock = false; } } } ((FVRFireArmAttachmentInterface)this).OnDetach(); } } public class ExpandedAmmoDisplay : MonoBehaviour { [Header("Ammo Counter Settings")] [Tooltip("Text to display ammo left in the gun.")] public Text UItext; [Tooltip("Text to display maximum ammo.")] public Text MaxAmmoText; [Tooltip("Text to display the type of ammo.")] public Text ammoTypeText; [Tooltip("Adds a minimum character count. See tooltip for MinCharLength for more.")] public bool AddMinCharLength; [Tooltip("i.e if MinCharLength is 2 and the amount of rounds left is 5, it will display 05 instead of 5.")] public int MinCharLength; [Tooltip("Will not instantly be the correct amount of rounds, but will tick up/down until it is.")] public bool enableDispLerp; [Tooltip("MaxAmmo will also lerp according to the DispLerpAmt")] public bool enableLerpForMaxAmmo; [Tooltip("EnabledObjects will also lerp according to the DispLerpAmt")] public bool enableLerpForEnabledObjects; [Tooltip("From 0-1. The % amount moved towards its correct amount every 50th of a second.")] [Range(0f, 0.2f)] public float DispLerpAmt; [Header("Alternate Displays")] [Tooltip("Enables enabling/disabling objects based on rounds left in mag.")] public bool EnabledObjects; [Tooltip("Object enabled when there is no magazine.")] public GameObject ObjectWhenEmpty; [Tooltip("Element no. corresponds to rounds left. 0 means no rounds, 1 means one round. Enables the 5th object if there are 5 rounds, and so on.")] public List Objects; [Tooltip("Enables all objects under the round count. Enables the 0th, 1st, 2nd, 3rd objects if there are 3 rounds left, and so on.")] public bool EnableAllUnderAmount; [Tooltip("Overrides Objects. #0 means Objects' #0 displays from 0% to #0%, #1 means Objects' #1 displays from #0% to #1%, etc- written normally, not mathmatically (e.g 57.32)")] public bool EnableBasedOnPercentage; public List ObjectPercentages; [Header("Fire Mode Display")] [Tooltip("Text to display the fire mode (e.g., Safe, Single, FullAuto, Burst).")] public Text fireModeText; [Tooltip("Image to display fire mode visually.")] public Image fireModeImage; [Tooltip("Sprites for each fire mode: 0=Safe, 1=Single, 2=FullAuto, 3=Burst, 4=Other.")] public Sprite[] fireModeSprites; [Header("Low Ammo Warning")] [Tooltip("Enable sound and blink effects when ammo drops to a percentage of max.")] public bool enableLowAmmoWarning; [Tooltip("Percentage of max ammo at which the warning triggers (e.g. 25 means 25%).")] [Range(0f, 100f)] public float lowAmmoThresholdPercent = 25f; [Tooltip("AudioSource used to play warning sounds.")] public AudioSource warningAudioSource; [Tooltip("Sound played once when ammo drops to or below the low ammo threshold.")] public AudioClip lowAmmoClip; [Tooltip("Sound played once when ammo is fully depleted (0 rounds).")] public AudioClip depletedAmmoClip; [Tooltip("Enable blinking on the ammo text when at or below the low ammo threshold.")] public bool enableLowAmmoBlink; [Tooltip("How many times per second the text blinks on/off.")] public float blinkRate = 4f; [Header("Chamber Indicator (optional)")] [Tooltip("Enable a visual/text indicator when there is a round in the chamber.")] public bool showChamberIndicator = false; [Tooltip("If true the indicator will use an Image; otherwise it will use Text.")] public bool chamberIndicatorUseImage = true; [Tooltip("Image used to indicate a round is chambered. Assign only if using image mode.")] public Image chamberIndicatorImage; [Tooltip("Text used to indicate a round is chambered. Assign only if using text mode.")] public Text chamberIndicatorText; [Tooltip("Text shown when a round is chambered (used when chamberIndicatorUseImage == false).")] public string chamberIndicatorString = "CH"; private FVRFireArm _fa; private FVRFireArmMagazine _mag; private FVRFirearmMovingProxyRound[] proxies; private FVRFireArmChamber[] chambers; private int lastAmountOfBullets; private int lastAmountOfMaxBullets; private int lastAmountOfBulletsForEnableObjects; private bool _hasPlayedLowAmmoSound; private bool _hasPlayedDepletedSound; private bool _isBlinking; private float _blinkTimer; private int _previousAmmoCount = -1; private bool _hadMagLastFrame; private bool _isChamberIndicatorImageNotNull; private bool _isChamberIndicatorTextNotNull; private bool _isUItextNotNull; private bool _isMaxAmmoTextNotNull; private bool _isammoTypeTextNotNull; private bool _isfireModeTextNotNull; private bool _isfireModeImageNotNull; private void Start() { NullCheck(); } private void GetFirearmAndMag() { _fa = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); if ((Object)(object)_fa != (Object)null) { _mag = _fa.Magazine; if (chambers == null) { chambers = ((_fa.GetChamberRoundList() == null) ? null : _fa.GetChambers())?.ToArray(); } proxies = ((Component)_fa).GetComponentsInChildren(true); } else { _mag = null; chambers = null; proxies = null; } } private void Update() { GetFirearmAndMag(); int ammoCount = GetAmmoCount(); int maxAmmoCount = GetMaxAmmoCount(); bool flag = (Object)(object)_mag != (Object)null; if (_isUItextNotNull) { string text = CalculateAmmoCounterAmount(ammoCount, ref lastAmountOfBullets, enableDispLerp, DispLerpAmt, AddMinCharLength, MinCharLength); UItext.text = text; } if (_isMaxAmmoTextNotNull) { string text2 = CalculateAmmoCounterAmount(maxAmmoCount, ref lastAmountOfMaxBullets, enableLerpForMaxAmmo, DispLerpAmt, AddMinCharLength, MinCharLength); MaxAmmoText.text = text2; } if (_isammoTypeTextNotNull) { ammoTypeText.text = GetAmmoType(); } if (_isfireModeTextNotNull || _isfireModeImageNotNull) { string fireMode = GetFireMode(); if (_isfireModeTextNotNull) { fireModeText.text = fireMode; } if (_isfireModeImageNotNull && fireModeSprites != null && fireModeSprites.Length > 0) { int spriteIndexForMode = GetSpriteIndexForMode(fireMode); if (spriteIndexForMode >= 0 && spriteIndexForMode < fireModeSprites.Length) { fireModeImage.sprite = fireModeSprites[spriteIndexForMode]; } } } if (EnabledObjects) { int num = int.Parse(CalculateAmmoCounterAmount(ammoCount, ref lastAmountOfBulletsForEnableObjects, enableLerpForEnabledObjects, DispLerpAmt)); if (EnableBasedOnPercentage) { SetEnabledObjectsPercentage(num); } else { SetEnabledObjects(num); } } if (enableLowAmmoWarning) { UpdateLowAmmoWarning(ammoCount, maxAmmoCount, flag); } else { ResetWarningState(); } if (showChamberIndicator) { int num2 = 0; if (chambers != null) { num2 = chambers.Count((FVRFireArmChamber chamber) => chamber.IsFull && !chamber.IsSpent); } bool flag2 = num2 > 0; if (chamberIndicatorUseImage) { if (_isChamberIndicatorImageNotNull && (Object)(object)chamberIndicatorImage != (Object)null) { ((Component)chamberIndicatorImage).gameObject.SetActive(flag2); } } else if (_isChamberIndicatorTextNotNull && (Object)(object)chamberIndicatorText != (Object)null) { ((Component)chamberIndicatorText).gameObject.SetActive(flag2); if (flag2) { chamberIndicatorText.text = chamberIndicatorString; } } } else { if (_isChamberIndicatorImageNotNull && (Object)(object)chamberIndicatorImage != (Object)null) { ((Component)chamberIndicatorImage).gameObject.SetActive(false); } if (_isChamberIndicatorTextNotNull && (Object)(object)chamberIndicatorText != (Object)null) { ((Component)chamberIndicatorText).gameObject.SetActive(false); } } _previousAmmoCount = ammoCount; _hadMagLastFrame = flag; } private void UpdateLowAmmoWarning(int currentAmmo, int maxAmmo, bool hasMag) { if (!hasMag) { ResetWarningState(); return; } bool flag = hasMag && !_hadMagLastFrame; bool flag2 = false; bool flag3 = false; if (maxAmmo > 0) { if (currentAmmo > 0) { float num = (float)currentAmmo / (float)maxAmmo * 100f; flag2 = num <= lowAmmoThresholdPercent; } if (_previousAmmoCount > 0) { float num2 = (float)_previousAmmoCount / (float)maxAmmo * 100f; flag3 = num2 <= lowAmmoThresholdPercent; } } if (flag2 && (!flag3 || flag)) { PlayWarningClip(lowAmmoClip); } if (currentAmmo <= 0) { bool flag4 = _previousAmmoCount > 0; bool flag5 = flag; if ((flag4 || flag5) && !_hasPlayedDepletedSound) { PlayWarningClip(depletedAmmoClip); _hasPlayedDepletedSound = true; } } if (maxAmmo > 0 && currentAmmo > 0) { float num3 = (float)currentAmmo / (float)maxAmmo * 100f; if (num3 > lowAmmoThresholdPercent) { _hasPlayedDepletedSound = false; } } if (enableLowAmmoBlink && _isUItextNotNull && (flag2 || _hasPlayedDepletedSound)) { _isBlinking = true; _blinkTimer += Time.deltaTime; float num4 = ((!(blinkRate > 0f)) ? 1f : (1f / blinkRate)); bool enabled = _blinkTimer % num4 < num4 * 0.5f; ((Behaviour)UItext).enabled = enabled; } else if (_isBlinking) { _isBlinking = false; _blinkTimer = 0f; if (_isUItextNotNull) { ((Behaviour)UItext).enabled = true; } } } private void ResetWarningState() { if (_isBlinking) { _isBlinking = false; _blinkTimer = 0f; if (_isUItextNotNull) { ((Behaviour)UItext).enabled = true; } } _hasPlayedLowAmmoSound = false; _hasPlayedDepletedSound = false; } private void PlayWarningClip(AudioClip clip) { if ((Object)(object)clip != (Object)null && (Object)(object)warningAudioSource != (Object)null) { warningAudioSource.PlayOneShot(clip); } } private int GetAmmoCount() { if ((Object)(object)_mag != (Object)null) { return _mag.m_numRounds; } int num = 0; if ((Object)(object)_fa != (Object)null) { if (chambers != null) { num += chambers.Count((FVRFireArmChamber chamber) => chamber.IsFull && !chamber.IsSpent); } if (proxies != null) { FVRFirearmMovingProxyRound[] array = proxies; foreach (FVRFirearmMovingProxyRound val in array) { if (val.IsFull) { num++; } } } if ((Object)(object)_fa.BeltDD != (Object)null) { num += _fa.BeltDD.m_roundsOnBelt; } } return num; } private int GetMaxAmmoCount() { if ((Object)(object)_mag != (Object)null) { return _mag.m_capacity; } if ((Object)(object)_fa != (Object)null && !_fa.UsesMagazines) { return (chambers != null) ? chambers.Length : 0; } return 0; } private string GetAmmoType() { //IL_00d5: 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_0037: 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_0080: 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) if ((Object)(object)_fa != (Object)null) { List chamberRoundList = _fa.GetChamberRoundList(); if (chamberRoundList != null && chamberRoundList.Count > 0) { return AM.GetFullRoundName(_fa.RoundType, chamberRoundList[0]); } if ((Object)(object)_fa.BeltDD != (Object)null && _fa.BeltDD.m_roundsOnBelt > 0) { return AM.GetFullRoundName(_fa.RoundType, _fa.BeltDD.BeltRounds[0].LR_Class); } } if ((Object)(object)_mag != (Object)null && _mag.m_numRounds > 0) { return AM.GetFullRoundName(_mag.RoundType, _mag.LoadedRounds[0].LR_Class); } return string.Empty; } private string GetFireMode() { if ((Object)(object)_fa == (Object)null) { return "N/A"; } FVRFireArm fa = _fa; Handgun val = (Handgun)(object)((fa is Handgun) ? fa : null); if ((Object)(object)val == (Object)null) { return "N/A"; } if (val.IsSafetyEngaged) { return "Safe"; } if (val.FireSelectorModes != null && val.FireSelectorModes.Length > 0) { FireSelectorMode val2 = val.FireSelectorModes[val.FireSelectorModeIndex]; return ((object)Unsafe.As(ref val2.ModeType)/*cast due to .constrained prefix*/).ToString(); } return "N/A"; } private int GetSpriteIndexForMode(string mode) { return mode switch { "Safe" => 0, "Single" => 1, "FullAuto" => 2, "Burst" => 3, _ => 4, }; } public static string CalculateAmmoCounterAmount(int currentammo, ref int lastammo, bool lerp = false, float lerpAmt = 0f, bool pad = false, int padAmt = 0) { if (lerp) { currentammo = LerpInt(lastammo, currentammo, lerpAmt); } string text = currentammo.ToString(); if (pad) { text = PadStringNumberToAmt(text, padAmt); } lastammo = currentammo; return text; } public static string PadStringNumberToAmt(string str, int minCharLength) { int num = minCharLength - str.Length; for (int i = 0; i < num; i++) { str = "0" + str; } return str; } public static int LerpInt(int a, int b, float lerp) { bool flag = a == 0; a = Mathf.CeilToInt(Mathf.Lerp((float)a, (float)b, lerp)); if (a == 1 && flag) { a = 0; } return a; } private void SetEnabledObjects(int amt) { amt = Mathf.Clamp(amt, 0, Objects.Count - 1); for (int i = 0; i < Objects.Count; i++) { Objects[i].SetActive(false); } if ((Object)(object)ObjectWhenEmpty != (Object)null) { ObjectWhenEmpty.SetActive(false); } if ((Object)(object)_mag == (Object)null && (Object)(object)ObjectWhenEmpty != (Object)null) { ObjectWhenEmpty.SetActive(true); return; } for (int j = 0; j < Objects.Count; j++) { if (j < amt) { if (EnableAllUnderAmount) { Objects[j].SetActive(true); } } else if (j == amt) { Objects[j].SetActive(true); } } } private void SetEnabledObjectsPercentage(int amt) { amt = Mathf.Clamp(amt, 0, Objects.Count - 1); int maxAmmoCount = GetMaxAmmoCount(); if (maxAmmoCount <= 0) { return; } float num = (float)amt / (float)maxAmmoCount; for (int i = 0; i < Objects.Count; i++) { Objects[i].SetActive(false); } if ((Object)(object)ObjectWhenEmpty != (Object)null) { ObjectWhenEmpty.SetActive(false); } if ((Object)(object)_mag == (Object)null && (Object)(object)ObjectWhenEmpty != (Object)null) { ObjectWhenEmpty.SetActive(true); return; } for (int j = 0; j < Objects.Count; j++) { float num2 = ObjectPercentages[j] / 100f; float num3 = 0f; if (j > 0) { num3 = ObjectPercentages[j - 1] / 100f; } if (!(num > num2)) { continue; } if (num > num3) { if (EnableAllUnderAmount) { Objects[j].SetActive(true); } } else { Objects[j].SetActive(true); } } } public void NullCheck() { _isammoTypeTextNotNull = (Object)(object)ammoTypeText != (Object)null; _isMaxAmmoTextNotNull = (Object)(object)MaxAmmoText != (Object)null; _isUItextNotNull = (Object)(object)UItext != (Object)null; _isfireModeTextNotNull = (Object)(object)fireModeText != (Object)null; _isfireModeImageNotNull = (Object)(object)fireModeImage != (Object)null; _isChamberIndicatorImageNotNull = (Object)(object)chamberIndicatorImage != (Object)null; _isChamberIndicatorTextNotNull = (Object)(object)chamberIndicatorText != (Object)null; } } public class RootGrabPointAddon : MonoBehaviour, IPartFireArmRequirement { [Header("Debugging")] [Tooltip("Enable this to print comprehensive logs to the BepInEx / Unity console.")] public bool EnableDebug = false; [Header("Root Grab Point Setup")] [Tooltip("The GameObject on your stock prefab that contains the reference trigger collider.")] public GameObject ColliderReference; [Tooltip("If checked, the original trigger colliders on the firearm's root object will be disabled while this stock is mounted.")] public bool ReplaceExistingCollider = false; private FVRFireArm _firearm; private Collider[] _origColliders; private Collider _addedCollider; private bool _wasHeldLastFrame = false; private bool _origEndInteractionIfDistant = true; public FVRFireArm FireArm { get { return _firearm; } set { //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: 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_01f2: Expected O, but got Unknown //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_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024c: 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_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Expected O, but got Unknown //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)value != (Object)null) { _firearm = value; if (EnableDebug) { Debug.Log((object)("[RootGrabPointDebug] OnAttach triggered. FireArm set to: " + ((Object)((Component)_firearm).gameObject).name)); } _wasHeldLastFrame = ((FVRInteractiveObject)_firearm).IsHeld; _origEndInteractionIfDistant = ((FVRInteractiveObject)_firearm).EndInteractionIfDistant; if ((Object)(object)ColliderReference == (Object)null) { ModularWorkshopManager.LogError((MonoBehaviour)(object)this, "ColliderReference is null! RootGrabPointAddon cannot run."); return; } Collider component = ColliderReference.GetComponent(); if ((Object)(object)component == (Object)null) { ModularWorkshopManager.LogError((MonoBehaviour)(object)this, "ColliderReference does not contain a collider! RootGrabPointAddon cannot run."); return; } _origColliders = ((Component)_firearm).GetComponents(); if (EnableDebug) { Debug.Log((object)("[RootGrabPointDebug] Scanned root object for colliders. Found: " + ((_origColliders != null) ? _origColliders.Length : 0))); } if (ReplaceExistingCollider && _origColliders != null) { if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] ReplaceExistingCollider is true. Disabling all root receiver colliders."); } for (int i = 0; i < _origColliders.Length; i++) { if ((Object)(object)_origColliders[i] != (Object)null) { _origColliders[i].enabled = false; } } } component.enabled = false; if (EnableDebug) { Debug.Log((object)("[RootGrabPointDebug] Adding new collider component directly to root firearm: " + ((Object)((Component)_firearm).gameObject).name)); } if (component is BoxCollider) { BoxCollider val = (BoxCollider)component; BoxCollider val2 = ((Component)_firearm).gameObject.AddComponent(); val2.size = Vector3.Scale(val.size, ((Component)val).transform.lossyScale); _addedCollider = (Collider)(object)val2; } else if (component is SphereCollider) { SphereCollider val3 = (SphereCollider)component; SphereCollider val4 = ((Component)_firearm).gameObject.AddComponent(); val4.radius = val3.radius * Mathf.Max(new float[3] { ((Component)val3).transform.lossyScale.x, ((Component)val3).transform.lossyScale.y, ((Component)val3).transform.lossyScale.z }); _addedCollider = (Collider)(object)val4; } else if (component is CapsuleCollider) { CapsuleCollider val5 = (CapsuleCollider)component; CapsuleCollider val6 = ((Component)_firearm).gameObject.AddComponent(); val6.radius = val5.radius * Mathf.Max(((Component)val5).transform.lossyScale.x, ((Component)val5).transform.lossyScale.z); val6.height = val5.height * ((Component)val5).transform.lossyScale.y; val6.direction = val5.direction; _addedCollider = (Collider)(object)val6; } if (!((Object)(object)_addedCollider != (Object)null)) { return; } _addedCollider.isTrigger = true; if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] Successfully configured root trigger collider component."); } FieldInfo field = typeof(FVRInteractiveObject).GetField("m_colliders", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)field == null) { return; } Collider[] array = (Collider[])field.GetValue(_firearm); if (array != null) { if (EnableDebug) { Debug.Log((object)("[RootGrabPointDebug] Located m_colliders array via Reflection. Original size: " + array.Length)); } bool flag = false; for (int j = 0; j < array.Length; j++) { if ((Object)(object)array[j] == (Object)(object)_addedCollider) { flag = true; break; } } if (!flag) { Collider[] array2 = (Collider[])(object)new Collider[array.Length + 1]; Array.Copy(array, array2, array.Length); array2[^1] = _addedCollider; field.SetValue(_firearm, array2); if (EnableDebug) { Debug.Log((object)("[RootGrabPointDebug] m_colliders updated. New size: " + array2.Length)); } } } else { field.SetValue(_firearm, new Collider[1] { _addedCollider }); } } else { if (!((Object)(object)value == (Object)null) || !((Object)(object)_firearm != (Object)null)) { return; } if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] OnDetach triggered. Cleaning up grab point addon."); } if ((Object)(object)_addedCollider != (Object)null) { FieldInfo field2 = typeof(FVRInteractiveObject).GetField("m_colliders", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)field2 != null) { Collider[] array3 = (Collider[])field2.GetValue(_firearm); if (array3 != null) { List list = new List(); for (int k = 0; k < array3.Length; k++) { if ((Object)(object)array3[k] != (Object)(object)_addedCollider && (Object)(object)array3[k] != (Object)null) { list.Add(array3[k]); } } Collider[] value2 = list.ToArray(); field2.SetValue(_firearm, value2); } } Object.DestroyImmediate((Object)(object)_addedCollider); if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] Destroyed root trigger collider component instantly."); } } if (ReplaceExistingCollider && _origColliders != null) { for (int l = 0; l < _origColliders.Length; l++) { if ((Object)(object)_origColliders[l] != (Object)null) { _origColliders[l].enabled = true; } } } if ((Object)(object)ColliderReference != (Object)null) { Collider component2 = ColliderReference.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.enabled = true; } } ((FVRInteractiveObject)_firearm).EndInteractionIfDistant = _origEndInteractionIfDistant; _firearm = null; _origColliders = null; _wasHeldLastFrame = false; if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] Cleanup complete."); } } } } public void Awake() { if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] Awake() started on RootGrabPointAddon."); } if ((Object)(object)ColliderReference != (Object)null) { Collider component = ColliderReference.GetComponent(); if ((Object)(object)component == (Object)null) { ModularWorkshopManager.LogWarning((MonoBehaviour)(object)this, "ColliderReference " + ((Object)ColliderReference).name + " does not contain a collider! Setup may fail."); } else { component.enabled = false; } } else { ModularWorkshopManager.LogError((MonoBehaviour)(object)this, "ColliderReference is empty! RootGrabPointAddon will not function."); } } private void Update() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_01ad: 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_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_firearm == (Object)null || (Object)(object)_addedCollider == (Object)null || (Object)(object)ColliderReference == (Object)null) { return; } Collider component = ColliderReference.GetComponent(); if ((Object)(object)component == (Object)null) { return; } bool isHeld = ((FVRInteractiveObject)_firearm).IsHeld; if (isHeld != _wasHeldLastFrame) { if (isHeld) { _origEndInteractionIfDistant = ((FVRInteractiveObject)_firearm).EndInteractionIfDistant; ((FVRInteractiveObject)_firearm).EndInteractionIfDistant = false; if (EnableDebug) { string arg = ((!((Object)(object)((FVRInteractiveObject)_firearm).m_hand != (Object)null)) ? "Unknown Hand" : ((Object)((Component)((FVRInteractiveObject)_firearm).m_hand).gameObject).name); string text = $"[RootGrabPointDebug] GRAB EVENT DETECTED: Weapon successfully held by {arg}"; Debug.Log((object)text); } } else { ((FVRInteractiveObject)_firearm).EndInteractionIfDistant = _origEndInteractionIfDistant; if (EnableDebug) { Debug.Log((object)"[RootGrabPointDebug] RELEASE EVENT DETECTED: Weapon released."); } } _wasHeldLastFrame = isHeld; } Vector3 val = Vector3.zero; if (component is BoxCollider) { val = ((Component)component).transform.TransformPoint(((BoxCollider)component).center); } else if (component is SphereCollider) { val = ((Component)component).transform.TransformPoint(((SphereCollider)component).center); } else if (component is CapsuleCollider) { val = ((Component)component).transform.TransformPoint(((CapsuleCollider)component).center); } Vector3 center = ((Component)_firearm).transform.InverseTransformPoint(val); if (_addedCollider is BoxCollider) { ((BoxCollider)_addedCollider).center = center; } else if (_addedCollider is SphereCollider) { ((SphereCollider)_addedCollider).center = center; } else if (_addedCollider is CapsuleCollider) { ((CapsuleCollider)_addedCollider).center = center; } } } public class SpadeGripSecondaryHandle : FVRInteractiveObject, IPartFireArmRequirement { [Header("Debugging")] [Tooltip("Enable this to print comprehensive logs to the BepInEx / Unity console.")] public bool EnableDebug = false; private FVRFireArm _firearm; private float _lastTriggerVal = 0f; private float _fireDelayTimer = 0f; private bool _wasHeldLastFrame = false; private FieldInfo _triggerField; private MethodInfo _inputMethod; private FVRFireArmRecoilProfile _recoilProfile; private float _origVerticalRot; private float _origHorizontalRot; private float _origZLinear; private bool _recoilBackedUp = false; public FVRFireArm FireArm { get { return _firearm; } set { if ((Object)(object)value != (Object)null) { _firearm = value; _wasHeldLastFrame = ((FVRInteractiveObject)this).IsHeld; if ((Object)(object)_firearm.RecoilProfile != (Object)null) { _recoilProfile = _firearm.RecoilProfile; _origVerticalRot = _recoilProfile.VerticalRotPerShot; _origHorizontalRot = _recoilProfile.HorizontalRotPerShot; _origZLinear = _recoilProfile.ZLinearPerShot; _recoilBackedUp = true; } Type type = ((object)_firearm).GetType(); _triggerField = type.GetField("m_triggerFloat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _inputMethod = type.GetMethod("UpdateInputAndAnimate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (EnableDebug) { Debug.Log((object)("[SpadeGripDebug] OnAttach called. FireArm set to: " + ((Object)((Component)_firearm).gameObject).name)); Debug.Log((object)("[SpadeGripDebug] Reflection: m_triggerFloat field found = " + ((object)_triggerField != null))); Debug.Log((object)("[SpadeGripDebug] Reflection: UpdateInputAndAnimate method found = " + ((object)_inputMethod != null))); } } else { if (EnableDebug) { Debug.Log((object)"[SpadeGripDebug] OnDetach called (FireArm set to null)."); } RestoreOriginalRecoil(); if ((Object)(object)_firearm != (Object)null && (Object)(object)((Component)_firearm).transform.parent == (Object)(object)base.m_hand.WholeRig) { ((Component)_firearm).transform.SetParent((Transform)null, true); ((FVRPhysicalObject)_firearm).RootRigidbody.isKinematic = false; } _firearm = null; _recoilProfile = null; _wasHeldLastFrame = false; _triggerField = null; _inputMethod = null; } } } public override void Awake() { ((FVRInteractiveObject)this).Awake(); base.EndInteractionIfDistant = false; if (EnableDebug) { Debug.Log((object)"[SpadeGripDebug] Secondary handle Awake completed. Distance-drop disabled."); } } public override void TestHandDistance() { } public override void BeginInteraction(FVRViveHand hand) { ((FVRInteractiveObject)this).BeginInteraction(hand); if (EnableDebug) { Debug.Log((object)("[SpadeGripDebug] Secondary handle GRABBED by hand: " + ((!((Object)(object)hand != (Object)null)) ? "null" : ((Object)((Component)hand).gameObject).name))); } } public override void EndInteraction(FVRViveHand hand) { ((FVRInteractiveObject)this).EndInteraction(hand); if (EnableDebug) { Debug.Log((object)"[SpadeGripDebug] Secondary handle RELEASED."); } } private void ProcessSpadeGripLogic() { if ((Object)(object)_firearm == (Object)null) { return; } bool isHeld = ((FVRInteractiveObject)this).IsHeld; if (isHeld != _wasHeldLastFrame) { if (EnableDebug) { if (isHeld) { string text = ((!((Object)(object)base.m_hand != (Object)null)) ? "Unknown Hand" : ((Object)((Component)base.m_hand).gameObject).name); Debug.Log((object)("[SpadeGripDebug] GRAB EVENT DETECTED: Secondary grip held by " + text)); } else { Debug.Log((object)"[SpadeGripDebug] RELEASE EVENT DETECTED: Secondary grip released."); } } _wasHeldLastFrame = isHeld; } if (isHeld && !((FVRInteractiveObject)_firearm).IsHeld) { if ((Object)(object)((Component)_firearm).transform.parent != (Object)(object)base.m_hand.WholeRig) { ((FVRPhysicalObject)_firearm).RootRigidbody.isKinematic = true; ((Component)_firearm).transform.SetParent(base.m_hand.WholeRig, true); if (EnableDebug) { Debug.Log((object)"[SpadeGripDebug] Gun parented to off-hand. Tracking active."); } } } else if (((FVRInteractiveObject)_firearm).IsHeld && (Object)(object)((Component)_firearm).transform.parent == (Object)(object)base.m_hand.WholeRig) { ((Component)_firearm).transform.SetParent((Transform)null, true); ((FVRPhysicalObject)_firearm).RootRigidbody.isKinematic = false; if (EnableDebug) { Debug.Log((object)"[SpadeGripDebug] Gun parentage restored to primary hand."); } } float num = ((!((Object)(object)((FVRInteractiveObject)_firearm).m_hand != (Object)null)) ? 0f : ((FVRInteractiveObject)_firearm).m_hand.Input.TriggerFloat); float num2 = ((!((Object)(object)base.m_hand != (Object)null)) ? 0f : base.m_hand.Input.TriggerFloat); float num3 = Mathf.Max(num, num2); if (EnableDebug && Mathf.Abs(num3 - _lastTriggerVal) > 0.05f) { string text2 = string.Format("[SpadeGripDebug] Trigger Delta. Primary: {0}, Secondary: {1}, Active (Injected): {2}", num.ToString("F2"), num2.ToString("F2"), num3.ToString("F2")); Debug.Log((object)text2); _lastTriggerVal = num3; } if ((object)_triggerField != null && (object)_inputMethod != null && (Object)(object)((FVRInteractiveObject)_firearm).m_hand != (Object)null) { _triggerField.SetValue(_firearm, num3); _inputMethod.Invoke(_firearm, new object[1] { ((FVRInteractiveObject)_firearm).m_hand }); } if (_recoilBackedUp && (Object)(object)_recoilProfile != (Object)null) { if ((Object)(object)((FVRInteractiveObject)_firearm).m_hand != (Object)null && isHeld) { _recoilProfile.VerticalRotPerShot = _origVerticalRot * 0.45f; _recoilProfile.HorizontalRotPerShot = _origHorizontalRot * 0.45f; _recoilProfile.ZLinearPerShot = _origZLinear * 0.45f; } else { _recoilProfile.VerticalRotPerShot = _origVerticalRot; _recoilProfile.HorizontalRotPerShot = _origHorizontalRot; _recoilProfile.ZLinearPerShot = _origZLinear; } } } private void RestoreOriginalRecoil() { if (_recoilBackedUp && (Object)(object)_recoilProfile != (Object)null) { _recoilProfile.VerticalRotPerShot = _origVerticalRot; _recoilProfile.HorizontalRotPerShot = _origHorizontalRot; _recoilProfile.ZLinearPerShot = _origZLinear; _recoilBackedUp = false; } } public override void FVRUpdate() { ((FVRInteractiveObject)this).FVRUpdate(); if ((Object)(object)_firearm == (Object)null) { _firearm = ((Component)this).GetComponentInParent(); if ((Object)(object)_firearm != (Object)null) { _wasHeldLastFrame = ((FVRInteractiveObject)this).IsHeld; if ((Object)(object)_firearm.RecoilProfile != (Object)null) { _recoilProfile = _firearm.RecoilProfile; _origVerticalRot = _recoilProfile.VerticalRotPerShot; _origHorizontalRot = _recoilProfile.HorizontalRotPerShot; _origZLinear = _recoilProfile.ZLinearPerShot; _recoilBackedUp = true; } Type type = ((object)_firearm).GetType(); _triggerField = type.GetField("m_triggerFloat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _inputMethod = type.GetMethod("UpdateInputAndAnimate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (EnableDebug) { Debug.Log((object)("[SpadeGripDebug] Natively resolved parent firearm: " + ((Object)((Component)_firearm).gameObject).name)); Debug.Log((object)("[SpadeGripDebug] Reflection: m_triggerFloat found = " + ((object)_triggerField != null))); Debug.Log((object)("[SpadeGripDebug] Reflection: UpdateInputAndAnimate found = " + ((object)_inputMethod != null))); } } } ProcessSpadeGripLogic(); } private void LateUpdate() { ProcessSpadeGripLogic(); } public override void FVRFixedUpdate() { ((FVRInteractiveObject)this).FVRFixedUpdate(); ProcessSpadeGripLogic(); } public override void OnDestroy() { RestoreOriginalRecoil(); ((FVRInteractiveObject)this).OnDestroy(); } }