diff --git a/JBTrackIR/JBTrackIR.csproj b/JBTrackIR/JBTrackIR.csproj new file mode 100644 index 0000000..5996305 --- /dev/null +++ b/JBTrackIR/JBTrackIR.csproj @@ -0,0 +1,45 @@ + + + + netstandard2.0 + JBTrackIR + My first plugin + 1.0.0 + true + latest + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + JBTrackIR + + + + + + + + + ..\References\0Harmony.dll + + + ..\References\Aki.Reflection.dll + + + ..\References\Assembly-CSharp.dll + + + ..\References\BepInEx.dll + + + ..\References\TrackIRUnity.dll + + + ..\References\UnityEngine.dll + + + ..\References\UnityEngine.CoreModule.dll + + + diff --git a/JBTrackIR/JBTrackIR.sln b/JBTrackIR/JBTrackIR.sln new file mode 100644 index 0000000..99621be --- /dev/null +++ b/JBTrackIR/JBTrackIR.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33516.290 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JBTrackIR", "JBTrackIR.csproj", "{A4AC854D-33F9-464C-A05D-E1030F892CB1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A4AC854D-33F9-464C-A05D-E1030F892CB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4AC854D-33F9-464C-A05D-E1030F892CB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4AC854D-33F9-464C-A05D-E1030F892CB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4AC854D-33F9-464C-A05D-E1030F892CB1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C22410CD-BDAB-4AE8-87C7-E5CF5D1A0FFA} + EndGlobalSection +EndGlobal diff --git a/JBTrackIR/Plugin.cs b/JBTrackIR/Plugin.cs new file mode 100644 index 0000000..81ca20a --- /dev/null +++ b/JBTrackIR/Plugin.cs @@ -0,0 +1,174 @@ +using Aki.Reflection.Patching; +using BepInEx; +using BepInEx.Configuration; +using EFT; +using EFT.Animations; +using EFT.InventoryLogic; +using HarmonyLib; +using RootMotion; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Security.Cryptography; +using TrackIRUnity; +using UnityEngine; + +namespace JBTrackIR; + +[BepInPlugin("com.jonbons.trackir", "JonBons.TrackIR", "1.0.0")] +public class Plugin : BaseUnityPlugin +{ + static ConfigEntry tirEnabled; + static ConfigEntry tirSensitivityCoef; + static ConfigEntry tirLimitPitchLower; + static ConfigEntry tirLimitPitchUpper; + static ConfigEntry tirLimitYawLower; + static ConfigEntry tirLimitYawUpper; + static TrackIRClient tirClient; + static bool tirRunning = false; + + private void Awake() + { + // Plugin startup logic + Logger.LogInfo($"Plugin com.jonbons.trackir is loaded!"); + + tirClient = new TrackIRClient(); + if (tirClient != null && !tirRunning) + { + tirClient.TrackIR_Enhanced_Init(); + tirRunning = true; + Logger.LogInfo($"com.jonbons.trackir: trackir is running"); + } + + BindSettings(); + + new Transpiler().Enable(); + } + + private void OnDestroy() + { + if (tirClient != null && tirRunning) + { + tirClient.TrackIR_Shutdown(); + tirRunning = false; + } + } + + private void BindSettings() + { + tirEnabled = Config.Bind( + "Main Settings", + "TrackIR Enabled", + true, + new ConfigDescription("Enable TrackIR support") + ); + + tirSensitivityCoef = Config.Bind( + "Main Settings", + "TrackIR Sensitivity coef", + 0.5f, + new ConfigDescription("Senstivity coefficient to apply to all TrackIR inputs", + new AcceptableValueRange(0, 1)) + ); + + tirLimitPitchLower = Config.Bind( + "Main Settings", + "TrackIR Pitch lower limit", + -85, + new ConfigDescription("Lower limit of TrackIR pitch angles", + new AcceptableValueRange(-180, 180)) + ); + + tirLimitPitchUpper = Config.Bind( + "Main Settings", + "TrackIR Pitch upper limit", + 85, + new ConfigDescription("Upper limit of TrackIR pitch angles", + new AcceptableValueRange(-180, 180)) + ); + + tirLimitYawLower = Config.Bind( + "Main Settings", + "TrackIR Yaw lower limit", + -150, + new ConfigDescription("Lower limit of TrackIR yaw angles", + new AcceptableValueRange(-180, 180)) + ); + + tirLimitYawUpper = Config.Bind( + "Main Settings", + "TrackIR Yaw upper limit", + 150, + new ConfigDescription("Upper limit of TrackIR yaw angles", + new AcceptableValueRange(-180, 180)) + ); + } + + [Serializable] + public class Limit + { + public Limit() + { + lower = 0; + upper = 360; + } + public Limit(float low, float up) + { + lower = low; + upper = up; + } + public float lower, upper; + } + + public class Transpiler : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return typeof(Player).GetMethod("Look", BindingFlags.Instance | BindingFlags.Public); + } + + [PatchPostfix] + private static void PatchPostfix(ref Player __instance) + { + if (!tirRunning) return; + if (!tirEnabled.Value) return; + + float positionReductionFactor = 0.045f * tirSensitivityCoef.Value; + float rotationReductionFactor = 0.045f * tirSensitivityCoef.Value; + Limit positionXLimits = new Limit(); + Limit positionYLimits = new Limit(); + Limit positionZLimits = new Limit(); + Limit pitchLimits = new Limit(tirLimitPitchLower.Value, tirLimitPitchUpper.Value); + Limit yawLimits = new Limit(tirLimitYawLower.Value, tirLimitYawUpper.Value); + Limit rollLimits = new Limit(-100, 100); + bool useLimits = true; + + //Logger.LogInfo(string.Format("TIR DATA Start")); + + TrackIRClient tirClient = Plugin.tirClient; + + TrackIRClient.LPTRACKIRDATA tid = tirClient.client_HandleTrackIRData(); // Data for head tracking + + //Logger.LogInfo(string.Format("TIR DATA Pitch = {0}; Yaw = {1}, Roll = {2}", tid.fNPPitch, tid.fNPYaw, tid.fNPRoll)); + + Vector3 rot = __instance.ProceduralWeaponAnimation.HandsContainer.CameraTransform.localRotation.eulerAngles; + rot.z = 0; // we don't need to use the existing Z value + if (!useLimits) + { + rot.y = tid.fNPYaw * rotationReductionFactor; + rot.x = tid.fNPPitch * rotationReductionFactor; + //rot.z = -tid.fNPRoll * rotationReductionFactor; + } + else + { + rot.y = Mathf.Clamp(tid.fNPYaw * rotationReductionFactor, yawLimits.lower, yawLimits.upper); + rot.x = Mathf.Clamp(tid.fNPPitch * rotationReductionFactor, pitchLimits.lower, pitchLimits.upper); + //rot.z = Mathf.Clamp(-tid.fNPRoll * rotationReductionFactor, rollLimits.lower, rollLimits.upper); + } + + __instance.ProceduralWeaponAnimation.SetHeadRotation(rot); + //Logger.LogInfo(string.Format("TIR DATA Final pos = {0}; Final rot = {1}", pos, rot)); + } + } +}