2022-06-20 14:08:15 +02:00
using BepInEx ;
using BepInEx.Configuration ;
2022-06-20 15:43:15 +02:00
using System ;
using UnityEngine ;
2022-06-22 14:56:37 +02:00
using EFT ;
2022-06-20 14:08:15 +02:00
2022-06-20 15:43:15 +02:00
namespace UniformAim
2022-06-20 14:08:15 +02:00
{
2022-06-20 20:15:14 +02:00
[BepInPlugin("com.greg.tarkovuniformaim", "Uniform Aim for Tarkov", "1.0.0")]
2022-06-20 14:08:15 +02:00
[BepInProcess("EscapeFromTarkov.exe")]
2022-06-20 15:43:15 +02:00
public class Plugin : BaseUnityPlugin
2022-06-20 14:08:15 +02:00
{
//Bepinex.Configurator fields
public static ConfigEntry < int > configFOV ;
2022-06-20 20:06:49 +02:00
public static ConfigEntry < int > configCoeff ;
2022-06-20 14:08:15 +02:00
public static ConfigEntry < int > configSens ;
2022-06-22 14:56:37 +02:00
public static ConfigEntry < bool > configOverride ;
2022-06-20 14:08:15 +02:00
2022-06-22 14:56:37 +02:00
//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
2022-06-20 15:43:15 +02:00
2022-06-22 14:56:37 +02:00
public static float mySens = 1f ;
//sight data for hacky workarounds
public static int SelectedScope = 0 ;
public static int SelectedScopeMode = 0 ;
public static bool isAiming = false ;
2022-06-20 15:43:15 +02:00
2022-06-20 20:06:49 +02:00
//human-friendly names for variables used later
2022-06-22 14:56:37 +02:00
float FPSCameraFOV = 50f ;
float ScopeFOV = 50f ;
float currentFOV = 50f ;
2022-06-20 15:43:15 +02:00
2022-06-22 14:56:37 +02:00
//Return aspect ratio based on game window resolution, currently unused but could be useful in the future
2022-06-20 15:43:15 +02:00
float GetAspectRatio ( )
{
string screenWidth = Screen . width . ToString ( ) ;
string screenHeight = Screen . height . ToString ( ) ;
float resX = Convert . ToUInt16 ( screenWidth ) ;
float resY = Convert . ToUInt16 ( screenHeight ) ;
//Logger.LogInfo("GetAspectRatio(): resX: " + resX + " resY: " + resY);
return ( resX / resY ) ;
}
2022-06-22 14:56:37 +02:00
//calculate horizontal FOV based on vertical FOV, currently unused but could be useful in the future
2022-06-20 15:43:15 +02:00
float CalculateHFOV ( float FOV )
{
float vFOVRad = FOV * Mathf . Deg2Rad ;
float hFOVRad = ( float ) ( 2 * Math . Atan ( Math . Tan ( FOV / 2 ) * Mathf . Deg2Rad ) * GetAspectRatio ( ) ) ;
return ( float ) ( Math . Round ( hFOVRad * Mathf . Rad2Deg ) ) ;
}
//calculate sensitivity based on FOV difference and coefficient
float CalculateSensitivity ( float aimedFOV , float hipFOV , float mySens )
{ //clamp to avoid invalid values
aimedFOV = Mathf . Clamp ( aimedFOV , 0.1f , 90f ) ;
hipFOV = Mathf . Clamp ( hipFOV , 0.1f , 90f ) ;
2022-06-22 14:56:37 +02:00
//convert to radians
aimedFOV = aimedFOV * Mathf . Deg2Rad ;
hipFOV = hipFOV * Mathf . Deg2Rad ;
2022-06-20 15:43:15 +02:00
2022-06-20 20:06:49 +02:00
float exponent = ( float ) ( 100f / configCoeff . Value ) ;
2022-06-20 15:43:15 +02:00
2022-06-22 14:56:37 +02:00
float tanRatio = ( float ) ( Math . Tan ( aimedFOV / 2 ) / Math . Tan ( hipFOV / 2 ) ) ;
2022-06-20 20:06:49 +02:00
float sensitivity = ( float ) ( configSens . Value / 100f ) ;
float result = ( float ) Math . Pow ( tanRatio , exponent ) * sensitivity ;
return result ;
2022-06-20 15:43:15 +02:00
}
2022-06-22 14:56:37 +02:00
//used to determine if the player is looking through the scope
bool isScopeCameraActive ( )
{
if ( Camera . allCamerasCount > 1 ) { return Camera . allCameras [ 1 ] . GetComponent < Behaviour > ( ) . isActiveAndEnabled ; }
return false ;
}
//used to determine the correct FOV for calculations
void DetermineCurrentFOV ( )
{
if ( ! isScopeCameraActive ( ) )
{
currentFOV = FPSCameraFOV ;
}
else
{
if ( SelectedScope = = 0 ) { currentFOV = ScopeFOV ; }
if ( SelectedScope ! = 0 ) { currentFOV = FPSCameraFOV ; }
}
}
2022-06-20 14:08:15 +02:00
void Awake ( )
{
new UpdateSensitivityPatch ( ) . Enable ( ) ;
2022-06-20 20:06:49 +02:00
new get_AimingSensitivityPatch ( ) . Enable ( ) ;
2022-06-22 14:56:37 +02:00
new get_SelectedScopeIndexPatch ( ) . Enable ( ) ;
new get_SelectedScopeModePatch ( ) . Enable ( ) ;
new get_IsAimingPatch ( ) . Enable ( ) ;
2022-06-20 14:08:15 +02:00
//add configuration slider for field of view
2022-06-22 14:56:37 +02:00
configFOV = Config . Bind ( "General" , "FOV" , 75 , new ConfigDescription ( "In-game Field of View value" , new AcceptableValueRange < int > ( 51 , 75 ) ) ) ;
2022-06-20 14:08:15 +02:00
//add coefficient slider
2022-06-20 20:06:49 +02:00
configCoeff = Config . Bind ( "General" , "Coefficient" , 133 , new ConfigDescription ( "Coefficient - increases sensitivity at higher zoom levels" , new AcceptableValueRange < int > ( 1 , 300 ) ) ) ;
2022-06-20 14:08:15 +02:00
2022-06-22 14:56:37 +02:00
//add sensitivity slider
2022-06-20 20:06:49 +02:00
configSens = Config . Bind ( "General" , "Sensitivity" , 25 , new ConfigDescription ( "Sensitivity while aiming" , new AcceptableValueRange < int > ( 1 , 200 ) ) ) ;
2022-06-20 14:08:15 +02:00
2022-06-22 14:56:37 +02:00
//override for consistent mouse to 360 distance
configOverride = Config . Bind ( "Debug" , "Override sensitivity" , false , new ConfigDescription ( "Overrides sensitivity to provide consistent mouse to 360 distance regardless of zoom level." ) ) ;
2022-06-20 14:08:15 +02:00
}
2022-06-20 15:43:15 +02:00
void Update ( )
{
2022-06-22 14:56:37 +02:00
if ( isAiming )
2022-06-20 15:43:15 +02:00
{
2022-06-22 14:56:37 +02:00
//Grab FOV values for calculation
2022-06-20 15:43:15 +02:00
FPSCameraFOV = Camera . allCameras [ 0 ] . fieldOfView ;
2022-06-22 14:56:37 +02:00
if ( Camera . allCamerasCount > 1 ) { ScopeFOV = Camera . allCameras [ 1 ] . fieldOfView ; }
//calculate what FOV is right
DetermineCurrentFOV ( ) ;
2022-06-20 15:43:15 +02:00
}
2022-06-22 14:56:37 +02:00
////do the magic!
2022-06-20 15:43:15 +02:00
mySens = CalculateSensitivity ( currentFOV , configFOV . Value , configSens . Value ) ;
2022-06-22 14:56:37 +02:00
//Override for crazy people, enables consistent mouse input to 360 rotation. Why would anyone do it?
if ( configOverride . Value = = true ) { mySens = ( float ) ( configSens . Value / 100f ) ; }
2022-06-20 15:43:15 +02:00
}
2022-06-20 14:08:15 +02:00
}
}
2022-06-22 14:56:37 +02:00