diff --git a/TarkovUniformAim/TarkovUniformAim.csproj b/TarkovUniformAim/TarkovUniformAim.csproj
index b1afccf..d3f5134 100644
--- a/TarkovUniformAim/TarkovUniformAim.csproj
+++ b/TarkovUniformAim/TarkovUniformAim.csproj
@@ -44,10 +44,18 @@
..\..\MyFirstPlugin\MyFirstPlugin\lib\BepInEx.dll
+
+ False
+ E:\SPT-AKI\SPT-AKI 3.0.0\EscapeFromTarkov_Data\Managed\Comfort.dll
+
False
..\..\libs\EFT Trainer DLLs\Newtonsoft.Json.dll
+
+ False
+ E:\SPT-AKI\SPT-AKI 3.0.0\EscapeFromTarkov_Data\Managed\Sirenix.Serialization.dll
+
@@ -64,6 +72,8 @@
+
+
diff --git a/TarkovUniformAim/UniformAimCore.cs b/TarkovUniformAim/UniformAimCore.cs
new file mode 100644
index 0000000..2690854
--- /dev/null
+++ b/TarkovUniformAim/UniformAimCore.cs
@@ -0,0 +1,57 @@
+using BepInEx;
+using System;
+using UnityEngine;
+
+namespace UniformAim
+{
+ public class Core
+ {
+ //math stuff
+ //Get screen aspect ratio
+ public static float GetAspectRatio()
+ {
+ return Camera.allCameras[0].aspect;
+ }
+ //Calculate horizontal FOV based on vertical FOV and aspect ratio
+ public static float CalculateHFOV(float FOV)
+ {
+ float vFOVRad = FOV / 2 * Mathf.Deg2Rad;
+ float hFOVRad = (float)(2 * Math.Atan(GetAspectRatio() * Math.Tan(vFOVRad)));
+
+ return (float)(hFOVRad * Mathf.Rad2Deg);
+ }
+
+ //calculate sensitivity based on FOV delta and coefficient
+ public static float CalculateSensitivity(float aimedFOV, float hipFOV)
+ {
+ //calculate horizontal FOV values for inputs
+ aimedFOV = CalculateHFOV(aimedFOV) * Mathf.Deg2Rad;
+ hipFOV = CalculateHFOV(hipFOV) * Mathf.Deg2Rad;
+
+ float exponent = (float)(100f / Plugin.configCoeff.Value);
+
+ float tanRatio = (float)(Math.Tan(aimedFOV / 2) / (Math.Tan(hipFOV / 2)));
+
+ float sensitivity = Plugin.configSens.Value / 100f;
+
+ float result = (float)Math.Pow(tanRatio, exponent) * sensitivity;
+
+ return result;
+ }
+
+ //check if BaseOpticCamera is present and active
+ public static bool isScopeCameraActive()
+ {
+ if(Camera.allCamerasCount > 1) { return Camera.allCameras[1].GetComponent().isActiveAndEnabled; }
+ return false;
+ }
+ //figure out current fov based on scope and in-game camera statuses
+ public static float DetermineCurrentFOV()
+ {
+ //dirty fix for the Ultima MP-155 shotgun
+ if (Plugin.currentFPSCameraFOV> 35 && isScopeCameraActive() && Plugin.currentScopeCameraFOV == 15) { return Plugin.currentFPSCameraFOV; }
+
+ if (Plugin.SelectedScope == 0 && isScopeCameraActive()) { return Plugin.currentScopeCameraFOV; } else { return Plugin.currentFPSCameraFOV; }
+ }
+ }
+}
diff --git a/TarkovUniformAim/UniformAimPatch.cs b/TarkovUniformAim/UniformAimPatch.cs
index 6f4175f..a83e139 100644
--- a/TarkovUniformAim/UniformAimPatch.cs
+++ b/TarkovUniformAim/UniformAimPatch.cs
@@ -2,6 +2,7 @@
using EFT;
using System.Reflection;
+
namespace UniformAim
{
public class UpdateSensitivityPatch : ModulePatch
@@ -67,6 +68,4 @@ namespace UniformAim
Plugin.isAiming = ____isAiming;
}
}
-
-
}
\ No newline at end of file
diff --git a/TarkovUniformAim/UniformAimPlugin.cs b/TarkovUniformAim/UniformAimPlugin.cs
index 115b69b..696ed3d 100644
--- a/TarkovUniformAim/UniformAimPlugin.cs
+++ b/TarkovUniformAim/UniformAimPlugin.cs
@@ -1,26 +1,30 @@
using BepInEx;
using BepInEx.Configuration;
-using System;
using UnityEngine;
+
+
namespace UniformAim
{
- [BepInPlugin("com.greg.tarkovuniformaim", "Uniform Aim for Tarkov", "1.0.0")]
+ [BepInPlugin("com.greg.tarkovuniformaim", "Uniform Aim for Tarkov", "1.1.0")]
[BepInProcess("EscapeFromTarkov.exe")]
public class Plugin : BaseUnityPlugin
{
//Bepinex.Configurator fields
public static ConfigEntry configFOV;
+ int[] FOVRange = new int[2] { 50, 75 };
+ public static ConfigEntry configFOVRangeOverride;
+
public static ConfigEntry configCoeff;
public static ConfigEntry configSens;
- public static ConfigEntry configUseHFOV;
+ public static ConfigEntry configDebug;
- //TODO: figure out a way to read game settings to default the configFOV.Value to whatever the player has already set
- //TODO: figure out a way to read game settings to apply configSens.Value as a multiplier on top of Tarkov's stock sensitivity setting
+ //only for persistence
+ public static ConfigEntry inGameSens;
public static float mySens = 1f;
- public static float aimingSens;
+ //public static float aimingSens;
//sight data for hacky workarounds
public static int SelectedScope = 0;
@@ -28,66 +32,18 @@ namespace UniformAim
public static bool isAiming = false;
//human-friendly names for variables used later
- float FPSCameraFOV;
- float ScopeFOV;
- float currentFOV;
-
- //values to prevent unnecessary repetition
- float cachedFOV;
- string cachedDebugInfo;
-
- //aspect ratio for further calculations
- float GetAspectRatio()
+ public static float baseCameraFOV = 75;
+ public static float currentFPSCameraFOV = 75;
+ public static float currentScopeCameraFOV = 75;
+
+ void printDebug()
{
- return Camera.allCameras[0].aspect;
- }
- //calculate horizontal FOV based on vertical FOV, currently unused but could be useful in the future
- float CalculateHFOV(float FOV)
- {
- float vFOVRad = FOV / 2 * Mathf.Deg2Rad;
- float hFOVRad = (float)(2 * Math.Atan(GetAspectRatio() * Math.Tan(vFOVRad)));
-
- return (float)(hFOVRad * Mathf.Rad2Deg);
- }
- //calculate sensitivity based on FOV difference and the coefficient
- float CalculateSensitivity(float aimedFOV, float hipFOV)
- {
- //clamp to avoid invalid values
- aimedFOV = Mathf.Clamp(aimedFOV, 1f, 75f) * Mathf.Deg2Rad;
- hipFOV = Mathf.Clamp(hipFOV, 1f, 75f) * Mathf.Deg2Rad;
-
- //check if configUseHFOV is enabled, convert to horizontal degrees if true
- if (configUseHFOV.Value)
- {
- aimedFOV = CalculateHFOV(aimedFOV);
- hipFOV = CalculateHFOV(hipFOV);
- }
-
- float exponent = (float)(100f / configCoeff.Value);
-
- float tanRatio = (float)(Math.Tan(aimedFOV / 2) / Math.Tan(hipFOV / 2));
-
- float sensitivity = configSens.Value / 100f;
-
- float result = (float)Math.Pow(tanRatio, exponent) * sensitivity;
-
- return result;
- }
-
- //determine if the player is looking through the scope
- bool isScopeCameraActive()
- {
- if (Camera.allCamerasCount > 1) { return Camera.allCameras[1].GetComponent().isActiveAndEnabled; }
- return false;
- }
-
- //determine the correct FOV for calculations
- void DetermineCurrentFOV()
- {
- if (SelectedScope == 0 && isScopeCameraActive()) { currentFOV = ScopeFOV; } else { currentFOV = FPSCameraFOV; }
-
- //dirty fix for the Ultima MP-155 shotgun
- if (FPSCameraFOV > 35 && isScopeCameraActive() && ScopeFOV == 15) { currentFOV = FPSCameraFOV; }
+ Logger.LogInfo($"\nIn-Game FOV: {configFOV.Value} In-Game Sens: {inGameSens.Value} FOV Override: {configFOVRangeOverride.Value}" +
+ $"\nFPS Camera FOV: {currentFPSCameraFOV} / {Core.CalculateHFOV(currentFPSCameraFOV)} BaseOpticCamera FOV: {currentScopeCameraFOV} / {Core.CalculateHFOV(currentScopeCameraFOV)} CurrentFOV: {Core.DetermineCurrentFOV()} / {Core.CalculateHFOV(Core.DetermineCurrentFOV())}" +
+ $"\nisAiming? {isAiming} SelectedScope: {SelectedScope} SelectedScopeMode:{SelectedScopeMode}" +
+ $"\nCalculated sensitivity: {Core.CalculateSensitivity(Core.DetermineCurrentFOV(), baseCameraFOV)}" +
+ $"\nAspect Ratio: {Core.GetAspectRatio()}" +
+ $"\nFinal Sensitivity: {mySens * inGameSens.Value}");
}
void Awake()
@@ -98,38 +54,64 @@ namespace UniformAim
new get_SelectedScopeModePatch().Enable();
new get_IsAimingPatch().Enable();
+ //override FOV range
+ configFOVRangeOverride = Config.Bind("General", "FOV Override", false, new ConfigDescription("Override FOV range for compatibility with other mods. Requires restart."));
+ if (configFOVRangeOverride.Value)
+ {
+ FOVRange[0] = 1; FOVRange[1] = 178;
+ }
+
//add configuration slider for field of view
- configFOV = Config.Bind("General", "FOV", 75, new ConfigDescription("In-game Field of View value", new AcceptableValueRange(51, 75)));
+ configFOV = Config.Bind("General", "FOV", 75, new ConfigDescription("In-game Field of View value", new AcceptableValueRange(FOVRange[0], FOVRange[1])));
//add coefficient slider
configCoeff = Config.Bind("General", "Coefficient", 133, new ConfigDescription("Coefficient - increases sensitivity at higher zoom levels", new AcceptableValueRange(1, 300)));
//add sensitivity slider
- configSens = Config.Bind("General", "Sensitivity", 25, new ConfigDescription("Sensitivity while aiming", new AcceptableValueRange(1, 200)));
+ configSens = Config.Bind("General", "Sensitivity", 100, new ConfigDescription("Fine control over sensitivity while aiming", new AcceptableValueRange(1, 200)));
+
+ //enable debug logging
+ configDebug = Config.Bind("Debug", "Enable logging?", false, new ConfigDescription("Enables logging in BepInEx console"));
+
+ //settings for persistence, these values get updated when the in-game menu is opened
+ inGameSens = Config.Bind("¡Do not touch unless necessary!", "In-game Aiming Sensitivity value", 0.5f, new ConfigDescription("Should update on its own - kept for persistence between sessions.", new AcceptableValueRange(0.1f, 5.0f)));
- //use HFOV instead of VFOV for sensitivity calculations
- configUseHFOV = Config.Bind("General", "Use Horizontal FOV?", true, new ConfigDescription("Toggles between using Horizontal FOV and Vertical FOV for sensitivity calculations."));
}
-
void FixedUpdate()
{
- //FixedUpdate() at 50Hz (Unity default) tickrate appears to resolve the issue of this script breaking when AI spawns.
+ //FixedUpdate() at 50Hz (Unity default) tickrate appears to resolve the issue of this script breaking when AI spawns
Time.fixedDeltaTime = (1f / 50f);
- if (isAiming)
- {
- //Grab FOV values for calculation
- FPSCameraFOV = Camera.allCameras[0].fieldOfView; //Camera[0] tends to be FPS Camera
- if (Camera.allCamerasCount > 1) { ScopeFOV = Camera.allCameras[1].fieldOfView; } //Camera[1] tends to be BaseOpticCamera
+ //check if the game is running
+ var isRunning = Utils.checkIsReady();
+ if (!isRunning) return;
- //Figure out if the FPSCamera is zoomed in, prevents the script from ticking while the player is healing
- if (FPSCameraFOV < configFOV.Value)
+ if (isRunning)
+ {
+ if (Utils.SetRootObject() != null) {
+ var rootObject = Utils.SetRootObject();
+ //only update these values if the menu has been opened, otherwise read the config
+ if (rootObject.transform.Find("Game Settings").gameObject.activeInHierarchy)
+ {
+ if (!configFOVRangeOverride.Value) { configFOV.Value = 50 + Utils.GetInGameFOV(rootObject); }
+ inGameSens.Value = Utils.GetInGameSens(rootObject);
+ }
+ }
+ //cgheck if the player is aiming
+ if (isAiming)
{
- DetermineCurrentFOV();
- //do not update sensitivity if currentFOV hasn't changed
- if (cachedFOV != currentFOV) { mySens = CalculateSensitivity(currentFOV, configFOV.Value); cachedFOV = currentFOV; }
+ //Grab FOV values for calculation
+ currentFPSCameraFOV = Camera.allCameras[0].fieldOfView; //Camera[0] tends to be FPS Camera
+ if (Camera.allCamerasCount > 1) { currentScopeCameraFOV= Camera.allCameras[1].fieldOfView; } //Camera[1] tends to be BaseOpticCamera
+
+ //Figure out if the FPSCamera is zoomed in, prevents the script from ticking while the player is healing
+ if (currentFPSCameraFOV < configFOV.Value) {
+ mySens = inGameSens.Value * Core.CalculateSensitivity(Core.DetermineCurrentFOV(), configFOV.Value);
+ }
}
}
+ //Print debug info in BepInEx console
+ if (configDebug.Value) printDebug();
}
}
}
diff --git a/TarkovUniformAim/UniformAimUtils.cs b/TarkovUniformAim/UniformAimUtils.cs
new file mode 100644
index 0000000..b6f9f90
--- /dev/null
+++ b/TarkovUniformAim/UniformAimUtils.cs
@@ -0,0 +1,66 @@
+using Comfort.Common;
+using EFT;
+using UnityEngine;
+
+
+
+namespace UniformAim
+{
+ public class Utils
+ {
+ public static bool isPlaying = false;
+ public static GameObject rootObject = null;
+
+ public static bool checkIsReady()
+ {
+ var gameWorld = Singleton.Instance;
+ var sessionResultPanel = Singleton.Instance;
+
+ if (gameWorld == null
+ || gameWorld.AllPlayers == null
+ || gameWorld.AllPlayers.Count <= 0
+ || sessionResultPanel != null)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static bool checkPlayerIsAlive()
+ {
+ var gameWorld = Singleton.Instance;
+ var currentHealth = gameWorld.AllPlayers[0].HealthController.GetBodyPartHealth(EBodyPart.Common).Current;
+
+ if (currentHealth > 0) { return true; } else { return false; }
+ }
+
+
+ public static GameObject SetRootObject()
+ {
+ string path = "Common UI/Common UI/SettingsScreen";
+
+ if(GameObject.Find(path) != null)
+ {
+ GameObject rootObject = GameObject.Find(path);
+ return rootObject;
+ }
+ else { return null; }
+ }
+
+ public static int GetInGameFOV(GameObject root)
+ {
+ GameObject fovObject = root.transform.Find("Game Settings/Image/Other Settings/FOV/FOV").gameObject;
+ int rootFOV = fovObject.GetComponent().CurrentValue();
+
+ return rootFOV;
+ }
+
+ public static float GetInGameSens(GameObject root)
+ {
+ GameObject sensObject = root.transform.Find("Control Settings/ControlPanel/Mouse Settings/Sensitivity Aiming Panel/Mouse Sensitivity Aiming").gameObject;
+ float rootSens = sensObject.GetComponent().CurrentValue();
+
+ return rootSens;
+ }
+ }
+}