using BepInEx; using BepInEx.Configuration; using UnityEngine; using System; namespace UniformAim { [BepInPlugin("com.greg.tarkovuniformaim", "Uniform Aim for Tarkov", "1.1.3")] [BepInProcess("EscapeFromTarkov.exe")] public class Plugin : BaseUnityPlugin { //Bepinex.Configurator fields public static ConfigEntry configFOV; int[] FOVRange = new int[2] { 50, 75 }; ConfigEntry configFOVRangeOverride; public static ConfigEntry configCoeff; public static ConfigEntry configSens; ConfigEntry configDebug; //only for persistence ConfigEntry inGameSens; public static float mySens = 1f; //public static float aimingSens; //sight data for hacky workarounds public static int SelectedScope = 0; public static int SelectedScopeMode = 0; public static bool isAiming = false; //human-friendly names for variables used later float baseCameraFOV = 75; public static float currentFPSCameraFOV = 75; public static float currentScopeCameraFOV = 75; Core core = new Core(); Utils utils = new Utils(); Vector2 FOVInfo; Vector2 ScopeInfo; void Awake() { new UpdateSensitivityPatch().Enable(); new get_AimingSensitivityPatch().Enable(); new get_SelectedScopeIndexPatch().Enable(); 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(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", 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))); } void FixedUpdate() { //FixedUpdate() at 50Hz (Unity default) tickrate appears to resolve the issue of this script breaking when AI spawns Time.fixedDeltaTime = (1f / 50f); 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); } } //check if the player is in the Hideout or in a Raid var isRunning = utils.checkIsReady(); if (!isRunning) return; try { if (Camera.main.isActiveAndEnabled != true) { return; } }catch(NullReferenceException) { Logger.LogInfo("Main camera is disabled!"); } //Print debug info in BepInEx console if (configDebug.Value) printDebug(); if (isRunning) { //check if the player is aiming if (isAiming) { //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) { FOVInfo = new Vector2(currentFPSCameraFOV, currentScopeCameraFOV); ScopeInfo = new Vector2(SelectedScope, SelectedScopeMode); mySens = inGameSens.Value * core.CalculateSensitivity(core.DetermineCurrentFOV(FOVInfo.x, FOVInfo.y, (int)ScopeInfo.x, (int)ScopeInfo.y), configFOV.Value); } } } } string lastDebugLog; void printDebug() { string debugLog = $"\nIn-Game FOV: {configFOV.Value} | In-Game Sens: {inGameSens.Value} | FOV Override: {configFOVRangeOverride.Value}" + $"\nFPS Camera FOV: {currentFPSCameraFOV}V / {core.CalculateHFOV(currentFPSCameraFOV)}H | BaseOpticCamera FOV: {currentScopeCameraFOV}V / {core.CalculateHFOV(currentScopeCameraFOV)}H | CurrentFOV: {core.DetermineCurrentFOV(FOVInfo.x, FOVInfo.y, (int)ScopeInfo.x, (int)ScopeInfo.y)}V / {core.CalculateHFOV(core.DetermineCurrentFOV(FOVInfo.x, FOVInfo.y, (int)ScopeInfo.x, (int)ScopeInfo.y))}H" + $"\nisAiming? {isAiming} | SelectedScope: {SelectedScope} | SelectedScopeMode:{SelectedScopeMode}" + $"\nCalculated sensitivity: {core.CalculateSensitivity(core.DetermineCurrentFOV(FOVInfo.x, FOVInfo.y, (int)ScopeInfo.x, (int)ScopeInfo.y), baseCameraFOV)}" + $"\nAspect Ratio: {Camera.main.aspect}" + $"\nFinal Sensitivity: {mySens}"; if (lastDebugLog != debugLog) { Logger.LogInfo(debugLog); lastDebugLog = debugLog; } } } }