completely reworked the code to work off SelectedScope and Camera info instead of Field of View values alone

This commit is contained in:
notGreg 2022-06-22 14:56:37 +02:00
parent e41a9f7f35
commit 1896c35a2b
3 changed files with 136 additions and 42 deletions

View File

@ -1 +1,15 @@
# TarkovUniformAim
# Uniform Aim for Tarkov
Many thanks to the helpful community of SPT-AKI server, especially kiobu-kouhai, Kobrakon, and SamSWAT
---
This plugin aims to address the issue of wonky and inconsistent sensitivity multipliers of all sights in Escape from Tarkov.
Sensitivity is now derived from player's hipfire Field of View and weapon's Field of View when aiming to produce consistent experience regardless of weapon and sight used. It also addresses some edge cases like NcSTAR ADO P4 back-up sight being way slower than it should be.
Examples in other games:
[Battlefield: Important Guide to Uniform Soldier Aiming on web.archive](https://web.archive.org/web/20160716041925/http://battlelog.battlefield.com/bf4/forum/threadview/2979150494051524581/)
[Rainbow Six Siege: Guide to ADS Sensitivity in Y5S3](https://www.ubisoft.com/en-gb/game/rainbow-six/siege/news-updates/3IMlDGlaRFgdvQNq3BOSFv/guide-to-ads-sensitivity-in-y5s3)

View File

@ -33,4 +33,65 @@ namespace UniformAim
____aimingSens = Plugin.mySens;
}
}
public class get_SelectedScopeIndexPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return typeof(EFT.InventoryLogic.SightComponent).GetMethod("get_SelectedScopeIndex");
}
[PatchPostfix]
public static void PatchPostfix(ref int ___SelectedScope)
{
Plugin.SelectedScope = ___SelectedScope;
}
}
public class get_SelectedScopeModePatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return typeof(EFT.InventoryLogic.SightComponent).GetMethod("get_SelectedScopeMode");
}
[PatchPostfix]
public static void PatchPostfix(ref int[] ___ScopesSelectedModes)
{
Plugin.SelectedScopeMode = ___ScopesSelectedModes[Plugin.SelectedScope];
}
}
public class get_IsAimingPatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return typeof(Player.FirearmController).GetMethod("get_IsAiming");
}
[PatchPostfix]
public static void PatchPostfix(ref bool ____isAiming)
{
Plugin.isAiming = ____isAiming;
}
}
//public class ScopesSelectedModesPatch : ModulePatch
//{
// protected override MethodBase GetTargetMethod()
// {
// return typeof(EFT.InventoryLogic.SightComponent).GetMethod("ScopesSelectedModes");
// }
// [PatchPostfix]
// public static void PatchPostfix(ref int[] ScopesSelectedModes)
// {
// ScopesSelectedModes.CopyTo(Plugin.CurrentScopeValue, 0);
// }
//}
//patch bool HasCurrentZoomGreaterThenOne()
//EFT.InventoryLogic.SightComponent seems like a decent route to sort it all out
//
}

View File

