222 lines
9.1 KiB
C#
Raw Permalink Normal View History

2022-12-10 16:47:02 +01:00
using BepInEx;
using BepInEx.Bootstrap;
2022-12-10 16:47:02 +01:00
using BepInEx.Configuration;
using Comfort.Common;
using EFT;
using System;
using System.Collections;
using UnityEngine;
2024-04-26 14:03:42 +02:00
// DLL dependencies needed to update the Uniform Aim Mod for newer versions of the game
//%tarkovdir%\BepInEx\core\BepInEx.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\Aki.Reflection.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\Comfort.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\UnityEngine.dll
//%tarkovdir%\EscapeFromTarkov_Data\Managed\UnityEngine.CoreModule.dll
2023-02-28 15:47:02 +01:00
2022-12-10 16:47:02 +01:00
namespace notGreg.UniformAim
{
2024-04-26 14:03:42 +02:00
[BepInPlugin("com.notGreg.UniformAim", "notGreg's Uniform Aim for Tarkov", "3.8.0")]
[BepInDependency("RealismMod", BepInDependency.DependencyFlags.SoftDependency)]
2022-12-10 16:47:02 +01:00
public class Plugin : BaseUnityPlugin
{
ConfigEntry<int> configExponent;
ConfigEntry<int> configSens;
2023-04-01 16:44:32 +02:00
ConfigEntry<bool> enableDebug;
2022-12-10 16:47:02 +01:00
public static bool isRealismModPresent = Chainloader.PluginInfos.ContainsKey("RealismMod");
2022-12-10 16:47:02 +01:00
void Awake()
{
2023-02-28 15:47:02 +01:00
configExponent = Config.Bind("General", "Coefficient", 133, new ConfigDescription("", new AcceptableValueRange<int>(10, 500)));
2024-04-26 14:03:42 +02:00
//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)));
2022-12-10 16:47:02 +01:00
2023-04-01 16:44:32 +02:00
enableDebug = Config.Bind("Debug", "Enable debug logging", false);
if (!isRealismModPresent)
{
new get_AimingSensitivityPatch().Enable();
}
2023-02-28 15:47:02 +01:00
else
{
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo("RealismMod detected! Abandoning aimingSens patch...\nMake sure to use the compatibility plugin!");
2023-02-28 15:47:02 +01:00
}
2022-12-10 16:47:02 +01:00
}
Player mainPlayer;
int inGameFOV;
float inGameAimedSens;
public static float aimingSens = 1.0f;
2022-12-10 16:47:02 +01:00
//this function can be replaced by FixedUpdate() at 50Hz (adjustable via Time.fixedDeltaTime)
//FixedUpdate() proved to be slightly more reliable in the past, however it had other unintended effects on the game.
void FixedUpdate()
{
//check if the world instance exists
if (Singleton<AbstractGame>.Instance == null)
{
return;
}
//grab the game status of the existing instance
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)
if (currentGameStatus == GameStatus.Started && mainPlayer != null)
{
if (mainPlayer.HandsController.IsAiming)
{
2023-02-28 15:47:02 +01:00
aimingSens = calculateSensitivity();
2022-12-10 16:47:02 +01:00
}
return;
}
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo("Switch on GameStatus");
2022-12-10 16:47:02 +01:00
switch (currentGameStatus)
{
case GameStatus.Started:
{
mainPlayer = getLocalPlayer();
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo($"Subscribing to onAimingChanged event");
2022-12-10 16:47:02 +01:00
subscribeOnAimingChanged();
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo("TryGetCameras coroutines");
2022-12-10 16:47:02 +01:00
StartCoroutine(tryGetMainCamera());
StartCoroutine(tryGetScopeCamera());
break;
}
case GameStatus.SoftStopping:
case GameStatus.Stopped:
{
mainPlayer = null;
break;
}
default:
{
break;
}
}
2023-02-28 15:47:02 +01:00
2022-12-10 16:47:02 +01:00
}
//this function grabs the Field of View from the settings. This is the function that most often needs patching after update.
2024-04-26 14:03:42 +02:00
//Appropriate class can usually be found by searching for the "ClearSettings" function.
2022-12-10 16:47:02 +01:00
int getInGameFOV()
{
2024-04-26 14:03:42 +02:00
int fov = Singleton<SharedGameSettingsClass>.Instance.Game.Settings.FieldOfView;
2022-12-10 16:47:02 +01:00
return fov;
}
//this function grabs the Aiming Sensitivity from the settings. This is the function that most often needs patching after update.
2024-04-26 14:03:42 +02:00
//Appropriate class can usually be found by searching for the "ClearSettings" function.
2022-12-10 16:47:02 +01:00
float getInGameAimSens()
{
2024-04-26 14:03:42 +02:00
float sens = Singleton<SharedGameSettingsClass>.Instance.Control.Settings.MouseAimingSensitivity;
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo($"In-game AimSens: {sens}");
2022-12-10 16:47:02 +01:00
return sens;
}
Player getLocalPlayer()
{
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo("Setting local player...");
return Singleton<GameWorld>.Instance.RegisteredPlayers.Find(p => p.IsYourPlayer) as Player;
2022-12-10 16:47:02 +01:00
}
WaitForSecondsRealtime myDelay = new WaitForSecondsRealtime(1f);
Camera mainCamera;
Camera scopeCamera;
//this coroutine attempts to find the FPS Camera in the scene.
IEnumerator tryGetMainCamera()
{
string cameraName = "FPS Camera";
if (GameObject.Find(cameraName) != null)
{
mainCamera = GameObject.Find(cameraName).GetComponent<Camera>();
2023-04-01 16:44:32 +02:00
if (enableDebug.Value) Logger.LogInfo($"{mainCamera.name} found!");
2022-12-10 16:47:02 +01:00
}
else
{
2023-04-01 16:44:32 +02:00
if (enableDebug.Value) Logger.LogMessage($"Camera \"{cameraName}\" not found, rescheduling...");
2022-12-10 16:47:02 +01:00
yield return myDelay;
StartCoroutine(tryGetMainCamera());
yield break;
}
yield return null;
}
2023-04-01 16:44:32 +02:00
//this coroutine attempts to find existing baseOpticCamera in the scene.
2022-12-10 16:47:02 +01:00
IEnumerator tryGetScopeCamera()
{
string cameraName = "BaseOpticCamera(Clone)";
if (GameObject.Find(cameraName) != null)
{
scopeCamera = GameObject.Find(cameraName).GetComponent<Camera>();
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo($"{scopeCamera.name} found!");
2022-12-10 16:47:02 +01:00
}
yield break;
}
2023-04-01 16:44:32 +02:00
//figure out whether the player is using a magnified optic or not. Return the camera of the sight.
float determineCurrentAimedFOV()
2022-12-10 16:47:02 +01:00
{
2023-04-01 16:44:32 +02:00
if(enableDebug.Value)
{
2023-04-01 16:44:32 +02:00
Logger.LogInfo($"Current scope: {mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.Item.LocalizedName()} isOptic? {mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic}");
}
2023-04-01 16:44:32 +02:00
if (mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic)
2022-12-10 16:47:02 +01:00
{
2023-04-01 16:44:32 +02:00
return scopeCamera.fieldOfView;
2022-12-10 16:47:02 +01:00
}
2023-04-01 16:44:32 +02:00
return mainCamera.fieldOfView;
2022-12-10 16:47:02 +01:00
}
float calculateSensitivity()
{
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo("calculateSensitivity()");
2022-12-10 16:47:02 +01:00
//grab vertical hipfire field of view (FOV set by the user in the setting), then convert it to horizontal FOV
//convert degrees to radians
float hipFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(inGameFOV, mainCamera.aspect);
//grab current field of view while aiming, then convert it to horizontal FOV
//convert degrees to radians
2023-04-01 16:44:32 +02:00
float aimedFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(determineCurrentAimedFOV(), mainCamera.aspect);
2022-12-10 16:47:02 +01:00
//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;
2023-03-25 11:28:04 +01:00
2022-12-10 16:47:02 +01:00
float tanRatio = (float)(Mathf.Tan(aimedFOV / 2) / Mathf.Tan(hipFOV / 2));
float sensitivity = (float)Math.Pow(tanRatio, exponent) * inGameAimedSens;
2023-04-01 16:44:32 +02:00
if(enableDebug.Value) Logger.LogInfo($"Sensitivity: {sensitivity}");
return sensitivity * (configSens.Value / 100.0f);
2022-12-10 16:47:02 +01:00
}
void subscribeOnAimingChanged()
{
//HandsChangedEvent triggers whenever player changes weapons
//without it the patch would cease to work as expected when weapons were changed
mainPlayer.HandsChangedEvent += (handsArgs) =>
{
//onAimingChanged triggers whenever the player starts or stops aiming.
mainPlayer.HandsController.OnAimingChanged += (aimArgs) =>
{
2023-04-01 16:44:32 +02:00
if (enableDebug.Value) Logger.LogInfo($"Scope: {mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.Item.LocalizedName()} isOptic? {mainPlayer.ProceduralWeaponAnimation.CurrentScope.IsOptic}");
2022-12-10 16:47:02 +01:00
inGameFOV = getInGameFOV();
inGameAimedSens = getInGameAimSens();
StartCoroutine(tryGetScopeCamera());
};
};
}
}
}