using System; using System.CodeDom.Compiler; using System.Collections; using System.Configuration; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FistVR; using HarmonyLib; using Microsoft.CodeAnalysis; using PSVR2Toolkit; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("Niko666")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Implemented some Adaptive Trigger effects for chad PSVR2 controller enjoyers. REQUIRES PSVR2 Toolkit TO USE!")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyProduct("Niko666.Adaptive_Trigger_For_PSVR2")] [assembly: AssemblyTitle("Adaptive_Trigger_For_PSVR2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace PSVR2Toolkit { public enum VRControllerType : byte { Left, Right, Both } public enum GazeCalibrationReportMode : ushort { None, StartCalibration, CollectCalibrationPoint, DiscardCalibrationPoint, ComputeAndApplyCalibration, RetrieveCalibrationData, StopCalibration, SetEnabledEye, HardwareCalibrationRetrieve } public enum GazeCalibrationStatus : ushort { EyetrackingInactive, EyetrackingActive, CalibrationReady, DSPBusy, Computing, ComputeSucceeded, ComputeFailed, SettingEye } public enum GazeCalibrationResult : byte { Success, Failure, Discarded, Waiting } public enum hmd2_gaze_bool_t : uint { HMD2_GAZE_BOOL_FALSE, HMD2_GAZE_BOOL_TRUE } public enum hmd2_gaze_enabled_eye_t : byte { HMD2_GAZE_ENABLED_EYE_LEFT, HMD2_GAZE_ENABLED_EYE_RIGHT, HMD2_GAZE_ENABLED_EYE_BOTH } public enum ScePadTriggerEffectMode { SCE_PAD_TRIGGER_EFFECT_MODE_OFF, SCE_PAD_TRIGGER_EFFECT_MODE_FEEDBACK, SCE_PAD_TRIGGER_EFFECT_MODE_WEAPON, SCE_PAD_TRIGGER_EFFECT_MODE_VIBRATION, SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_FEEDBACK, SCE_PAD_TRIGGER_EFFECT_MODE_SLOPE_FEEDBACK, SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_VIBRATION } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct hmd2_gaze_vec2_t { public float x; public float y; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct hmd2_gaze_vec3_t { public float x; public float y; public float z; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct hmd2_gaze_lens_config_t { public hmd2_gaze_vec3_t left; public hmd2_gaze_vec3_t right; } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct hmd2_gaze_wearable_eye_t { public hmd2_gaze_bool_t is_gaze_origin_valid; public hmd2_gaze_vec3_t gaze_origin_mm; public hmd2_gaze_bool_t is_gaze_dir_valid; public hmd2_gaze_vec3_t gaze_dir_norm; public hmd2_gaze_bool_t is_pupil_dia_valid; public float pupil_dia_mm; public hmd2_gaze_bool_t is_pupil_pos_in_sensor_area_valid; public hmd2_gaze_vec2_t pupil_pos_in_sensor_area; public hmd2_gaze_bool_t is_pos_guide_valid; public hmd2_gaze_vec2_t pos_guide; public hmd2_gaze_bool_t is_blink_valid; public hmd2_gaze_bool_t blink; } [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct hmd2_gaze_wearable_data_t { public long timestamp; public uint frame_counter; public hmd2_gaze_wearable_eye_t left; public hmd2_gaze_wearable_eye_t right; public hmd2_gaze_bool_t is_gaze_origin_combined_valid; public hmd2_gaze_vec3_t gaze_origin_combined_mm; public hmd2_gaze_bool_t is_gaze_dir_combined_valid; public hmd2_gaze_vec3_t gaze_dir_combined_norm; public hmd2_gaze_bool_t is_convergence_distance_valid; } [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct hmd2_gaze_foveated_gaze_t { public long timestamp; public uint frame_counter; public uint tracking_state; public hmd2_gaze_vec3_t gaze_dir_left_norm; public hmd2_gaze_vec3_t gaze_dir_right_norm; public hmd2_gaze_vec3_t gaze_dir_combined_norm; public float convergence_distance_mm; } [StructLayout(LayoutKind.Sequential, Pack = 8)] public struct hmd2_gaze_status_t { public byte magic0; public byte magic1; public ushort version; public uint size; public float exp_l; public float exp_r; public uint led_status; public uint exp_counter_l; public uint exp_counter_r; public uint led_counter; public int dsp_return_code; public hmd2_gaze_lens_config_t lens_config; public uint user_calibration_id; public hmd2_gaze_vec3_t fr_gaze_origin; public hmd2_gaze_enabled_eye_t enabled_eye; public byte motor_sequence; public byte motor_strength; public hmd2_gaze_wearable_data_t wearable; public hmd2_gaze_foveated_gaze_t foveated; } [StructLayout(LayoutKind.Explicit, Size = 48)] public struct ScePadTriggerEffectCommandData { [FieldOffset(0)] public byte feedbackPosition; [FieldOffset(1)] public byte feedbackStrength; [FieldOffset(0)] public byte weaponStartPosition; [FieldOffset(1)] public byte weaponEndPosition; [FieldOffset(2)] public byte weaponStrength; [FieldOffset(0)] public byte vibrationPosition; [FieldOffset(1)] public byte vibrationAmplitude; [FieldOffset(2)] public byte vibrationFrequency; [FieldOffset(0)] public byte multiplePositionFeedbackStrength0; [FieldOffset(1)] public byte multiplePositionFeedbackStrength1; [FieldOffset(2)] public byte multiplePositionFeedbackStrength2; [FieldOffset(3)] public byte multiplePositionFeedbackStrength3; [FieldOffset(4)] public byte multiplePositionFeedbackStrength4; [FieldOffset(5)] public byte multiplePositionFeedbackStrength5; [FieldOffset(6)] public byte multiplePositionFeedbackStrength6; [FieldOffset(7)] public byte multiplePositionFeedbackStrength7; [FieldOffset(8)] public byte multiplePositionFeedbackStrength8; [FieldOffset(9)] public byte multiplePositionFeedbackStrength9; [FieldOffset(0)] public byte slopeStartPosition; [FieldOffset(1)] public byte slopeEndPosition; [FieldOffset(2)] public byte slopeStartStrength; [FieldOffset(3)] public byte slopeEndStrength; [FieldOffset(0)] public byte multiplePositionVibrationFrequency; [FieldOffset(1)] public byte multiplePositionVibrationAmplitude0; [FieldOffset(2)] public byte multiplePositionVibrationAmplitude1; [FieldOffset(3)] public byte multiplePositionVibrationAmplitude2; [FieldOffset(4)] public byte multiplePositionVibrationAmplitude3; [FieldOffset(5)] public byte multiplePositionVibrationAmplitude4; [FieldOffset(6)] public byte multiplePositionVibrationAmplitude5; [FieldOffset(7)] public byte multiplePositionVibrationAmplitude6; [FieldOffset(8)] public byte multiplePositionVibrationAmplitude7; [FieldOffset(9)] public byte multiplePositionVibrationAmplitude8; [FieldOffset(10)] public byte multiplePositionVibrationAmplitude9; public void SetMultiplePositionFeedbackStrength(byte[] strength) { if (strength == null) { throw new ArgumentNullException("strength"); } int num = Math.Min(strength.Length, 10); if (num > 0) { multiplePositionFeedbackStrength0 = strength[0]; } if (num > 1) { multiplePositionFeedbackStrength1 = strength[1]; } if (num > 2) { multiplePositionFeedbackStrength2 = strength[2]; } if (num > 3) { multiplePositionFeedbackStrength3 = strength[3]; } if (num > 4) { multiplePositionFeedbackStrength4 = strength[4]; } if (num > 5) { multiplePositionFeedbackStrength5 = strength[5]; } if (num > 6) { multiplePositionFeedbackStrength6 = strength[6]; } if (num > 7) { multiplePositionFeedbackStrength7 = strength[7]; } if (num > 8) { multiplePositionFeedbackStrength8 = strength[8]; } if (num > 9) { multiplePositionFeedbackStrength9 = strength[9]; } } public void SetMultiplePositionVibrationAmplitude(byte[] amplitude) { if (amplitude == null) { throw new ArgumentNullException("amplitude"); } int num = Math.Min(amplitude.Length, 10); if (num > 0) { multiplePositionVibrationAmplitude0 = amplitude[0]; } if (num > 1) { multiplePositionVibrationAmplitude1 = amplitude[1]; } if (num > 2) { multiplePositionVibrationAmplitude2 = amplitude[2]; } if (num > 3) { multiplePositionVibrationAmplitude3 = amplitude[3]; } if (num > 4) { multiplePositionVibrationAmplitude4 = amplitude[4]; } if (num > 5) { multiplePositionVibrationAmplitude5 = amplitude[5]; } if (num > 6) { multiplePositionVibrationAmplitude6 = amplitude[6]; } if (num > 7) { multiplePositionVibrationAmplitude7 = amplitude[7]; } if (num > 8) { multiplePositionVibrationAmplitude8 = amplitude[8]; } if (num > 9) { multiplePositionVibrationAmplitude9 = amplitude[9]; } } } [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct ScePadTriggerEffectCommand { public ScePadTriggerEffectMode mode; public uint padding; public ScePadTriggerEffectCommandData commandData; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TriggerEffectCommandPayload { public VRControllerType controllerType; public ScePadTriggerEffectCommand command; } [StructLayout(LayoutKind.Explicit, Size = 13)] public struct GazeCalibrationPacket { [FieldOffset(0)] public float x; [FieldOffset(4)] public float y; [FieldOffset(8)] public float z; [FieldOffset(12)] public GazeCalibrationResult result; [FieldOffset(12)] public hmd2_gaze_enabled_eye_t eyeEnabled; } [StructLayout(LayoutKind.Explicit, Size = 15)] public struct GazeCalibrationCommand { [FieldOffset(0)] public GazeCalibrationReportMode reportMode; [FieldOffset(0)] public GazeCalibrationStatus status; [FieldOffset(2)] public GazeCalibrationPacket payload; } public static class PSVR2ToolkitCAPI { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int psvr2_toolkit_init_delegate(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_deinit_delegate(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool psvr2_toolkit_gaze_status_delegate(ref hmd2_gaze_status_t pGazeStatus, uint timeoutMs); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool psvr2_toolkit_gaze_image_delegate(ref IntPtr pGazeImage, uint timeoutMs); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_write_pcm_delegate(VRControllerType controllerType, IntPtr pcm); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_wait_for_pcm_delegate(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_set_trigger_effect_delegate(VRControllerType controllerType, ref ScePadTriggerEffectCommand command); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_set_hmd_rumble_delegate(byte rumbleHz); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate GazeCalibrationCommand psvr2_toolkit_private_send_gaze_set_command_delegate(GazeCalibrationCommand command); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate GazeCalibrationCommand psvr2_toolkit_private_send_gaze_get_command_delegate(GazeCalibrationCommand command); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void psvr2_toolkit_private_set_usb_connection_state_delegate(bool connected); private static psvr2_toolkit_init_delegate _init; private static psvr2_toolkit_deinit_delegate _deinit; private static psvr2_toolkit_gaze_status_delegate _gaze_status; private static psvr2_toolkit_gaze_image_delegate _gaze_image; private static psvr2_toolkit_write_pcm_delegate _write_pcm; private static psvr2_toolkit_wait_for_pcm_delegate _wait_for_pcm; private static psvr2_toolkit_set_trigger_effect_delegate _set_trigger_effect; private static psvr2_toolkit_set_hmd_rumble_delegate _set_hmd_rumble; private static psvr2_toolkit_private_send_gaze_set_command_delegate _private_send_gaze_set_command; private static psvr2_toolkit_private_send_gaze_get_command_delegate _private_send_gaze_get_command; private static psvr2_toolkit_private_set_usb_connection_state_delegate _private_set_usb_connection_state; private static IntPtr _moduleHandle = IntPtr.Zero; private static readonly object _lock = new object(); public static IntPtr ModuleHandle { get { EnsureLoaded(); return _moduleHandle; } } [DllImport("psvr2_toolkit_capi_loader", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr psvr2_toolkit_loader_get_module_handle(); [DllImport("psvr2_toolkit_capi_loader", CallingConvention = CallingConvention.Cdecl)] private static extern nuint psvr2_toolkit_loader_get_module_path(IntPtr buffer, nuint bufferSize); public static string GetModulePath() { EnsureLoaded(); try { nuint num = psvr2_toolkit_loader_get_module_path(IntPtr.Zero, 0u); if (num == 0) { return string.Empty; } IntPtr intPtr = Marshal.AllocHGlobal((int)(num + 1)); try { psvr2_toolkit_loader_get_module_path(intPtr, num + 1); return Marshal.PtrToStringAnsi(intPtr); } finally { Marshal.FreeHGlobal(intPtr); } } catch { return "Unknown (Failed to query loader)"; } } private static void EnsureLoaded() { if (_moduleHandle != IntPtr.Zero) { return; } lock (_lock) { if (!(_moduleHandle != IntPtr.Zero)) { try { _moduleHandle = psvr2_toolkit_loader_get_module_handle(); } catch (DllNotFoundException inner) { throw new DllNotFoundException("Could not load the loader library 'psvr2_toolkit_capi_loader'. Make sure 'psvr2_toolkit_capi_loader.dll' is in your application directory or search path.", inner); } if (_moduleHandle == IntPtr.Zero) { throw new InvalidOperationException("psvr2_toolkit_loader_get_module_handle returned NULL. Make sure psvr2tk_capi_path.txt contains the correct directory of 'psvr2_toolkit_capi.dll' and the dll exists in that directory."); } _init = GetExport("psvr2_toolkit_init"); _deinit = GetExport("psvr2_toolkit_deinit"); _gaze_status = GetExport("psvr2_toolkit_gaze_status"); _gaze_image = GetExport("psvr2_toolkit_gaze_image"); _write_pcm = GetExport("psvr2_toolkit_write_pcm"); _wait_for_pcm = GetExport("psvr2_toolkit_wait_for_pcm"); _set_trigger_effect = GetExport("psvr2_toolkit_set_trigger_effect"); _set_hmd_rumble = GetExport("psvr2_toolkit_set_hmd_rumble"); _private_send_gaze_set_command = GetExport("psvr2_toolkit_private_send_gaze_set_command"); _private_send_gaze_get_command = GetExport("psvr2_toolkit_private_send_gaze_get_command"); _private_set_usb_connection_state = GetExport("psvr2_toolkit_private_set_usb_connection_state"); } } } private static T GetExport(string name) where T : Delegate { IntPtr procAddress = GetProcAddress(_moduleHandle, name); if (procAddress == IntPtr.Zero) { throw new EntryPointNotFoundException("Could not find entry point '" + name + "' in the loaded PSVR2 Toolkit CAPI library."); } return (T)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T)); } private static IntPtr GetProcAddress(IntPtr hModule, string procName) { Type type = Type.GetType("System.Runtime.InteropServices.NativeLibrary, System.Runtime.InteropServices"); if ((object)type != null) { MethodInfo method = type.GetMethod("GetExport", new Type[2] { typeof(IntPtr), typeof(string) }); if ((object)method != null) { try { return (IntPtr)method.Invoke(null, new object[2] { hModule, procName }); } catch { } } } return Win32GetProcAddress(hModule, procName); } [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", ExactSpelling = true, SetLastError = true)] private static extern IntPtr Win32GetProcAddress(IntPtr hModule, string procName); [DllImport("libdl", CharSet = CharSet.Ansi, EntryPoint = "dlsym")] private static extern IntPtr UnixDlsym(IntPtr handle, string symbol); [DllImport("libdl.so.2", CharSet = CharSet.Ansi, EntryPoint = "dlsym")] private static extern IntPtr UnixDlsym2(IntPtr handle, string symbol); public static int Init() { EnsureLoaded(); return _init(); } public static void Deinit() { EnsureLoaded(); _deinit(); } public static bool GetGazeStatus(ref hmd2_gaze_status_t gazeStatus, uint timeoutMs) { EnsureLoaded(); return _gaze_status(ref gazeStatus, timeoutMs); } public static bool GetGazeImage(ref byte[] gazeImage, uint timeoutMs) { if (gazeImage == null) { throw new ArgumentNullException("gazeImage"); } if (gazeImage.Length < 2097408) { throw new ArgumentException("Array size must be at least 0x200100 bytes.", "gazeImage"); } EnsureLoaded(); IntPtr pGazeImage = IntPtr.Zero; bool num = _gaze_image(ref pGazeImage, timeoutMs); if (num && pGazeImage != IntPtr.Zero) { Marshal.Copy(pGazeImage, gazeImage, 0, 2097408); } return num; } public static bool GetGazeImage(ref IntPtr pGazeImage, uint timeoutMs) { EnsureLoaded(); return _gaze_image(ref pGazeImage, timeoutMs); } public unsafe static void WritePcm(VRControllerType controllerType, byte[] pcm) { if (pcm == null) { throw new ArgumentNullException("pcm"); } if (pcm.Length < 32) { throw new ArgumentException("PCM array must be at least 32 bytes.", "pcm"); } EnsureLoaded(); fixed (byte* ptr = pcm) { _write_pcm(controllerType, (IntPtr)ptr); } } public static void WritePcm(VRControllerType controllerType, IntPtr pcm) { if (pcm == IntPtr.Zero) { throw new ArgumentNullException("pcm"); } EnsureLoaded(); _write_pcm(controllerType, pcm); } public static void WaitForPcm() { EnsureLoaded(); _wait_for_pcm(); } public static void SetTriggerEffect(VRControllerType controllerType, ref ScePadTriggerEffectCommand command) { EnsureLoaded(); _set_trigger_effect(controllerType, ref command); } public static void SetHmdRumble(byte rumbleHz) { EnsureLoaded(); _set_hmd_rumble(rumbleHz); } public static GazeCalibrationCommand SendGazeSetCommand(GazeCalibrationCommand command) { EnsureLoaded(); return _private_send_gaze_set_command(command); } public static GazeCalibrationCommand SendGazeGetCommand(GazeCalibrationCommand command) { EnsureLoaded(); return _private_send_gaze_get_command(command); } public static void SetUsbConnectionState(bool connected) { EnsureLoaded(); _private_set_usb_connection_state(connected); } } } namespace Niko666 { [BepInProcess("h3vr.exe")] [BepInPlugin("Niko666.Adaptive_Trigger_For_PSVR2", "Adaptive_Trigger_For_PSVR2", "2.0.0")] public class AdaptiveTrigger : BaseUnityPlugin { public enum HeadsetVibrationType { Disabled, OnHit, OnRecoil, Both } public static ConfigEntry ControllerToUse; public static ConfigEntry HeadsetVibration; public static ConfigEntry HeadsetVibrationFrequency; public static ConfigEntry AllowDualStageTriggerEffect; public static ConfigEntry DisableEffectWhenEmpty; public static ConfigEntry ClickyEffectStrength; public static ConfigEntry RecoilFeedbackStrength; public static ConfigEntry UseVibrationFeedbackForRecoil; public static ConfigEntry VibrationFrequency; public static ConfigEntry OverrideTriggerEffectPos; public static ConfigEntry OverrideStartPos; public static ConfigEntry OverrideEndPos; public static int _leftShotsSoFar; public static int _rightShotsSoFar; public static bool _LeftHandTriggerEffectApplied; public static bool _LeftHandRecoilEffectApplied; public static bool _LeftHandTriggerEffectCleared; public static bool _RightHandTriggerEffectApplied; public static bool _RightHandRecoilEffectApplied; public static bool _RightHandTriggerEffectCleared; private static Coroutine _headsetVibrationCoroutine; public const string Id = "Niko666.Adaptive_Trigger_For_PSVR2"; public static AdaptiveTrigger Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } public static string Name => "Adaptive_Trigger_For_PSVR2"; public static string Version => "2.0.0"; public void Awake() { SetDllDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); Instance = this; ControllerToUse = ((BaseUnityPlugin)this).Config.Bind("General", "ControllerToUse", VRControllerType.Both, "Enable Adaptive Trigger effect on selected controllers only. (Both, Left, Right)"); HeadsetVibration = ((BaseUnityPlugin)this).Config.Bind("General", "HeadsetVibration", HeadsetVibrationType.Both, "Enable headset vibration effect. (Disabled, OnHit, OnRecoil, Both)"); HeadsetVibrationFrequency = ((BaseUnityPlugin)this).Config.Bind("General", "HeadsetVibrationFrequency", (byte)15, "Headset vibration frequency. (1-25)"); AllowDualStageTriggerEffect = ((BaseUnityPlugin)this).Config.Bind("General", "AllowDualStageTriggerEffect", true, "Enable dual stage trigger effect. This will attempt to add a little bit of resistance before the each \"stage\" of the trigger. (I have no idea how a real Dual Stage trigger feels so sorry if it doesn't feel right)"); DisableEffectWhenEmpty = ((BaseUnityPlugin)this).Config.Bind("General", "DisableEffectWhenEmpty", false, "Disable trigger effect when the gun is empty or the hammer is not cocked."); ClickyEffectStrength = ((BaseUnityPlugin)this).Config.Bind("General", "ClickyEffectStrength", (byte)4, "Effect strength of clicky trigger effect. Going too high might cause weak recoil effect. (1-8)"); RecoilFeedbackStrength = ((BaseUnityPlugin)this).Config.Bind("General", "RecoilFeedbackStrength", (byte)8, "Effect strength of firearm recoil effect. (0-8)"); UseVibrationFeedbackForRecoil = ((BaseUnityPlugin)this).Config.Bind("General", "UseVibrationFeedbackForRecoil", false, "Use vibration-based feedback for recoil effect. By default the mod use force-based feedback to emulate the recoil \"kick\" effect, but it doesn't work well with extremely high RPM weapons when doing full-auto shooting. Turning this option on will make the trigger vibrates instead of kicking, which is more suitable for full-auto shooting but worse the feeling when single-shot. "); VibrationFrequency = ((BaseUnityPlugin)this).Config.Bind("General", "VibrationFrequency", (byte)50, "Vibration frequency for recoil effect when 'UseVibrationFeedbackForRecoil' is enabled. (1-255)"); OverrideTriggerEffectPos = ((BaseUnityPlugin)this).Config.Bind("General", "OverrideTriggerEffectPos", false, "Override trigger effect position with user set values instead of reading from firearm's trigger thresholds. Not recommend but could be useful if you want to. Also this will disable dual stage trigger effect and empty effect."); OverrideStartPos = ((BaseUnityPlugin)this).Config.Bind("General", "OverrideStartPos", (byte)2, "Override start position of the trigger effect. (0-9)"); OverrideEndPos = ((BaseUnityPlugin)this).Config.Bind("General", "OverrideStartPos", (byte)7, "Override end position of the trigger effect. (0-9)"); Logger = ((BaseUnityPlugin)this).Logger; try { PSVR2ToolkitCAPI.Init(); Logger.LogMessage((object)"PSVR2 Toolkit CAPI Initialized."); Harmony.CreateAndPatchAll(typeof(AdaptiveTriggerPatch), (string)null); Logger.LogMessage((object)("Fuk U Sony! Sent from Niko666.Adaptive_Trigger_For_PSVR2 " + Version)); } catch (Exception ex) { Logger.LogError((object)("Failed to initialize PSVR2 Toolkit CAPI: " + ex.Message + "\n You need to install or update PSVR2 Toolkit!")); } } public void OnDestroy() { if (_headsetVibrationCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_headsetVibrationCoroutine); } PSVR2ToolkitCAPI.SetHmdRumble(0); SetTriggerEffectOff(VRControllerType.Both); PSVR2ToolkitCAPI.Deinit(); Logger.LogMessage((object)"PSVR2 Toolkit CAPI Deinitialized. It is now safe to turn off your computer."); } private static void SetTriggerEffectOff(VRControllerType controller) { ScePadTriggerEffectCommand command = new ScePadTriggerEffectCommand { mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_OFF }; PSVR2ToolkitCAPI.SetTriggerEffect(controller, ref command); } public static void ShotFired(FVRFireArm fireArm) { if ((Object)(object)((FVRInteractiveObject)fireArm).m_hand != (Object)null) { if (((FVRInteractiveObject)fireArm).m_hand.IsThisTheRightHand) { _rightShotsSoFar++; } else { _leftShotsSoFar++; } } } public static void ApplyTriggerEffect(byte startPos, byte endPos, VRControllerType Hand, float buzztime) { bool flag = ControllerToUse.Value == Hand || ControllerToUse.Value == VRControllerType.Both; if (Hand != VRControllerType.Left && Hand != VRControllerType.Right) { return; } bool num = Hand == VRControllerType.Left; ref bool reference = ref num ? ref _LeftHandTriggerEffectCleared : ref _RightHandTriggerEffectCleared; ref bool reference2 = ref num ? ref _LeftHandTriggerEffectApplied : ref _RightHandTriggerEffectApplied; ref bool reference3 = ref num ? ref _LeftHandRecoilEffectApplied : ref _RightHandRecoilEffectApplied; ref int reference4 = ref num ? ref _leftShotsSoFar : ref _rightShotsSoFar; reference = false; if (reference4 != 0) { if (!reference3 && flag) { if (UseVibrationFeedbackForRecoil.Value) { ScePadTriggerEffectCommand command = new ScePadTriggerEffectCommand { mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_VIBRATION, commandData = { vibrationPosition = 0, vibrationAmplitude = RecoilFeedbackStrength.Value, vibrationFrequency = VibrationFrequency.Value } }; PSVR2ToolkitCAPI.SetTriggerEffect(Hand, ref command); } else { ScePadTriggerEffectCommand command2 = new ScePadTriggerEffectCommand { mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_FEEDBACK, commandData = { feedbackPosition = 0, feedbackStrength = RecoilFeedbackStrength.Value } }; PSVR2ToolkitCAPI.SetTriggerEffect(Hand, ref command2); } reference3 = true; } if (buzztime > 0.01f && flag) { ScePadTriggerEffectCommand command3 = new ScePadTriggerEffectCommand { mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_SLOPE_FEEDBACK, commandData = { slopeStartPosition = (byte)Mathf.Clamp(startPos - 1, 0, 9), slopeEndPosition = (byte)Mathf.Clamp(endPos - 1, 0, 9), slopeStartStrength = 1, slopeEndStrength = ClickyEffectStrength.Value } }; PSVR2ToolkitCAPI.SetTriggerEffect(Hand, ref command3); reference3 = false; reference4 = 0; } } else if (!reference2 && flag) { ScePadTriggerEffectCommand command4 = new ScePadTriggerEffectCommand { mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_SLOPE_FEEDBACK, commandData = { slopeStartPosition = (byte)Mathf.Clamp(startPos - 1, 0, 9), slopeEndPosition = (byte)Mathf.Clamp(endPos - 1, 0, 9), slopeStartStrength = 1, slopeEndStrength = ClickyEffectStrength.Value } }; PSVR2ToolkitCAPI.SetTriggerEffect(Hand, ref command4); reference2 = true; } } public static void ClearTriggerEffect(VRControllerType Hand) { switch (Hand) { case VRControllerType.Left: if (!_LeftHandTriggerEffectCleared) { SetTriggerEffectOff(VRControllerType.Left); _LeftHandTriggerEffectApplied = false; _LeftHandRecoilEffectApplied = false; _leftShotsSoFar = 0; _LeftHandTriggerEffectCleared = true; } break; case VRControllerType.Right: if (!_RightHandTriggerEffectCleared) { SetTriggerEffectOff(VRControllerType.Right); _RightHandTriggerEffectApplied = false; _RightHandRecoilEffectApplied = false; _rightShotsSoFar = 0; _RightHandTriggerEffectCleared = true; } break; case VRControllerType.Both: if (!_LeftHandTriggerEffectCleared || !_RightHandTriggerEffectCleared) { SetTriggerEffectOff(VRControllerType.Both); _LeftHandTriggerEffectApplied = false; _LeftHandRecoilEffectApplied = false; _leftShotsSoFar = 0; _LeftHandTriggerEffectCleared = true; _RightHandTriggerEffectApplied = false; _RightHandRecoilEffectApplied = false; _rightShotsSoFar = 0; _RightHandTriggerEffectCleared = true; } break; } } public static void ApplyHeadsetVibration(float duration, byte freq) { if (_headsetVibrationCoroutine != null) { ((MonoBehaviour)Instance).StopCoroutine(_headsetVibrationCoroutine); } _headsetVibrationCoroutine = ((MonoBehaviour)Instance).StartCoroutine(VibrationFadeRoutine(duration, freq)); } private static IEnumerator VibrationFadeRoutine(float duration, byte startFreq) { byte clampedStartFreq = (byte)Mathf.Clamp((int)startFreq, 0, 25); float elapsedTime = 0f; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; PSVR2ToolkitCAPI.SetHmdRumble((byte)Mathf.Lerp((float)(int)clampedStartFreq, 0f, elapsedTime / duration)); yield return null; } PSVR2ToolkitCAPI.SetHmdRumble(0); _headsetVibrationCoroutine = null; } [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetDllDirectory(string lpPathName); } internal class AdaptiveTriggerPatch : MonoBehaviour { [CompilerGenerated] private static class <>O { public static ShotFired <0>__ShotFired; } [HarmonyPatch(typeof(SteamVR_LoadLevel), "Begin")] [HarmonyPrefix] public static bool BeginPatch() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if ((Object)(object)GM.CurrentSceneSettings != (Object)null) { FVRSceneSettings currentSceneSettings = GM.CurrentSceneSettings; object obj = <>O.<0>__ShotFired; if (obj == null) { ShotFired val = AdaptiveTrigger.ShotFired; <>O.<0>__ShotFired = val; obj = (object)val; } currentSceneSettings.ShotFiredEvent -= (ShotFired)obj; } ((BaseUnityPlugin)AdaptiveTrigger.Instance).Config.Reload(); AdaptiveTrigger._LeftHandTriggerEffectCleared = false; AdaptiveTrigger._RightHandTriggerEffectCleared = false; AdaptiveTrigger.ClearTriggerEffect(VRControllerType.Both); return true; } [HarmonyPatch(typeof(FVRFireArm), "Awake")] [HarmonyPostfix] public static void ShotDetect() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown FVRSceneSettings currentSceneSettings = GM.CurrentSceneSettings; object obj = <>O.<0>__ShotFired; if (obj == null) { ShotFired val = AdaptiveTrigger.ShotFired; <>O.<0>__ShotFired = val; obj = (object)val; } currentSceneSettings.ShotFiredEvent += (ShotFired)obj; } [HarmonyPatch(typeof(FVRPlayerBody), "HitEffect")] [HarmonyPrefix] public static bool HitEffectPatch() { if (AdaptiveTrigger.HeadsetVibration.Value == AdaptiveTrigger.HeadsetVibrationType.OnHit || AdaptiveTrigger.HeadsetVibration.Value == AdaptiveTrigger.HeadsetVibrationType.Both) { AdaptiveTrigger.ApplyHeadsetVibration(3f, AdaptiveTrigger.HeadsetVibrationFrequency.Value); } return true; } [HarmonyPatch(typeof(FVRViveHand), "Update")] [HarmonyPostfix] public static void ClearEffectOnDropButAlsoDoHeadsetVibration(FVRViveHand __instance) { if ((Object)(object)__instance.CurrentInteractable == (Object)null) { AdaptiveTrigger.ClearTriggerEffect(__instance.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } if ((Object)(object)__instance.CurrentInteractable != (Object)null && __instance.CurrentInteractable is FVRFireArm && __instance.m_isBuzzing && (AdaptiveTrigger._rightShotsSoFar > 0 || AdaptiveTrigger._leftShotsSoFar > 0) && (AdaptiveTrigger.HeadsetVibration.Value == AdaptiveTrigger.HeadsetVibrationType.OnRecoil || AdaptiveTrigger.HeadsetVibration.Value == AdaptiveTrigger.HeadsetVibrationType.Both) && (Object)(object)__instance.m_curBuzz != (Object)null) { AdaptiveTrigger.ApplyHeadsetVibration(__instance.m_curBuzz.BuzzLength, AdaptiveTrigger.HeadsetVibrationFrequency.Value); } } private static bool IsWeaponEmpty(FVRFireArm w) { Handgun val = (Handgun)(object)((w is Handgun) ? w : null); int num; if (val == null) { BAP val2 = (BAP)(object)((w is BAP) ? w : null); num = ((val2 != null && (Object)(object)((FVRFireArm)val2).Magazine != (Object)null) ? 1 : 0); } else { num = (((Object)(object)((FVRFireArm)val).Magazine != (Object)null) ? 1 : 0); } bool flag = (byte)num != 0; Handgun val3 = (Handgun)(object)((w is Handgun) ? w : null); int num2; if (val3 == null) { BAP val4 = (BAP)(object)((w is BAP) ? w : null); num2 = ((val4 != null && ((FVRFireArm)val4).Magazine.HasARound()) ? 1 : 0); } else { num2 = (((FVRFireArm)val3).Magazine.HasARound() ? 1 : 0); } bool flag2 = (byte)num2 != 0; bool flag3 = ((Handgun)(((w is Handgun) ? w : null)?)).m_isHammerCocked ?? ((BAP)(((w is BAP) ? w : null)?)).m_isHammerCocked ?? ((Airgun)(((w is Airgun) ? w : null)?)).m_isHammerCocked ?? ((RailTater)(((w is RailTater) ? w : null)?)).m_isHammerCocked ?? ((SingleActionRevolver)(((w is SingleActionRevolver) ? w : null)?)).m_isHammerCocked ?? false; bool flag4 = ((Handgun)(((w is Handgun) ? w : null)?)).Chamber.IsFull ?? ((BAP)(((w is BAP) ? w : null)?)).Chamber.IsFull ?? ((Airgun)(((w is Airgun) ? w : null)?)).Chamber.IsFull ?? ((RailTater)(((w is RailTater) ? w : null)?)).Chamber.IsFull ?? false; if (!flag || flag2 || flag4 || flag3) { if (!flag && !flag4) { return !flag3; } return false; } return true; } [HarmonyPatch(typeof(FVRFireArm), "FVRUpdate")] [HarmonyPostfix] public static void GlobalTriggerEffect(FVRFireArm __instance) { if (!((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null)) { return; } if ((Object)(object)((FVRPhysicalObject)__instance).savedGrip != (Object)null) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); return; } AdaptiveTrigger._LeftHandTriggerEffectCleared = false; AdaptiveTrigger._RightHandTriggerEffectCleared = false; byte startPos; byte endPos; if (AdaptiveTrigger.OverrideTriggerEffectPos.Value) { startPos = (byte)Mathf.Clamp((int)AdaptiveTrigger.OverrideStartPos.Value, 0, 9); endPos = (byte)Mathf.Clamp((int)AdaptiveTrigger.OverrideEndPos.Value, 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); return; } ClosedBoltWeapon val = (ClosedBoltWeapon)(object)((__instance is ClosedBoltWeapon) ? __instance : null); if (val == null) { OpenBoltReceiver val2 = (OpenBoltReceiver)(object)((__instance is OpenBoltReceiver) ? __instance : null); if (val2 == null) { Handgun val3 = (Handgun)(object)((__instance is Handgun) ? __instance : null); if (val3 == null) { TubeFedShotgun val4 = (TubeFedShotgun)(object)((__instance is TubeFedShotgun) ? __instance : null); if (val4 == null) { BoltActionRifle val5 = (BoltActionRifle)(object)((__instance is BoltActionRifle) ? __instance : null); if (val5 == null) { if (!(__instance is BreakActionWeapon)) { if (!(__instance is Revolver)) { SingleActionRevolver val6 = (SingleActionRevolver)(object)((__instance is SingleActionRevolver) ? __instance : null); if (val6 == null) { RevolvingShotgun val7 = (RevolvingShotgun)(object)((__instance is RevolvingShotgun) ? __instance : null); if (val7 == null) { LAPD2019 val8 = (LAPD2019)(object)((__instance is LAPD2019) ? __instance : null); if (val8 == null) { BAP val9 = (BAP)(object)((__instance is BAP) ? __instance : null); if (val9 == null) { if (!(__instance is PotatoGun)) { GrappleGun val10 = (GrappleGun)(object)((__instance is GrappleGun) ? __instance : null); if (val10 == null) { Airgun val11 = (Airgun)(object)((__instance is Airgun) ? __instance : null); if (val11 == null) { CarlGustaf val12 = (CarlGustaf)(object)((__instance is CarlGustaf) ? __instance : null); if (val12 == null) { RailTater val13 = (RailTater)(object)((__instance is RailTater) ? __instance : null); if (val13 == null) { FlameThrower val14 = (FlameThrower)(object)((__instance is FlameThrower) ? __instance : null); if (val14 == null) { sblp val15 = (sblp)(object)((__instance is sblp) ? __instance : null); if (val15 != null) { startPos = (byte)Mathf.Clamp((int)(val15.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val15.TriggerFiringThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } else { startPos = 2; endPos = 7; AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = 3; endPos = (byte)Mathf.Clamp((int)(val14.TriggerFiringThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val13.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val13.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && !val13.m_isHammerCocked) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val12.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val12.TriggerFiringThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val11.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val11.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && !val11.m_isHammerCocked) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val10.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val10.TriggerBreakThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = 4; endPos = 7; AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val9.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val9.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val9)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val8.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val8.TriggerFireThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val7.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val7.TriggerFiringThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val6.TriggerThreshold * 10f - 2f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val6.TriggerThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && !val6.m_isHammerCocked) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = 2; endPos = 9; AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = 4; endPos = 7; AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { startPos = (byte)Mathf.Clamp((int)(val5.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val5.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val5)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val4.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val4.TriggerBreakThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val4)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val3.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val3.TriggerBreakThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val3)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } else { startPos = (byte)Mathf.Clamp((int)(val2.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val2.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val2)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } return; } startPos = (byte)Mathf.Clamp((int)(val.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val.TriggerFiringThreshold * 10f - 1f), 0, 9); if (AdaptiveTrigger.DisableEffectWhenEmpty.Value && IsWeaponEmpty((FVRFireArm)(object)val)) { AdaptiveTrigger.ClearTriggerEffect(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left); } else if (val.UsesDualStageFullAuto && AdaptiveTrigger.AllowDualStageTriggerEffect.Value) { if (val.m_triggerFloat < val.TriggerFiringThreshold) { startPos = (byte)Mathf.Clamp((int)(val.TriggerResetThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val.TriggerFiringThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } else { startPos = (byte)Mathf.Clamp((int)(val.TriggerFiringThreshold * 10f - 1f), 0, 9); endPos = (byte)Mathf.Clamp((int)(val.TriggerDualStageThreshold * 10f - 1f), 0, 9); AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } else { AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } [HarmonyPatch(typeof(AttachableFirearmPhysicalObject), "UpdateInteraction")] [HarmonyPostfix] public static void AttachableFirearmPhysicalObjectTriggerEffect(AttachableFirearmPhysicalObject __instance) { if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null) { AdaptiveTrigger._LeftHandTriggerEffectCleared = false; AdaptiveTrigger._RightHandTriggerEffectCleared = false; byte startPos = 2; byte endPos = 7; if (AdaptiveTrigger.OverrideTriggerEffectPos.Value) { startPos = (byte)Mathf.Clamp(AdaptiveTrigger.OverrideStartPos.Value + 1, 0, 10); endPos = (byte)Mathf.Clamp(AdaptiveTrigger.OverrideEndPos.Value + 1, 0, 10); } AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } [HarmonyPatch(typeof(AttachableFirearmInterface), "UpdateInteraction")] [HarmonyPostfix] public static void AttachableFirearmInterfaceTriggerEffect(AttachableFirearmInterface __instance) { if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null) { AdaptiveTrigger._LeftHandTriggerEffectCleared = false; AdaptiveTrigger._RightHandTriggerEffectCleared = false; byte startPos = 2; byte endPos = 7; if (AdaptiveTrigger.OverrideTriggerEffectPos.Value) { startPos = (byte)Mathf.Clamp(AdaptiveTrigger.OverrideStartPos.Value + 1, 0, 10); endPos = (byte)Mathf.Clamp(AdaptiveTrigger.OverrideEndPos.Value + 1, 0, 10); } AdaptiveTrigger.ApplyTriggerEffect(startPos, endPos, ((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? VRControllerType.Right : VRControllerType.Left, ((FVRInteractiveObject)__instance).m_hand.m_buzztime); } } } } namespace plugin.Properties { [CompilerGenerated] [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] internal sealed class Settings : ApplicationSettingsBase { private static Settings defaultInstance = (Settings)(object)SettingsBase.Synchronized((SettingsBase)(object)new Settings()); public static Settings Default => defaultInstance; } }