completely reworked the code to work off SelectedScope and Camera info instead of Field of View values alone
This commit is contained in:
parent
e41a9f7f35
commit
1896c35a2b
16
README.md
16
README.md
@ -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)
|
@ -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
|
||||
//
|
||||
|
||||
|
||||
}
|
@ -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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user