using BepInEx; using BepInEx.Configuration; using Comfort.Common; using EFT; using System; using System.Collections; using UnityEngine; namespace notGreg.UniformAim { [BepInPlugin("com.notGreg.UniformAim", "notGreg's Uniform Aim for Tarkov", "2.0.0")] public class Plugin : BaseUnityPlugin { ConfigEntry configExponent; void Awake() { configExponent = Config.Bind("General", "Coefficient", 133, new ConfigDescription("", new AcceptableValueRange(10, 200))); new get_AimingSensitivityPatch().Enable(); } Player mainPlayer; int inGameFOV; float inGameAimedSens; public static float aimingSens; void Update() { //Logger.LogInfo("Checking world instance"); if (Singleton.Instance == null) { return; } //Logger.LogInfo("Checking game status"); GameStatus currentGameStatus = Singleton.Instance.Status; //Logger.LogInfo("Checking GameStatus and isAiming"); if (currentGameStatus == GameStatus.Started && mainPlayer != null) { //Logger.LogInfo($"isAiming? {mainPlayer.HandsController.IsAiming}"); if (mainPlayer.HandsController.IsAiming) { aimingSens = calculateSensitivity(); } return; } //Logger.LogInfo("Switch on GameStatus"); switch (currentGameStatus) { case GameStatus.Started: { mainPlayer = getLocalPlayer(); //Logger.LogInfo($"Subscribing to onAimingChanged event"); subscribeOnAimingChanged(); inGameFOV = getInGameFOV(); //Logger.LogInfo($"Getting in-game FOV: {inGameFOV}"); inGameAimedSens = getInGameAimSens(); //Logger.LogInfo($"Getting in-game Aiming Sens: {inGameAimedSens}"); //Logger.LogInfo("TryGetCameras coroutines"); StartCoroutine(tryGetMainCamera()); StartCoroutine(tryGetScopeCamera()); break; } case GameStatus.SoftStopping: case GameStatus.Stopped: { mainPlayer = null; break; } default: { break; } } } int getInGameFOV() { return Singleton.Instance.Game.Settings.FieldOfView; ; } float getInGameAimSens() { return Singleton.Instance.Control.Settings.MouseAimingSensitivity; } Player getLocalPlayer() { return Singleton.Instance.RegisteredPlayers.Find(p => p.IsYourPlayer); } WaitForSecondsRealtime myDelay = new WaitForSecondsRealtime(1f); Camera mainCamera; Camera scopeCamera; IEnumerator tryGetMainCamera() { string cameraName = "FPS Camera"; if (GameObject.Find(cameraName) != null) { mainCamera = GameObject.Find(cameraName).GetComponent(); //Logger.LogInfo($"{mainCamera.name} found!"); } else { //Logger.LogMessage($"Camera \"{cameraName}\" not found, rescheduling..."); yield return myDelay; StartCoroutine(tryGetMainCamera()); yield break; } yield return null; } IEnumerator tryGetScopeCamera() { string cameraName = "BaseOpticCamera(Clone)"; if (GameObject.Find(cameraName) != null) { scopeCamera = GameObject.Find(cameraName).GetComponent(); //Logger.LogInfo($"{scopeCamera.name} found!"); } //else //{ //Logger.LogMessage($"Camera \"{cameraName}\" not found");//, rescheduling..."); //yield return myDelay; //StartCoroutine(tryGetScopeCamera()); yield break; //} //yield return null; } float calculateHFOV(Camera camera) { return Camera.VerticalToHorizontalFieldOfView(camera.fieldOfView, camera.aspect); } Camera determineCurrentAimedFOV() { string scopeName = mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.Item.Name; var scopeIndex = mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.SelectedScopeIndex; var scopeMode = mainPlayer.ProceduralWeaponAnimation.CurrentAimingMod.SelectedScopeMode; switch (scopeName) { case "tactical_mp155_kalashnikov_ultima_camera(Clone)": { //Logger.LogInfo("MP-155 Thermal"); return mainCamera; } case "scope_leupold_d_evo(Clone)": { 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; } } 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; } } } } float calculateSensitivity() { float hipFOV = Mathf.Deg2Rad * Camera.VerticalToHorizontalFieldOfView(inGameFOV, mainCamera.aspect); float aimedFOV = Mathf.Deg2Rad * calculateHFOV(determineCurrentAimedFOV()); float exponent = 100f / configExponent.Value; float tanRatio = (float)(Mathf.Tan(aimedFOV / 2) / Mathf.Tan(hipFOV / 2)); float sensitivity = (float)Math.Pow(tanRatio, exponent); //Logger.LogInfo($"Final sensitivity: {sensitivity * inGameAimedSens}"); return sensitivity * inGameAimedSens; } void subscribeOnAimingChanged() { mainPlayer.HandsChangedEvent += (handsArgs) => { StartCoroutine(tryGetScopeCamera()); mainPlayer.HandsController.OnAimingChanged += (aimArgs) => { inGameFOV = getInGameFOV(); inGameAimedSens = getInGameAimSens(); StartCoroutine(tryGetScopeCamera()); }; }; } } }