Compare commits

...

4 Commits

Author SHA1 Message Date
e12a9a69ed Updated for SPT-AKI 3.8.0 2024-04-26 14:03:42 +02:00
gregkprojects
090125b836 Updated for SPT-AKI 3.7.6
Sensitivity as integer for UX (float was too finnicky)
2024-01-02 17:14:30 +01:00
4a8da5a6ac Updated version number :) Code is fine, just needs to be recompiled with the latest assemblies. 2023-06-01 18:05:45 +02:00
eca93b02cd Improved sight detection logic. 2023-04-01 16:44:32 +02:00
3 changed files with 65 additions and 134 deletions

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32602.215 VisualStudioVersion = 17.2.32602.215
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TarkovUniformAim", "TarkovUniformAim\notGreg.UniformAim.csproj", "{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "notGreg.UniformAim", "TarkovUniformAim\notGreg.UniformAim.csproj", "{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -11,8 +11,8 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Debug|Any CPU.Build.0 = Debug|Any CPU {B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Debug|Any CPU.Build.0 = Release|Any CPU
{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Release|Any CPU.ActiveCfg = Release|Any CPU {B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Release|Any CPU.Build.0 = Release|Any CPU {B2F4587D-CFE6-42A6-8462-A884EB6E15CD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection

View File

@ -7,29 +7,35 @@ using System;
using System.Collections; using System.Collections;
using UnityEngine; using UnityEngine;
//Assembly-CSharp.dll
//Aki.Reflection.dll // DLL dependencies needed to update the Uniform Aim Mod for newer versions of the game
//BepInEx.dll //%tarkovdir%\BepInEx\core\BepInEx.dll
//Comfort.dll //%tarkovdir%\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll
//UnityEngine.dll //%tarkovdir%\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll
//UnityEngine.CoreModule.dll //%tarkovdir%\EscapeFromTarkov_Data\Managed\Comfort.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\UnityEngine.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll
namespace notGreg.UniformAim namespace notGreg.UniformAim
{ {
[BepInPlugin("com.notGreg.UniformAim", "notGreg's Uniform Aim for Tarkov", "3.5.0")] [BepInPlugin("com.notGreg.UniformAim", "notGreg's Uniform Aim for Tarkov", "3.8.0")]
[BepInDependency("RealismMod", BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency("RealismMod", BepInDependency.DependencyFlags.SoftDependency)]
public class Plugin : BaseUnityPlugin public class Plugin : BaseUnityPlugin
{ {
ConfigEntry<int> configExponent; ConfigEntry<int> configExponent;
ConfigEntry<float> configSens; ConfigEntry<int> configSens;
ConfigEntry<bool> enableDebug;
public static bool isRealismModPresent = Chainloader.PluginInfos.ContainsKey("RealismMod"); public static bool isRealismModPresent = Chainloader.PluginInfos.ContainsKey("RealismMod");
void Awake() void Awake()
{ {
configExponent = Config.Bind("General", "Coefficient", 133, new ConfigDescription("", new AcceptableValueRange<int>(10, 500))); configExponent = Config.Bind("General", "Coefficient", 133, new ConfigDescription("", new AcceptableValueRange<int>(10, 500)));
configSens = Config.Bind("General", "Sensitivity", 1.0f, new ConfigDescription("", new AcceptableValueRange<float>(0.01f, 2.0f))); //configSens = Config.Bind("General", "Sensitivity", 1.0f, new ConfigDescription("", new AcceptableValueRange<float>(0.01f, 2.0f))); // an old float-based sensitivity for future reference
configSens = Config.Bind("General", "Sensitivity", 100, new ConfigDescription("", new AcceptableValueRange<int>(10, 200)));
enableDebug = Config.Bind("Debug", "Enable debug logging", false);
if (!isRealismModPresent) if (!isRealismModPresent)
@ -38,7 +44,7 @@ namespace notGreg.UniformAim
} }
else else
{ {
Logger.LogInfo("RealismMod detected! Abandoning aimingSens patch...\nMake sure to use the compatibility plugin!"); if(enableDebug.Value) Logger.LogInfo("RealismMod detected! Abandoning aimingSens patch...\nMake sure to use the compatibility plugin!");
} }
} }
@ -52,22 +58,17 @@ namespace notGreg.UniformAim
void FixedUpdate() void FixedUpdate()
{ {
//check if the world instance exists //check if the world instance exists
//Logger.LogInfo("Checking world instance");
if (Singleton<AbstractGame>.Instance == null) if (Singleton<AbstractGame>.Instance == null)
{ {
return; return;
} }
//grab the game status of the existing instance //grab the game status of the existing instance
//Logger.LogInfo("Checking game status");
GameStatus currentGameStatus = Singleton<AbstractGame>.Instance.Status; GameStatus currentGameStatus = Singleton<AbstractGame>.Instance.Status;
//check if the game has started and if the player exists. If the player is aiming, update the scoped sensitivity (executed every frame while aiming) //check if the game has started and if the player exists. If the player is aiming, update the scoped sensitivity (executed every frame while aiming)
//Logger.LogInfo("Checking GameStatus and isAiming");
//Logger.LogInfo($"GameStatus: {currentGameStatus}");
if (currentGameStatus == GameStatus.Started && mainPlayer != null) if (currentGameStatus == GameStatus.Started && mainPlayer != null)
{ {
//Logger.LogInfo($"isAiming? {mainPlayer.HandsController.IsAiming}");
if (mainPlayer.HandsController.IsAiming) if (mainPlayer.HandsController.IsAiming)
{ {
aimingSens = calculateSensitivity(); aimingSens = calculateSensitivity();
@ -75,16 +76,16 @@ namespace notGreg.UniformAim
return; return;
} }
//Logger.LogInfo("Switch on GameStatus"); if(enableDebug.Value) Logger.LogInfo("Switch on GameStatus");
switch (currentGameStatus) switch (currentGameStatus)
{ {
case GameStatus.Started: case GameStatus.Started:
{ {
mainPlayer = getLocalPlayer(); mainPlayer = getLocalPlayer();
//Logger.LogInfo($"Subscribing to onAimingChanged event"); if(enableDebug.Value) Logger.LogInfo($"Subscribing to onAimingChanged event");
subscribeOnAimingChanged(); subscribeOnAimingChanged();
//Logger.LogInfo("TryGetCameras coroutines"); if(enableDebug.Value) Logger.LogInfo("TryGetCameras coroutines");
StartCoroutine(tryGetMainCamera()); StartCoroutine(tryGetMainCamera());
StartCoroutine(tryGetScopeCamera()); StartCoroutine(tryGetScopeCamera());
@ -106,38 +107,26 @@ namespace notGreg.UniformAim
} }
//this function grabs the Field of View from the settings. This is the function that most often needs patching after update. //this function grabs the Field of View from the settings. This is the function that most often needs patching after update.
//Appropriate class can usually be found by searching for the ClearSettings function. //Appropriate class can usually be found by searching for the "ClearSettings" function.
//SharedGameSettingsClass settingsLibrary = SharedGameSettingsClass.Instance; // Futureproofing for 3.5.1 and onwards
int getInGameFOV() int getInGameFOV()
{ {
//int fov = Singleton<GClass1642>.Instance.Game.Settings.FieldOfView; //SPT-AKI 3.2.3 int fov = Singleton<SharedGameSettingsClass>.Instance.Game.Settings.FieldOfView;
//int fov = Singleton<GClass1653>.Instance.Game.Settings.FieldOfView; //SPT-AKI 3.3.0
//int fov = Singleton<GClass1659>.Instance.Game.Settings.FieldOfView; //SPT-AKI 3.4.1
//int fov = Singleton<GClass1776>.Instance.Game.Settings.FieldOfView; //SPT-AKI 3.5.0
int fov = Singleton<SharedGameSettingsClass>.Instance.Game.Settings.FieldOfView; //SPT-AKI 3.5.3
return fov; return fov;
} }
//this function grabs the Aiming Sensitivity from the settings. This is the function that most often needs patching after update. //this function grabs the Aiming Sensitivity from the settings. This is the function that most often needs patching after update.
//Appropriate class can usually be found by searching for the ClearSettings function. //Appropriate class can usually be found by searching for the "ClearSettings" function.
float getInGameAimSens() float getInGameAimSens()
{ {
//float sens = Singleton<GClass1642>.Instance.Control.Settings.MouseAimingSensitivity; //SPT-AKI 3.2.* float sens = Singleton<SharedGameSettingsClass>.Instance.Control.Settings.MouseAimingSensitivity;
//float sens = Singleton<GClass1653>.Instance.Control.Settings.MouseAimingSensitivity; //SPT-AKI 3.3.0 if(enableDebug.Value) Logger.LogInfo($"In-game AimSens: {sens}");
//float sens = Singleton<GClass1659>.Instance.Control.Settings.MouseAimingSensitivity; //SPT-AKI 3.4.1
//float sens = Singleton<GClass1776>.Instance.Control.Settings.MouseAimingSensitivity; //SPT-AKI 3.5.0
float sens = Singleton<SharedGameSettingsClass>.Instance.Control.Settings.MouseAimingSensitivity; //SPT-AKI 3.5.3
//float sens = settingsLibrary.Control.Settings.MouseAimingSensitivity;
//Logger.LogInfo($"In-game AimSens: {sens}");
return sens; return sens;
} }
Player getLocalPlayer() Player getLocalPlayer()
{ {
//Logger.LogInfo("Setting local player..."); if(enableDebug.Value) Logger.LogInfo("Setting local player...");
return Singleton<GameWorld>.Instance.RegisteredPlayers.Find(p => p.IsYourPlayer); return Singleton<GameWorld>.Instance.RegisteredPlayers.Find(p => p.IsYourPlayer) as Player;
} }
WaitForSecondsRealtime myDelay = new WaitForSecondsRealtime(1f); WaitForSecondsRealtime myDelay = new WaitForSecondsRealtime(1f);
@ -151,11 +140,11 @@ namespace notGreg.UniformAim
if (GameObject.Find(cameraName) != null) if (GameObject.Find(cameraName) != null)
{ {
mainCamera = GameObject.Find(cameraName).GetComponent<Camera>(); mainCamera = GameObject.Find(cameraName).GetComponent<Camera>();
//Logger.LogInfo($"{mainCamera.name} found!"); if (enableDebug.Value) Logger.LogInfo($"{mainCamera.name} found!");
} }
else else
{ {
//Logger.LogMessage($"Camera \"{cameraName}\" not found, rescheduling..."); if (enableDebug.Value) Logger.LogMessage($"Camera \"{cameraName}\" not found, rescheduling...");
yield return myDelay; yield return myDelay;
StartCoroutine(tryGetMainCamera()); StartCoroutine(tryGetMainCamera());
yield break; yield break;
@ -163,106 +152,42 @@ namespace notGreg.UniformAim
yield return null; yield return null;
} }
//this coroutine attempts to find existing baseOpticCamera in the scene. The state of this camera is used to determine whether the player is using a magnified optic or not. //this coroutine attempts to find existing baseOpticCamera in the scene.
IEnumerator tryGetScopeCamera() IEnumerator tryGetScopeCamera()
{ {
string cameraName = "BaseOpticCamera(Clone)"; string cameraName = "BaseOpticCamera(Clone)";
if (GameObject.Find(cameraName) != null) if (GameObject.Find(cameraName) != null)
{ {
scopeCamera = GameObject.Find(cameraName).GetComponent<Camera>(); scopeCamera = GameObject.Find(cameraName).GetComponent<Camera>();
//Logger.LogInfo($"{scopeCamera.name} found!"); if(enableDebug.Value) Logger.LogInfo($"{scopeCamera.name} found!");
} }
yield break; yield break;
} }
//figure out whether the player is using a magnified optic or not. Return the FOV of the sight. //figure out whether the player is using a magnified optic or not. Return the camera of the sight.
Camera determineCurrentAimedFOV() float determineCurrentAimedFOV()
{ {
//Logger.LogInfo("Get current aiming mod"); if(enableDebug.Value)
//Logger.LogInfo($"MainPlayer {mainPlayer.name}");
//Logger.LogInfo($"ProcWeapAnim {mainPlayer.ProceduralWeaponAnimation}");
//Logger.LogInfo($"CurrAimMod {mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod}");
if (mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod == null)
{ {
return mainCamera; Logger.LogInfo($"Current scope: {mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.Item.LocalizedName()} isOptic? {mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic}");
} }
var currentAimingMod = mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod; if (mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic)
//get the name of the currently active scope
//string scopeName = currentAimingMod.Item.Template.Name;
string scopeName = currentAimingMod.Item.Name;
//Logger.LogInfo($"Scope name: {scopeName}");
//scopeMode determines the scope being used (e.g. main magnified optic at index 0, backup RDS at index 1)
//scopeIndex determines the mode of the scope being used (e.g. x1 magnification at index 0, x4 magnification at index 1)
//there are exceptions to this rule thanks to BSG's inconsistency, some of them are patched below
var scopeIndex = currentAimingMod.SelectedScopeIndex;
var scopeMode = currentAimingMod.SelectedScopeMode;
//Logger.LogInfo("Index: " + scopeIndex + "\nMode: " + scopeMode);
//patches for specific scopes, matches item name
switch (scopeName)
{ {
case "tactical_mp155_kalashnikov_ultima_camera": return scopeCamera.fieldOfView;
{
//Logger.LogInfo("MP-155 Thermal");
return mainCamera;
}
//SAM-SWAT's Leupold D-Evo optic patch. The modes on this scope are reversed. Causes detection based on baseOpticCamera to fail as the magnified optic camera is always active
case "scope_leupold_d_evo":
{
if (scopeMode == 0)
{
//Logger.LogInfo($"Leupold D-EVO BUIS FOV: {mainCamera.fieldOfView}");
return mainCamera;
}
else
{
//Logger.LogInfo($"Leupold D-EVO Scope FOV: {scopeCamera.fieldOfView}");
return scopeCamera;
}
}
case "scope_base_trijicon_acog_ta11_3,5x35":
{
if (scopeIndex == 1)
{
//Logger.LogInfo($"G36 Rail sight");
return mainCamera;
}
else
{
return scopeCamera;
}
}
default:
{
if (scopeCamera == null || scopeCamera.isActiveAndEnabled == false)
{
//Logger.LogInfo($"Non-magnified: {scopeName} FOV: {mainCamera.fieldOfView}");
return mainCamera;
}
else
{
//Logger.LogInfo($"Magnified: {scopeName} FOV: {scopeCamera.fieldOfView}");
return scopeCamera;
}
}
} }
return mainCamera.fieldOfView;
} }
float calculateSensitivity() float calculateSensitivity()
{ {
//Logger.LogInfo("calculateSensitivity()"); if(enableDebug.Value) Logger.LogInfo("calculateSensitivity()");
//grab vertical hipfire field of view (FOV set by the user in the setting), then convert it to horizontal FOV //grab vertical hipfire field of view (FOV set by the user in the setting), then convert it to horizontal FOV
//convert degrees to radians //convert degrees to radians
float hipFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(inGameFOV, mainCamera.aspect); float hipFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(inGameFOV, mainCamera.aspect);
//grab current field of view while aiming, then convert it to horizontal FOV //grab current field of view while aiming, then convert it to horizontal FOV
//convert degrees to radians //convert degrees to radians
float aimedFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(determineCurrentAimedFOV().fieldOfView, mainCamera.aspect); float aimedFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(determineCurrentAimedFOV(), mainCamera.aspect);
//exponent applied to the ratio of aimedFOV to hipFOV, causes sights to become relatively faster or slower as zoom increases //exponent applied to the ratio of aimedFOV to hipFOV, causes sights to become relatively faster or slower as zoom increases
float exponent = 100f / configExponent.Value; float exponent = 100f / configExponent.Value;
@ -271,8 +196,8 @@ namespace notGreg.UniformAim
float sensitivity = (float)Math.Pow(tanRatio, exponent) * inGameAimedSens; float sensitivity = (float)Math.Pow(tanRatio, exponent) * inGameAimedSens;
//Logger.LogInfo($"Sensitivity: {sensitivity}"); if(enableDebug.Value) Logger.LogInfo($"Sensitivity: {sensitivity}");
return sensitivity * configSens.Value; return sensitivity * (configSens.Value / 100.0f);
} }
@ -285,6 +210,7 @@ namespace notGreg.UniformAim
//onAimingChanged triggers whenever the player starts or stops aiming. //onAimingChanged triggers whenever the player starts or stops aiming.
mainPlayer.HandsController.OnAimingChanged += (aimArgs) => mainPlayer.HandsController.OnAimingChanged += (aimArgs) =>
{ {
if (enableDebug.Value) Logger.LogInfo($"Scope: {mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.Item.LocalizedName()} isOptic? {mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic}");
inGameFOV = getInGameFOV(); inGameFOV = getInGameFOV();
inGameAimedSens = getInGameAimSens(); inGameAimedSens = getInGameAimSens();
StartCoroutine(tryGetScopeCamera()); StartCoroutine(tryGetScopeCamera());

View File

@ -7,8 +7,8 @@
<ProjectGuid>{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}</ProjectGuid> <ProjectGuid>{B2F4587D-CFE6-42A6-8462-A884EB6E15CD}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TarkovUniformAim</RootNamespace> <RootNamespace>UniformAim</RootNamespace>
<AssemblyName>TarkovUniformAim</AssemblyName> <AssemblyName>notGreg.UniformAim</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
@ -36,24 +36,29 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Aki.Reflection"> <Reference Include="Aki.Reflection, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>G:\SPT\SPT-AKI 3.8.0\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll</HintPath>
</Reference> </Reference>
<Reference Include="Assembly-CSharp"> <Reference Include="Assembly-CSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>G:\SPT\SPT-AKI 3.8.0\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference> </Reference>
<Reference Include="BepInEx"> <Reference Include="BepInEx, Version=5.4.22.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\BepInEx\core\BepInEx.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>G:\SPT\SPT-AKI 3.8.0\BepInEx\core\BepInEx.dll</HintPath>
</Reference> </Reference>
<Reference Include="Comfort"> <Reference Include="Comfort, Version=1.0.0.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>G:\SPT\SPT-AKI 3.8.0\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="UnityEngine"> <SpecificVersion>False</SpecificVersion>
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\EscapeFromTarkov_Data\Managed\UnityEngine.dll</HintPath> <HintPath>G:\SPT\SPT-AKI 3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.dll</HintPath>
</Reference> </Reference>
<Reference Include="UnityEngine.CoreModule"> <Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>E:\SPT-AKI\SPT-AKI 3.5.0\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>G:\SPT\SPT-AKI 3.8.0\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />