using BepInEx; using BepInEx.Configuration; using EFT; using UnityEngine; using Comfort.Common; using System.Reflection; using System.Collections; using EFT.Settings.Graphics; namespace ScopeTweaks { [BepInPlugin("com.notGreg.scopeTweaks", "notGreg's Scope Tweaks", "2.0.0")] public class Plugin : BaseUnityPlugin { ConfigEntry cameraResolutionScale; ConfigEntry scopeCameraResolutionScale; ConfigEntry scopeFixType; enum EFOVScalingMode { Disabled, Enabled, } void Awake() { cameraResolutionScale = Config.Bind( "General", "Main camera scale %", 80, new ConfigDescription("Main camera resolution scale", new AcceptableValueRange(25, 100))); scopeCameraResolutionScale = Config.Bind( "General", "Scope camera scale %", 80, new ConfigDescription("Scope camera resolution scale", new AcceptableValueRange(25, 100))); scopeFixType = Config.Bind("General", "High FOV scope tweak", EFOVScalingMode.Enabled, new ConfigDescription("")); } Camera FPSCamera = null; Camera scopeCamera = null; SSAA ssaaInstance = null; FieldInfo _nextSSRation = null; WaitForSeconds myDelaySec = new WaitForSeconds(1); void Update() { if (Singleton.Instance == null) return; GameStatus currentGameState = Singleton.Instance.Status; if (!gameStateChanged(currentGameState)) return; switch(currentGameState) { case GameStatus.Started: { //Logger.LogInfo("Getting local player"); mainPlayer = getLocalPlayer(); subscribeHandsChangedEvent(); //Logger.LogInfo("Assigning cameras..."); StartCoroutine(tryGetMainCamera()); StartCoroutine(tryGetScopeCamera()); break; } case GameStatus.SoftStopping: case GameStatus.Stopped: { //Logger.LogInfo("Resetting..."); FPSCamera = null; scopeCamera = null; mainPlayer = null; break; } default: break; } } /// /// GAME STATUS /// GameStatus lastGameState; bool gameStateChanged(GameStatus currentState) { if (currentState == lastGameState) return false; lastGameState = currentState; return true; } Player mainPlayer; Player getLocalPlayer() { return Singleton.Instance.RegisteredPlayers.Find(p => p.IsYourPlayer); } /// /// FIELD OF VIEW /// int inGameFOV; int getInGameFOV() { int fov = Singleton.Instance.Game.Settings.FieldOfView.Value; //Logger.LogInfo($"In-game FOV: {fov}"); return fov; } void setInGameFOV(int value) { //Logger.LogInfo($"Setting FOV to {value}"); Singleton.Instance.Game.Settings.FieldOfView.Value = value; } /// /// CAMERA SETUP /// IEnumerator tryGetMainCamera() { string cameraName = "FPS Camera"; if (GameObject.Find(cameraName) != null) { FPSCamera = GameObject.Find(cameraName).GetComponent(); //Logger.LogInfo($"{FPSCamera.name} found!"); } else { //Logger.LogMessage($"Camera \"{cameraName}\" not found, rescheduling..."); yield return myDelaySec; StartCoroutine(tryGetMainCamera()); yield break; } yield return null; } FieldInfo getFieldInfo(string fieldName) { return typeof(SSAA).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); } IEnumerator tryGetScopeCamera() { string cameraName = "BaseOpticCamera(Clone)"; if (GameObject.Find(cameraName) != null) { scopeCamera = GameObject.Find(cameraName).GetComponent(); //Logger.LogInfo($"Camera \"{scopeCamera.name}\" found!"); } yield break; } void setMainCameraResolutionScale(int value = 100) { //Logger.LogInfo($"Setting MainCam res scale to {value}%"); ssaaInstance = FPSCamera.GetComponent(); _nextSSRation = getFieldInfo("_nextSSRation"); _nextSSRation.SetValue(ssaaInstance, (float)(currentScalingFactor * value / 100f)); } void setScopeCameraResolutionScale(int value) { if(scopeCamera == null || !scopeCamera.isActiveAndEnabled) { //Logger.LogInfo("ScopeCam inactive or absent!"); return; } //Logger.LogInfo($"Setting Scope res scale to {value}%"); scopeCamera.GetComponent().OpticCameraToMainCameraResolutionRatio = (float)(currentScalingFactor * value / 100); } /// /// PLAYER WEAPON EVENTS /// void subscribeHandsChangedEvent() { //Logger.LogInfo("Subscribing to HandsChanged Event"); mainPlayer.HandsChangedEvent += (handsArgs) => { subscribeOnAimingChangedEvent(); }; } void subscribeOnAimingChangedEvent() { //Logger.LogInfo("Subscribing to OnAimingChanged Event"); mainPlayer.HandsController.OnAimingChanged += (aimingArgs) => { if (scopeFixType.Value != EFOVScalingMode.Enabled) return; if(!mainPlayer.ProceduralWeaponAnimation.IsAiming) { GClass1774.Instance.SetFov(inGameFOV, 0.33f, false); setInGameFOV(inGameFOV); } setMainCameraResolutionScale(); currentScalingFactor = getCurrentScalingFactor(); StartCoroutine(tryGetScopeCamera()); if(mainPlayer.HandsController.IsAiming) { if(inGameFOV != 50) { inGameFOV = getInGameFOV(); } GClass1774.Instance.SetFov(35, 0.25f, false); setInGameFOV(50); setMainCameraResolutionScale(cameraResolutionScale.Value); setScopeCameraResolutionScale(scopeCameraResolutionScale.Value); return; } }; } /// /// IN-GAME SETTINGS /// float currentScalingFactor; float getCurrentScalingFactor() { //Logger.LogInfo("Getting current scaling factor:"); var graphics = Singleton.Instance.Graphics.Settings; if (!graphics.DLSSEnabled && !graphics.FSREnabled) { //Logger.LogInfo($"Supersampling factor: {graphics.SuperSamplingFactor}"); return graphics.SuperSamplingFactor; } if (graphics.DLSSEnabled) { float DLSSFactor = 1.0f; switch (graphics.DLSSMode.Value) { case EDLSSMode.Off: { DLSSFactor = 1.0f; break; } case EDLSSMode.Quality: { DLSSFactor = 0.67f; break; } case EDLSSMode.Balanced: { DLSSFactor = 0.58f; break; } case EDLSSMode.Performance: { DLSSFactor = 0.5f; break; } case EDLSSMode.UltraPerformance: { DLSSFactor = 0.33f; break; } } //Logger.LogInfo($"DLSS factor: {DLSSFactor}"); return DLSSFactor; } if (graphics.FSREnabled) { float FSRFactor = 1.0f; switch (graphics.FSRMode.Value) { case EFSRMode.Off: { FSRFactor = 1.0f; break; } case EFSRMode.UltraQuality: { FSRFactor = 0.77f; break; } case EFSRMode.Quality: { FSRFactor = 0.66f; break; } case EFSRMode.Balanced: { FSRFactor = 0.59f; break; } case EFSRMode.Performance: { FSRFactor = 0.5f; break; } } //Logger.LogInfo($"FSR factor: {FSRFactor}"); return FSRFactor; } //Logger.LogInfo($"GetCurrentScalingFactor(): Something went wrong. Returning 1.0f"); return 1.0f; } } }