@ -2,6 +2,7 @@
using BepInEx.Configuration;
using System;
using UnityEngine;
using EFT;
namespace UniformAim
{
@ -14,19 +15,24 @@ namespace UniformAim
public static ConfigEntry<int> configFOV;
public static ConfigEntry<int> configCoeff;
public static ConfigEntry<int> configSens;
public static ConfigEntry<bool> configOverride;
public static float mySens = 2f;
//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
// last FOV values for FPS Camera (Main camera) and baseOpticCamera(Clone) (Picture in picture for scopes)
float lastFOV = -1f;
float lastFOV2 = -1f;
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;
//human-friendly names for variables used later
float FPSCameraFOV = -1f;
float ScopeFOV = -1f;
float currentFOV = -1f;
float FPSCameraFOV = 50f;
float ScopeFOV = 50f;
float currentFOV = 50f;
//Return aspect ratio based on game window resolution
//Return aspect ratio based on game window resolution, currently unused but could be useful in the future
float GetAspectRatio()
{
string screenWidth = Screen.width.ToString();
@ -37,7 +43,7 @@ namespace UniformAim
//Logger.LogInfo("GetAspectRatio(): resX: " + resX + " resY: " + resY);
return (resX / resY);
}
//calculate horizontal FOV based on vertical FOV
//calculate horizontal FOV based on vertical FOV, currently unused but could be useful in the future
float CalculateHFOV(float FOV)
{
float vFOVRad = FOV * Mathf.Deg2Rad;
@ -51,13 +57,13 @@ namespace UniformAim
aimedFOV = Mathf.Clamp(aimedFOV, 0.1f, 90f);
hipFOV = Mathf.Clamp(hipFOV, 0.1f, 90f);
//halve and convert to radians
aimedFOV = aimedFOV / 2 * Mathf.Deg2Rad;
hipFOV = hipFOV / 2 * Mathf.Deg2Rad;
//convert to radians
aimedFOV = aimedFOV * Mathf.Deg2Rad;
hipFOV = hipFOV * Mathf.Deg2Rad;
float exponent = (float)(100f / configCoeff.Value);
float tanRatio = (float)(Math.Tan(aimedFOV) / Math.Tan(hipFOV));
float tanRatio = (float)(Math.Tan(aimedFOV / 2) / Math.Tan(hipFOV / 2));
float sensitivity = (float)(configSens.Value/100f);
@ -66,53 +72,66 @@ namespace UniformAim
return result;
}
//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; }
}
}
void Awake()
{
//Enable uniform aim patch
new UpdateSensitivityPatch().Enable();
new get_AimingSensitivityPatch().Enable();
new get_SelectedScopeIndexPatch().Enable();
new get_SelectedScopeModePatch().Enable();
new get_IsAimingPatch().Enable();
//add configuration slider for field of view
configFOV = Config.Bind("General", "FOV", 75, new ConfigDescription("In-game Field of View value", new AcceptableValueRange<int>(50, 75)));
configFOV = Config.Bind("General", "FOV", 75, new ConfigDescription("In-game Field of View value", new AcceptableValueRange<int>(51, 75)));
//add coefficient slider
configCoeff = Config.Bind("General", "Coefficient", 133, new ConfigDescription("Coefficient - increases sensitivity at higher zoom levels", new AcceptableValueRange<int>(1, 300)));
//add secondary sensitivity slider for greater control
//add sensitivity slider
configSens = Config.Bind("General", "Sensitivity", 25, new ConfigDescription("Sensitivity while aiming", new AcceptableValueRange<int>(1, 200)));
//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."));
}
void Update()
{
if (Camera.allCamerasCount >= 1)
if (isAiming)
{
//Grab FOV values for calculation
FPSCameraFOV = Camera.allCameras[0].fieldOfView;
if (Camera.allCamerasCount > 1) { ScopeFOV = Camera.allCameras[1].fieldOfView; }
//calculate what FOV is right
DetermineCurrentFOV();
}
if (Camera.allCamerasCount >= 2)
{
ScopeFOV = Camera.allCameras[1].fieldOfView;
}
if (Camera.allCamerasCount >= 1 && FPSCameraFOV != lastFOV)
{
//Logger.LogInfo("[0] FOV: " + FPSCameraFOV);
lastFOV = FPSCameraFOV;
}
if (Camera.allCamerasCount >= 2 && ScopeFOV != lastFOV2)
{
//Logger.LogInfo("[1] FOV: " + ScopeFOV);
lastFOV2 = ScopeFOV;
}
//nasty workaround for sensitivity while using PIP scopes, WILL break when FOV is set to 50
if (35 < FPSCameraFOV && FPSCameraFOV < configFOV.Value) { currentFOV = FPSCameraFOV; }
if (Camera.allCamerasCount >= 2)
{
if (FPSCameraFOV == 35) { currentFOV = ScopeFOV; }
if (FPSCameraFOV == configFOV.Value - 15) { currentFOV = FPSCameraFOV; }
}
////do the magic!
mySens = CalculateSensitivity(currentFOV, configFOV.Value, configSens.Value);
//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); }
}
}
}