using Noesis; using StellarConquest.Model.Core; using StellarConquest.Model.Platform; using StellarConquest.RGB; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; using GUI = Noesis.GUI; using NoesisEventArgs = Noesis.EventArgs; namespace StellarConquest.Presentation.Unity.UI { [AssetDependency] public partial class SettingsControl : OverlayControl { private FrameworkElement _Root; private BorderControlTitle _BorderControl; private TabControl _TabControl; // gameplay private CheckBox _WarnSafeParkingEnabled; private CheckBox _WarnEvilEnabled; private CheckBox _GameMenuEnabled; private CheckBox _TargetingEnabled; private CheckBox _WindowDragEnabled; private CheckBox _UIEnabled; private ComboBox _TemperatureUnits; // control private StackPanel _DevicesStackPanel; private CheckBox _MouseConfined; private CheckBox _GamepadEnabled; private TextBlock _CockpitHeadingTextBlock; private CheckBox _CharacterInvertUpEnabled; private Slider _CharacterLookSensitivity; private CheckBox _ShipInvertUpEnabled; private ComboBox _CharacterControl; private ComboBox _InteriorCamera; // display private bool _DisplayInitialized = false; private StackPanel _ResolutionStackPanel; private ComboBox _WindowMode; private StackPanel _DisplayResolutionStackPanel; private ComboBox _Displays; private ComboBox _DisplayResolution; private ComboBox _ResolutionUpscaler; private ComboBox _ResolutionUpscalerQuality; private ComboBox _FrameRateLimit; private ComboBox _VSync; private ComboBox _MotionBlur; private ComboBox _ShowFPS; private StackPanel _QualityStackPanel; private ToggleButton _QualityLow; private ToggleButton _QualityMedium; private ToggleButton _QualityHigh; private ToggleButton _QualityEpic; private ToggleButton _QualityAuto; private ToggleButton _ViewNear; private ToggleButton _ViewMedium; private ToggleButton _ViewFar; private ToggleButton _ViewEpic; private ToggleButton _ShadowsLow; private ToggleButton _ShadowsMedium; private ToggleButton _ShadowsHigh; private ToggleButton _ShadowsEpic; private ToggleButton _ShadowDistanceNear; private ToggleButton _ShadowDistanceMedium; private ToggleButton _ShadowDistanceFar; private ToggleButton _ShadowDistanceEpic; private ToggleButton _TexturesLow; private ToggleButton _TexturesMedium; private ToggleButton _TexturesHigh; private ToggleButton _TexturesEpic; private ToggleButton _ReflectionsOff; private ToggleButton _ReflectionsMedium; private ToggleButton _ReflectionsHigh; private ToggleButton _ReflectionsEpic; private ToggleButton _PostProcessingLow; private ToggleButton _PostProcessingMedium; private ToggleButton _PostProcessingHigh; private ToggleButton _PostProcessingEpic; private ToggleButton _DetailLow; private ToggleButton _DetailMedium; private ToggleButton _DetailHigh; private ToggleButton _DetailEpic; private StackPanel _FieldOfViewStackPanel; private Slider _CharacterFieldOfView; private Slider _CockpitFieldOfView; private Slider _ExternalFieldOfView; private Button _ResetFieldOfViewButton; private Slider _BrightnessSlider; private Slider _ContrastSlider; private Button _ResetColorCorrectionButton; // ui private ToggleButton _UISmallest; private ToggleButton _UISmaller; private ToggleButton _UINormal; private ToggleButton _UILarger; private ToggleButton _UILargest; private CheckBox _BlurEffectsEnabled; private Slider _TopBlurSlider; private Slider _BottomBlurSlider; private CheckBox _DesignerHelpUIEnabled; private CheckBox _GameHelpUIEnabled; // sound private CheckBox _MasterVolumeEnabled; private Slider _MasterVolumeSlider; private CheckBox _MusicVolumeEnabled; private Slider _MusicVolumeSlider; private CheckBox _EffectsVolumeEnabled; private Slider _EffectsVolumeSlider; private CheckBox _VoiceVolumeEnabled; private Slider _VoiceVolumeSlider; private CheckBox _UIVolumeEnabled; private Slider _UIVolumeSlider; private CheckBox _AmbientVolumeEnabled; private Slider _AmbientVolumeSlider; // network private TabItem _NetworkTab; private ComboBox _Environment; private Slider _ClientToServerSlider; private Slider _ServerToClientSlider; private TextBlock _ClientToServerRateTextBlock; private TextBlock _ServerToClientRateTextBlock; // generative AI private StackPanel _GenerativeAIStackPanel; private CheckBox _GenerativeTextDialogue; private CheckBox _GenerativeAudioDialogue; // corsair private TabItem _CorsairTab; private StackPanel _RGBStackPanel; private CheckBox _RGBLightingEnabled; private CheckBox _TutorialKeysEnabled; private CheckBox _InputKeysEnabled; private Slider _RGBHueSlider; private Slider _RGBSaturationSlider; private Slider _RGBBrightnessSlider; private Button _ResetCorsairColorCorrectionButton; private StackPanel _CorsairStackPanel; private TextBlock _CorsairNotFoundTextBlock; // about private Hyperlink _HyperlinkButton; private TextBlock _VersionTextBlock; private bool _ApplyEnabled = true; private List _SupportedResolutions; public SettingsControl() { Name = nameof(SettingsControl); IsBlurEnabled = false; IsDragAllowed = true; Initialized += OnInitialized; InitializeComponent(); } protected override void InitializeComponent() { base.InitializeComponent(); GUI.LoadComponent(this, "Assets/User Interface/Screens/Game/Overlay/Settings/SettingsControl.xaml"); _Root = Content as FrameworkElement; _TabControl = _Root.FindName("_TabControl") as TabControl; _BorderControl = _Root.FindName("_BorderControl") as BorderControlTitle; // bind controls: gameplay _WarnSafeParkingEnabled = _Root.FindName("_WarnSafeParkingEnabled") as CheckBox; _WarnEvilEnabled = _Root.FindName("_WarnEvilEnabled") as CheckBox; _GameMenuEnabled = _Root.FindName("_GameMenuEnabled") as CheckBox; _TargetingEnabled = _Root.FindName("_TargetingEnabled") as CheckBox; _WindowDragEnabled = _Root.FindName("_WindowDragEnabled") as CheckBox; _UIEnabled = _Root.FindName("_UIEnabled") as CheckBox; _TemperatureUnits = _Root.FindName(nameof(_TemperatureUnits)) as ComboBox; // bind controls: input _DevicesStackPanel = _Root.FindName(nameof(_DevicesStackPanel)) as StackPanel; _MouseConfined = _Root.FindName("_MouseConfined") as CheckBox; _GamepadEnabled = _Root.FindName("_GamepadEnabled") as CheckBox; _CockpitHeadingTextBlock = _Root.FindName("_CockpitHeadingTextBlock") as TextBlock; _CharacterInvertUpEnabled = _Root.FindName("_CharacterInvertUpEnabled") as CheckBox; _ShipInvertUpEnabled = _Root.FindName("_ShipInvertUpEnabled") as CheckBox; _CharacterControl = _Root.FindName("_CharacterControl") as ComboBox; _InteriorCamera = _Root.FindName("_InteriorCamera") as ComboBox; _CharacterLookSensitivity = _Root.FindName("_CharacterLookSensitivity") as Slider; // bind controls: video _ResolutionStackPanel = _Root.FindName(nameof(_ResolutionStackPanel)) as StackPanel; _WindowMode = _Root.FindName("_WindowMode") as ComboBox; _DisplayResolutionStackPanel = _Root.FindName("_DisplayResolutionStackPanel") as StackPanel; _Displays = _Root.FindName("_Displays") as ComboBox; _DisplayResolution = _Root.FindName("_DisplayResolution") as ComboBox; _ResolutionUpscaler = _Root.FindName(nameof(_ResolutionUpscaler)) as ComboBox; _ResolutionUpscalerQuality = _Root.FindName(nameof(_ResolutionUpscalerQuality)) as ComboBox; _FrameRateLimit = _Root.FindName("_FrameRateLimit") as ComboBox; _VSync = _Root.FindName("_VSync") as ComboBox; _MotionBlur = _Root.FindName("_MotionBlur") as ComboBox; _ShowFPS = _Root.FindName("_ShowFPS") as ComboBox; _QualityStackPanel = _Root.FindName(nameof(_QualityStackPanel)) as StackPanel; _QualityLow = _Root.FindName("_QualityLow") as ToggleButton; _QualityMedium = _Root.FindName("_QualityMedium") as ToggleButton; _QualityHigh = _Root.FindName("_QualityHigh") as ToggleButton; _QualityEpic = _Root.FindName("_QualityEpic") as ToggleButton; _QualityAuto = _Root.FindName("_QualityAuto") as ToggleButton; _ViewNear = _Root.FindName("_ViewNear") as ToggleButton; _ViewMedium = _Root.FindName("_ViewMedium") as ToggleButton; _ViewFar = _Root.FindName("_ViewFar") as ToggleButton; _ViewEpic = _Root.FindName("_ViewEpic") as ToggleButton; _ShadowsLow = _Root.FindName("_ShadowsLow") as ToggleButton; _ShadowsMedium = _Root.FindName("_ShadowsMedium") as ToggleButton; _ShadowsHigh = _Root.FindName("_ShadowsHigh") as ToggleButton; _ShadowsEpic = _Root.FindName("_ShadowsEpic") as ToggleButton; _ShadowDistanceNear = _Root.FindName("_ShadowDistanceNear") as ToggleButton; _ShadowDistanceMedium = _Root.FindName("_ShadowDistanceMedium") as ToggleButton; _ShadowDistanceFar = _Root.FindName("_ShadowDistanceFar") as ToggleButton; _ShadowDistanceEpic = _Root.FindName("_ShadowDistanceEpic") as ToggleButton; _TexturesLow = _Root.FindName("_TexturesLow") as ToggleButton; _TexturesMedium = _Root.FindName("_TexturesMedium") as ToggleButton; _TexturesHigh = _Root.FindName("_TexturesHigh") as ToggleButton; _TexturesEpic = _Root.FindName("_TexturesEpic") as ToggleButton; _ReflectionsOff = _Root.FindName("_ReflectionsOff") as ToggleButton; _ReflectionsMedium = _Root.FindName("_ReflectionsMedium") as ToggleButton; _ReflectionsHigh = _Root.FindName("_ReflectionsHigh") as ToggleButton; _ReflectionsEpic = _Root.FindName("_ReflectionsEpic") as ToggleButton; _PostProcessingLow = _Root.FindName("_PostProcessingLow") as ToggleButton; _PostProcessingMedium = _Root.FindName("_PostProcessingMedium") as ToggleButton; _PostProcessingHigh = _Root.FindName("_PostProcessingHigh") as ToggleButton; _PostProcessingEpic = _Root.FindName("_PostProcessingEpic") as ToggleButton; _DetailLow = _Root.FindName("_DetailLow") as ToggleButton; _DetailMedium = _Root.FindName("_DetailMedium") as ToggleButton; _DetailHigh = _Root.FindName("_DetailHigh") as ToggleButton; _DetailEpic = _Root.FindName("_DetailEpic") as ToggleButton; _FieldOfViewStackPanel = _Root.FindName(nameof(_FieldOfViewStackPanel)) as StackPanel; _CharacterFieldOfView = _Root.FindName("_CharacterFieldOfView") as Slider; _CockpitFieldOfView = _Root.FindName("_CockpitFieldOfView") as Slider; _ExternalFieldOfView = _Root.FindName("_ExternalFieldOfView") as Slider; _ResetFieldOfViewButton = _Root.FindName("_ResetFieldOfViewButton") as Button; _BrightnessSlider = _Root.FindName("_BrightnessSlider") as Slider; _ContrastSlider = _Root.FindName("_ContrastSlider") as Slider; _ResetColorCorrectionButton = _Root.FindName("_ResetColorCorrectionButton") as Button; // UI _UISmallest = _Root.FindName("_UISmallest") as ToggleButton; _UISmaller = _Root.FindName("_UISmaller") as ToggleButton; _UINormal = _Root.FindName("_UINormal") as ToggleButton; _UILarger = _Root.FindName("_UILarger") as ToggleButton; _UILargest = _Root.FindName("_UILargest") as ToggleButton; _BlurEffectsEnabled = _Root.FindName("_BlurEffectsEnabled") as CheckBox; _TopBlurSlider = _Root.FindName("_TopBlurSlider") as Slider; _BottomBlurSlider = _Root.FindName("_BottomBlurSlider") as Slider; _DesignerHelpUIEnabled = _Root.FindName("_DesignerHelpUIEnabled") as CheckBox; _GameHelpUIEnabled = _Root.FindName("_GameHelpUIEnabled") as CheckBox; // bind controls: audio _MasterVolumeEnabled = _Root.FindName("_MasterVolumeEnabled") as CheckBox; _MasterVolumeSlider = _Root.FindName("_MasterVolumeSlider") as Slider; _MusicVolumeEnabled = _Root.FindName("_MusicVolumeEnabled") as CheckBox; _MusicVolumeSlider = _Root.FindName("_MusicVolumeSlider") as Slider; _EffectsVolumeEnabled = _Root.FindName("_EffectsVolumeEnabled") as CheckBox; _EffectsVolumeSlider = _Root.FindName("_EffectsVolumeSlider") as Slider; _VoiceVolumeEnabled = _Root.FindName("_VoiceVolumeEnabled") as CheckBox; _VoiceVolumeSlider = _Root.FindName("_VoiceVolumeSlider") as Slider; _UIVolumeEnabled = _Root.FindName("_UIVolumeEnabled") as CheckBox; _UIVolumeSlider = _Root.FindName("_UIVolumeSlider") as Slider; _AmbientVolumeEnabled = _Root.FindName("_AmbientVolumeEnabled") as CheckBox; _AmbientVolumeSlider = _Root.FindName("_AmbientVolumeSlider") as Slider; // network _NetworkTab = _Root.FindName("_NetworkTab") as TabItem; _Environment = _Root.FindName("_Environment") as ComboBox; _ClientToServerSlider = _Root.FindName("_ClientToServerSlider") as Slider; _ServerToClientSlider = _Root.FindName("_ServerToClientSlider") as Slider; _ClientToServerRateTextBlock = _Root.FindName(nameof(_ClientToServerRateTextBlock)) as TextBlock; _ServerToClientRateTextBlock = _Root.FindName(nameof(_ServerToClientRateTextBlock)) as TextBlock; // generative AI _GenerativeAIStackPanel = _Root.FindName(nameof(_GenerativeAIStackPanel)) as StackPanel; _GenerativeTextDialogue = _Root.FindName(nameof(_GenerativeTextDialogue)) as CheckBox; _GenerativeAudioDialogue = _Root.FindName(nameof(_GenerativeAudioDialogue)) as CheckBox; // corsair _CorsairTab = _Root.FindName(nameof(_CorsairTab)) as TabItem; _RGBStackPanel = _Root.FindName(nameof(_RGBStackPanel)) as StackPanel; _RGBLightingEnabled = _Root.FindName(nameof(_RGBLightingEnabled)) as CheckBox; _TutorialKeysEnabled = _Root.FindName("_TutorialKeysEnabled") as CheckBox; _InputKeysEnabled = _Root.FindName("_InputKeysEnabled") as CheckBox; _RGBHueSlider = _Root.FindName("_RGBHueSlider") as Slider; _RGBSaturationSlider = _Root.FindName("_RGBSaturationSlider") as Slider; _RGBBrightnessSlider = _Root.FindName("_RGBBrightnessSlider") as Slider; _ResetCorsairColorCorrectionButton = _Root.FindName("_ResetCorsairColorCorrectionButton") as Button; _CorsairStackPanel = _Root.FindName("_CorsairStackPanel") as StackPanel; _CorsairNotFoundTextBlock = _Root.FindName("_CorsairNotFoundTextBlock") as TextBlock; // about _HyperlinkButton = _Root.FindName("_HyperLinkButton") as Hyperlink; _VersionTextBlock = _Root.FindName("_VersionTextBlock") as TextBlock; } private void WireEvents(Action action, int defaultIndex, params ToggleButton[] buttons) { buttons[defaultIndex].IsChecked = true; foreach (ToggleButton button in buttons) { button.Checked += (sender, e) => { int index = 0; for (int i = 0; i < buttons.Length; i++) { if (buttons[i].Equals(sender)) index = i; else if (!buttons[i].Equals(sender)) buttons[i].IsChecked = false; } action?.Invoke(index); }; } } protected override void OnInitialized(object sender, NoesisEventArgs args) { base.OnInitialized(sender, args); if (!Application.isPlaying) return; if (PlayerPreferences.Instance == null) return; Update(true); } public void Update(bool wireEvents) { _ApplyEnabled = false; // initialize values: gameplay _WarnSafeParkingEnabled.IsChecked = PlayerPreferences.Instance.WarnSafeParkingEnabled; _WarnEvilEnabled.IsChecked = PlayerPreferences.Instance.WarnEvilEnabled; // initialize values: controls _MouseConfined.IsChecked = PlayerPreferences.Instance.MouseConfined; _GamepadEnabled.IsChecked = PlayerPreferences.Instance.GamepadEnabled; _CharacterInvertUpEnabled.IsChecked = PlayerPreferences.Instance.CharacterInvertUpEnabled; _ShipInvertUpEnabled.IsChecked = PlayerPreferences.Instance.ShipInvertUpEnabled; _CharacterControl.SelectedIndex = (int)PlayerPreferences.Instance.CharacterControl; _InteriorCamera.SelectedIndex = (int)PlayerPreferences.Instance.DefaultInteriorCamera; _CharacterLookSensitivity.Value = PlayerPreferences.Instance.CharacterLookSensitivity; // initialize values: display _WindowMode.SelectedIndex = (int)PlayerPreferences.Instance.FullScreenMode; _FrameRateLimit.SelectedIndex = (int)PlayerPreferences.Instance.FrameRateLimit; _VSync.SelectedIndex = (int)PlayerPreferences.Instance.VSync; _MotionBlur.SelectedIndex = (int)PlayerPreferences.Instance.MotionBlur; _ShowFPS.SelectedIndex = PlayerPreferences.Instance.ShowFPS ? 1 : 0; // diplays List displays = new List(); Screen.GetDisplayLayout(displays); string FilterName(string displayName) { if (string.IsNullOrEmpty(displayName)) return string.Empty; return displayName.Replace("\\", string.Empty); } for (int i = 0; i < displays.Count; i++) { DisplayInfo displayInfo = displays[i]; ComboBoxItem comboBoxItem = new ComboBoxItem(); comboBoxItem.Content = $"{i + 1}: {FilterName(displayInfo.name)}"; comboBoxItem.Tag = displayInfo; _Displays.Items.Add(comboBoxItem); } _Displays.SelectedIndex = PlayerPreferences.Instance.SelectedDisplayIndex; UpdateScreeenResolutions(false); switch (PlayerPreferences.Instance.ResolutionUpscaler) { case ResolutionUpscalerType.DLSS: _ResolutionUpscaler.SelectedIndex = 1; break; case ResolutionUpscalerType.FSR: _ResolutionUpscaler.SelectedIndex = 2; break; case ResolutionUpscalerType.XeSS: _ResolutionUpscaler.SelectedIndex = 3; break; case ResolutionUpscalerType.TAA: case ResolutionUpscalerType.None: default: _ResolutionUpscaler.SelectedIndex = 0; break; } _ResolutionUpscalerQuality.SelectedIndex = (int)(PlayerPreferences.Instance.ResolutionUpscalerQuality - 2); _CharacterFieldOfView.Value = PlayerPreferences.Instance.CharacterFieldOfView; _CockpitFieldOfView.Value = PlayerPreferences.Instance.CockpitFieldOfView; _ExternalFieldOfView.Value = PlayerPreferences.Instance.ExternalFieldOfView; _BrightnessSlider.Value = PlayerPreferences.Instance.Brightness; _ContrastSlider.Value = PlayerPreferences.Instance.Contrast; // initialize values: ui _BlurEffectsEnabled.IsChecked = PlayerPreferences.Instance.BlurEffectsEnabled; _TopBlurSlider.Value = PlayerPreferences.Instance.TopBlurRadius; _BottomBlurSlider.Value = PlayerPreferences.Instance.BottomBlurRadius; _GameMenuEnabled.IsChecked = PlayerPreferences.Instance.GameMenuEnabled; _TargetingEnabled.IsChecked = PlayerPreferences.Instance.TargetingEnabled; _WindowDragEnabled.IsChecked = PlayerPreferences.Instance.WindowDragEnabled; _UIEnabled.IsChecked = PlayerPreferences.Instance.UIEnabled; _DesignerHelpUIEnabled.IsChecked = PlayerPreferences.Instance.DesignerHelpUIEnabled; _GameHelpUIEnabled.IsChecked = PlayerPreferences.Instance.GameHelpUIEnabled; _TemperatureUnits.SelectedIndex = (int)PlayerPreferences.Instance.TemperatureUnits; // initialize values: sound _MasterVolumeEnabled.IsChecked = PlayerPreferences.Instance.MasterVolumeEnabled; _MasterVolumeSlider.Value = PlayerPreferences.Instance.MasterVolume * 100.0f; _MusicVolumeEnabled.IsChecked = PlayerPreferences.Instance.MusicVolumeEnabled; _MusicVolumeSlider.Value = PlayerPreferences.Instance.MusicVolume * 100.0f; _EffectsVolumeEnabled.IsChecked = PlayerPreferences.Instance.EffectsVolumeEnabled; _EffectsVolumeSlider.Value = PlayerPreferences.Instance.EffectsVolume * 100.0f; _VoiceVolumeEnabled.IsChecked = PlayerPreferences.Instance.VoiceVolumeEnabled; _VoiceVolumeSlider.Value = PlayerPreferences.Instance.VoiceVolume * 100.0f; _UIVolumeEnabled.IsChecked = PlayerPreferences.Instance.UIVolumeEnabled; _UIVolumeSlider.Value = PlayerPreferences.Instance.UIVolume * 100.0f; _AmbientVolumeEnabled.IsChecked = PlayerPreferences.Instance.AmbientVolumeEnabled; _AmbientVolumeSlider.Value = PlayerPreferences.Instance.AmbientVolume * 100.0f; // generative ai _GenerativeTextDialogue.IsChecked = PlayerPreferences.Instance.GenerativeTextDialogue; _GenerativeAudioDialogue.IsChecked = PlayerPreferences.Instance.GenerativeAudioDialogue; // initialize values: rgb _RGBLightingEnabled.IsChecked = PlayerPreferences.Instance.RGBLightingEnabled; _TutorialKeysEnabled.IsChecked = PlayerPreferences.Instance.RGBConfiguration.TutorialKeysEnabled; _InputKeysEnabled.IsChecked = PlayerPreferences.Instance.RGBConfiguration.InputKeysEnabled; _Environment.SelectedIndex = (int)PlayerPreferences.Instance.ConquestEnvironment; _ClientToServerSlider.Value = PlayerPreferences.Instance.ClientToServerNetworkUpdateRate; _ServerToClientSlider.Value = PlayerPreferences.Instance.ServerToClientNetworkUpdateRate; _RGBHueSlider.Value = PlayerPreferences.Instance.RGBConfiguration.Hue * 100.0f; _RGBSaturationSlider.Value = PlayerPreferences.Instance.RGBConfiguration.Saturation * 100.0f; _RGBBrightnessSlider.Value = PlayerPreferences.Instance.RGBConfiguration.Brightness * 100.0f; // about _VersionTextBlock.Text = $"Version {VersionUtility.GetVersion()}{Environment.NewLine}{VersionUtility.GetBuildDate()}"; if (!wireEvents) { _ApplyEnabled = true; return; } // events: gameplay _WarnSafeParkingEnabled.Checked += (sender2, e2) => PlayerPreferences.Instance.WarnSafeParkingEnabled = true; _WarnSafeParkingEnabled.Unchecked += (sender2, e2) => PlayerPreferences.Instance.WarnSafeParkingEnabled = false; _WarnEvilEnabled.Checked += (sender2, e2) => PlayerPreferences.Instance.WarnEvilEnabled = true; _WarnEvilEnabled.Unchecked += (sender2, e2) => PlayerPreferences.Instance.WarnEvilEnabled = false; _GameMenuEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.GameMenuEnabled = true; Apply(); }; _GameMenuEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.GameMenuEnabled = false; Apply(); }; _TargetingEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.TargetingEnabled = true; Apply(); }; _TargetingEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.TargetingEnabled = false; Apply(); }; // UI _WindowDragEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.WindowDragEnabled = true; Apply(); UpdateWindowDragBehavior(); }; _WindowDragEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.WindowDragEnabled = false; Apply(); UpdateWindowDragBehavior(); }; _TemperatureUnits.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.TemperatureUnits = (TemperatureUnitType)_TemperatureUnits.SelectedIndex; }; _UIEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.UIEnabled = true; Apply(); }; _UIEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.UIEnabled = false; Apply(); }; _DesignerHelpUIEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.DesignerHelpUIEnabled = true; Apply(); }; _DesignerHelpUIEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.DesignerHelpUIEnabled = false; Apply(); }; _GameHelpUIEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.GameHelpUIEnabled = true; Apply(); }; _GameHelpUIEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.GameHelpUIEnabled = false; Apply(); }; // events: input _MouseConfined.Checked += (sender2, e2) => { PlayerPreferences.Instance.MouseConfined = true; }; _MouseConfined.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.MouseConfined = false; }; _GamepadEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.GamepadEnabled = true; }; _GamepadEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.GamepadEnabled = false; }; _CharacterInvertUpEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.CharacterInvertUpEnabled = true; }; _CharacterInvertUpEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.CharacterInvertUpEnabled = false; }; _ShipInvertUpEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.ShipInvertUpEnabled = true; }; _ShipInvertUpEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.ShipInvertUpEnabled = false; }; _CharacterControl.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.CharacterControl = (CharacterControlType)_CharacterControl.SelectedIndex; }; _InteriorCamera.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.DefaultInteriorCamera = (DefaultInteriorCameraType)_InteriorCamera.SelectedIndex; }; _CharacterLookSensitivity.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.CharacterLookSensitivity = e2.NewValue; }; // events: sound // master _MasterVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.MasterVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _MasterVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.MasterVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _MasterVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.MasterVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; // music _MusicVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.MusicVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _MusicVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.MusicVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _MusicVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.MusicVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; // effects _EffectsVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.EffectsVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _EffectsVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.EffectsVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _EffectsVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.EffectsVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; // ambient _AmbientVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.AmbientVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _AmbientVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.AmbientVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _AmbientVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.AmbientVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; // voice _VoiceVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.VoiceVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _VoiceVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.VoiceVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _VoiceVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.VoiceVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; // ui _UIVolumeEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.UIVolumeEnabled = true; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _UIVolumeEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.UIVolumeEnabled = false; Apply(updateUI: false, updateAudio: true, updateDisplay: false); UpdateButtonVisibility(); }; _UIVolumeSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.UIVolume = e2.NewValue / 100.0f; Apply(updateUI: false, updateAudio: true, updateDisplay: false); }; void OnResolutionChanged() { if (!_ApplyEnabled) return; if (_DisplayResolution.SelectedIndex == -1) return; Resolution selectedResolution = _SupportedResolutions[_DisplayResolution.SelectedIndex]; if (PlayerPreferences.Instance.FullScreenMode == FullScreenMode.Windowed) { // use system (window) resolution and system refresh rate PlayerPreferences.Instance.DisplayResolution = new Vector2Int(Screen.width, Screen.height); // causes maximized screen to reset to screen width and height? //PlayerPreferences.Instance.DisplayResolution = new Vector2Int(selectedResolution.width, selectedResolution.height); PlayerPreferences.Instance.DisplayRefreshRate = (float)Screen.currentResolution.refreshRateRatio.value; // ignore selected refreshrate } else if (PlayerPreferences.Instance.FullScreenMode == FullScreenMode.FullScreenWindow) { // use selected resolution and system refresh rate PlayerPreferences.Instance.DisplayResolution = new Vector2Int(selectedResolution.width, selectedResolution.height); PlayerPreferences.Instance.DisplayRefreshRate = (float)Screen.currentResolution.refreshRateRatio.value; // ignore selected refreshrate } else if (PlayerPreferences.Instance.FullScreenMode == FullScreenMode.ExclusiveFullScreen) { // use selected resolution and selected refresh rate PlayerPreferences.Instance.DisplayResolution = new Vector2Int(selectedResolution.width, selectedResolution.height); PlayerPreferences.Instance.DisplayRefreshRate = (float)Math.Round(selectedResolution.refreshRateRatio.value, 2); } Apply(updateDisplay: true); } void OnFullScreenModeChanged() { PlayerPreferences.Instance.FullScreenMode = (FullScreenMode)_WindowMode.SelectedIndex; UpdateScreeenResolutions(true); if (_ApplyEnabled) { UpdateButtonVisibility(); if (PlayerPreferences.Instance.FullScreenMode == FullScreenMode.FullScreenWindow || PlayerPreferences.Instance.FullScreenMode == FullScreenMode.ExclusiveFullScreen) { _DisplayResolution.SelectedIndex = 0; OnResolutionChanged(); // will invoke Apply() } else Apply(updateDisplay: true); } } void OnDisplayChanged() { PlayerPreferences.Instance.SelectedDisplayIndex = _Displays.SelectedIndex; if (_ApplyEnabled) { Apply(updateDisplay: true, completed: () => { UpdateScreeenResolutions(resetSelection: true); // updates display and resets Resolutions combobox Apply(updateDisplay: true); // applies resolution ^1 }); } } _Displays.SelectionChanged += (sender, e) => OnDisplayChanged(); _WindowMode.SelectionChanged += (sender, e) => OnFullScreenModeChanged(); _DisplayResolution.SelectionChanged += (sender2, e2) => OnResolutionChanged(); _ResolutionUpscaler.SelectionChanged += (sender2, e2) => { if (_ResolutionUpscaler.SelectedIndex == 0) PlayerPreferences.Instance.ResolutionUpscaler = ResolutionUpscalerType.TAA; else if (_ResolutionUpscaler.SelectedIndex == 1) PlayerPreferences.Instance.ResolutionUpscaler = ResolutionUpscalerType.DLSS; else if (_ResolutionUpscaler.SelectedIndex == 2) PlayerPreferences.Instance.ResolutionUpscaler = ResolutionUpscalerType.FSR; else if (_ResolutionUpscaler.SelectedIndex == 3) PlayerPreferences.Instance.ResolutionUpscaler = ResolutionUpscalerType.XeSS; else throw new ArgumentOutOfRangeException(); Apply(updateDisplay: true); }; _ResolutionUpscalerQuality.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.ResolutionUpscalerQuality = (ResolutionUpscalerQualityType)_ResolutionUpscalerQuality.SelectedIndex + 2; Apply(updateDisplay: true); }; _VSync.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.VSync = (VSyncType)_VSync.SelectedIndex; if (PlayerPreferences.Instance.VSync == VSyncType.On) _FrameRateLimit.Visibility = Visibility.Collapsed; else _FrameRateLimit.Visibility = Visibility.Visible; Apply(); }; if (PlayerPreferences.Instance.VSync == VSyncType.On) _FrameRateLimit.Visibility = Visibility.Collapsed; else _FrameRateLimit.Visibility = Visibility.Visible; _FrameRateLimit.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.FrameRateLimit = (FrameRateLimitType)_FrameRateLimit.SelectedIndex; Apply(); }; // motion blur _MotionBlur.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.MotionBlur = (MotionBlurType)_MotionBlur.SelectedIndex; Apply(); }; // show FPS _ShowFPS.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.ShowFPS = _ShowFPS.SelectedIndex == 1; Apply(); }; // quality Action updateAction = null; updateAction = new Action((value) => { PlayerPreferences.Instance.Quality = (QualityType)value; if (_DisplayInitialized) ApplyQualitySetting(PlayerPreferences.Instance.Quality); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.Quality, _QualityLow, _QualityMedium, _QualityHigh, _QualityEpic, _QualityAuto); // view distance updateAction = new Action((value) => { PlayerPreferences.Instance.ViewDistance = (ViewDistanceType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.ViewDistance, _ViewNear, _ViewMedium, _ViewFar, _ViewEpic); // shadows updateAction = new Action((value) => { PlayerPreferences.Instance.Shadows = (ShadowsQualityType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.Shadows, _ShadowsLow, _ShadowsMedium, _ShadowsHigh, _ShadowsEpic); // shadow distance updateAction = new Action((value) => { PlayerPreferences.Instance.ShadowDistance = (ShadowDistanceType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.ShadowDistance, _ShadowDistanceNear, _ShadowDistanceMedium, _ShadowDistanceFar, _ShadowDistanceEpic); // textures updateAction = new Action((value) => { PlayerPreferences.Instance.Textures = (TexturesType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.Textures, _TexturesLow, _TexturesMedium, _TexturesHigh, _TexturesEpic); // reflections updateAction = new Action((value) => { PlayerPreferences.Instance.Reflections = (ReflectionsType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.Reflections, _ReflectionsOff, _ReflectionsMedium, _ReflectionsHigh, _ReflectionsEpic); // post processing updateAction = new Action((value) => { PlayerPreferences.Instance.PostProcessing = (PostProcessingType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.PostProcessing, _PostProcessingLow, _PostProcessingMedium, _PostProcessingHigh, _PostProcessingEpic); // detail updateAction = new Action((value) => { PlayerPreferences.Instance.Detail = (DetailType)value; Apply(); }); WireEvents(updateAction, (int)PlayerPreferences.Instance.Detail, _DetailLow, _DetailMedium, _DetailHigh, _DetailEpic); // field of view _CharacterFieldOfView.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.CharacterFieldOfView = (int)e2.NewValue; Apply(); }; _CockpitFieldOfView.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.CockpitFieldOfView = (int)e2.NewValue; Apply(); }; _ExternalFieldOfView.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.ExternalFieldOfView = (int)e2.NewValue; Apply(); }; _ResetFieldOfViewButton.Click += (sender2, e2) => { _CockpitFieldOfView.Value = 60; _CharacterFieldOfView.Value = 60; _ExternalFieldOfView.Value = 40; }; _BrightnessSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.Brightness = (int)e2.NewValue; Apply(); }; _ContrastSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.Contrast = (int)e2.NewValue; Apply(); }; _ResetColorCorrectionButton.Click += (sender2, e2) => { _BrightnessSlider.Value = 0; _ContrastSlider.Value = 0; }; // ui // UI size updateAction = new Action((value) => { PlayerPreferences.Instance.UserInterfaceSize = AspectRatioUtility.DefaultAspectRatioIndex - 2 + value; Apply(); }); WireEvents(updateAction, PlayerPreferences.Instance.UserInterfaceSize, _UISmallest, _UISmaller, _UINormal, _UILarger, _UILargest); _BlurEffectsEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.BlurEffectsEnabled = _BlurEffectsEnabled.IsChecked.Value; Apply(); }; _BlurEffectsEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.BlurEffectsEnabled = _BlurEffectsEnabled.IsChecked.Value; Apply(); }; _TopBlurSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.TopBlurRadius = (int)e2.NewValue; Apply(); }; _BottomBlurSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.BottomBlurRadius = (int)e2.NewValue; Apply(); }; // generative AI _GenerativeTextDialogue.Checked += (sender2, e2) => { PlayerPreferences.Instance.GenerativeTextDialogue = true; }; _GenerativeTextDialogue.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.GenerativeTextDialogue = false; }; _GenerativeAudioDialogue.Checked += (sender2, e2) => { PlayerPreferences.Instance.GenerativeAudioDialogue = true; }; _GenerativeAudioDialogue.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.GenerativeAudioDialogue = false; }; // corsair _RGBLightingEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.RGBLightingEnabled = true; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); UpdateButtonVisibility(); }; _RGBLightingEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.RGBLightingEnabled = false; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); UpdateButtonVisibility(); }; _TutorialKeysEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.TutorialKeysEnabled = true; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); }; _TutorialKeysEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.TutorialKeysEnabled = false; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); }; _InputKeysEnabled.Checked += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.InputKeysEnabled = true; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); }; _InputKeysEnabled.Unchecked += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.InputKeysEnabled = false; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); }; _RGBHueSlider.ValueChanged += (sender2, e2) => { float value = e2.NewValue / 180.0f; if (value < 0) value = 1 - value; PlayerPreferences.Instance.RGBConfiguration.Hue = value; RGBBehavior.Instance.SetDirty(true, true); }; _RGBSaturationSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.Saturation = e2.NewValue / 100.0f; RGBBehavior.Instance.SetDirty(true, true); }; _RGBBrightnessSlider.ValueChanged += (sender2, e2) => { PlayerPreferences.Instance.RGBConfiguration.Brightness = e2.NewValue / 100.0f; RGBBehavior.Instance.SetDirty(true, true); }; _ResetCorsairColorCorrectionButton.Click += (sender2, e2) => { _RGBHueSlider.Value = 0; _RGBSaturationSlider.Value = 0; _RGBBrightnessSlider.Value = 0; }; if (PlayerPreferences.Instance.RGBLightingEnabled && RGBBehavior.Instance.IsAvailable) CreateRGBLightingUI(); _DisplayInitialized = true; // global UpdateButtonVisibility(); // network _Environment.SelectionChanged += (sender2, e2) => { PlayerPreferences.Instance.ConquestEnvironment = (EnvironmentType)_Environment.SelectedIndex; }; _ClientToServerRateTextBlock.Text = $"Client ({(int)(1000 / Mathf.Lerp(Constants.Network.SpatialUpdateDelayMaxMS, Constants.Network.SpatialUpdateDelayMinMS, PlayerPreferences.Instance.ClientToServerNetworkUpdateRate))} Hz)"; _ServerToClientRateTextBlock.Text = $"Server ({(int)(1000 / Mathf.Lerp(Constants.Network.SpatialUpdateDelayMaxMS, Constants.Network.SpatialUpdateDelayMinMS, PlayerPreferences.Instance.ServerToClientNetworkUpdateRate))} Hz)"; _ClientToServerSlider.ValueChanged += (sender2, e2) => { _ClientToServerRateTextBlock.Text = $"Client ({(int)(1000 / Mathf.Lerp(Constants.Network.SpatialUpdateDelayMaxMS, Constants.Network.SpatialUpdateDelayMinMS, e2.NewValue))} Hz)"; }; _ServerToClientSlider.ValueChanged += (sender2, e2) => { _ServerToClientRateTextBlock.Text = $"Server ({(int)(1000 / Mathf.Lerp(Constants.Network.SpatialUpdateDelayMaxMS, Constants.Network.SpatialUpdateDelayMinMS, e2.NewValue))} Hz)"; }; // about _HyperlinkButton.Click += (sender2, e2) => ShowSoftwareLicenseAttribution(); _ApplyEnabled = true; } private void UpdateScreeenResolutions(bool resetSelection) { bool applyEnabled = _ApplyEnabled; _ApplyEnabled = false; void AddResolution(List resolutions, float scalar) { Resolution resolution = new Resolution() { width = Mathf.RoundToInt(resolutions[0].width * scalar), height = Mathf.RoundToInt(resolutions[0].height * scalar), refreshRateRatio = resolutions[0].refreshRateRatio }; if (!resolutions.Where(a => a.width == resolution.width && a.height == resolution.height).Any()) resolutions.Add(resolution); } List resolutions = Screen.resolutions .Where(a => a.width >= 1024 && a.height >= 1024 && a.refreshRateRatio.value >= 50) .OrderByDescending(a => a.width) .ThenByDescending(a => a.height) .ThenByDescending(a => a.refreshRateRatio.value).ToList(); if (PlayerPreferences.Instance.FullScreenMode == FullScreenMode.FullScreenWindow) { AddResolution(resolutions, 0.90f); AddResolution(resolutions, 0.80f); AddResolution(resolutions, 0.70f); AddResolution(resolutions, 0.60f); AddResolution(resolutions, 0.50f); } _SupportedResolutions = resolutions .OrderByDescending(a => a.width) .ThenByDescending(a => a.height) .ThenByDescending(a => a.refreshRateRatio.value) .ToList(); Resolution highestScreenResolution = _SupportedResolutions[0]; var nativeAspectRatio = UIUtility.GetAspectRatio(highestScreenResolution.width, highestScreenResolution.height); _DisplayResolution.Items.Clear(); foreach (Resolution resolution in _SupportedResolutions) { var selectedAspectRatio = UIUtility.GetAspectRatio(resolution.width, resolution.height); ComboBoxItem i = new ComboBoxItem(); if (selectedAspectRatio == nativeAspectRatio) { i.Content = $"{resolution.width,4} x {resolution.height,-4} @ {Math.Round(resolution.refreshRateRatio.value, 2)}Hz 📐 "; i.FontFamily = FindResource("HeadingFontFamily") as FontFamily; } else i.Content = $"{resolution.width,4} x {resolution.height,-4} @ {Math.Round(resolution.refreshRateRatio.value, 2)}Hz"; i.Tag = resolution; _DisplayResolution.Items.Add(i); } if (resetSelection) _DisplayResolution.SelectedIndex = 0; else { int selectedResolutionIndex = -1; for (int i = 0; i < _SupportedResolutions.Count; i++) if (_SupportedResolutions[i].width == PlayerPreferences.Instance.DisplayResolution.x && _SupportedResolutions[i].height == PlayerPreferences.Instance.DisplayResolution.y && (PlayerPreferences.Instance.FullScreenMode != FullScreenMode.ExclusiveFullScreen || (Math.Round(_SupportedResolutions[i].refreshRateRatio.value, 2) == Math.Round(PlayerPreferences.Instance.DisplayRefreshRate, 2)))) { selectedResolutionIndex = i; break; } int currentScreenResolutionIndex = -1; for (int i = 0; i < _SupportedResolutions.Count; i++) { if (_SupportedResolutions[i].width == Screen.currentResolution.width && _SupportedResolutions[i].height == Screen.currentResolution.height && (PlayerPreferences.Instance.FullScreenMode != FullScreenMode.ExclusiveFullScreen || (_SupportedResolutions[i].refreshRateRatio.numerator == Screen.currentResolution.refreshRateRatio.numerator && _SupportedResolutions[i].refreshRateRatio.denominator == Screen.currentResolution.refreshRateRatio.denominator))) { currentScreenResolutionIndex = i; break; } } if (selectedResolutionIndex != -1) _DisplayResolution.SelectedIndex = selectedResolutionIndex; else if (currentScreenResolutionIndex != -1) _DisplayResolution.SelectedIndex = currentScreenResolutionIndex; else _DisplayResolution.SelectedIndex = 0; } _ApplyEnabled = applyEnabled; } private void ApplyQualitySetting(QualityType value) { _ApplyEnabled = false; switch (value) { case QualityType.Low: _ViewNear.IsChecked = true; _ShadowsMedium.IsChecked = true; _ShadowDistanceMedium.IsChecked = true; _TexturesLow.IsChecked = true; _ReflectionsMedium.IsChecked = true; _PostProcessingLow.IsChecked = true; _DetailLow.IsChecked = true; break; case QualityType.Medium: _ViewMedium.IsChecked = true; _ShadowsMedium.IsChecked = true; _ShadowDistanceMedium.IsChecked = true; _TexturesMedium.IsChecked = true; _ReflectionsMedium.IsChecked = true; _PostProcessingMedium.IsChecked = true; _DetailMedium.IsChecked = true; break; case QualityType.High: _ViewFar.IsChecked = true; _ShadowsHigh.IsChecked = true; _ShadowDistanceFar.IsChecked = true; _TexturesHigh.IsChecked = true; _ReflectionsMedium.IsChecked = true; _PostProcessingHigh.IsChecked = true; _DetailHigh.IsChecked = true; break; case QualityType.Epic: _ViewEpic.IsChecked = true; _ShadowsEpic.IsChecked = true; _ShadowDistanceEpic.IsChecked = true; _TexturesHigh.IsChecked = true; _ReflectionsHigh.IsChecked = true; _PostProcessingEpic.IsChecked = true; _DetailEpic.IsChecked = true; break; case QualityType.Auto: PlayerPreferences.Instance.VSync = 0; UnityDispatcher.Instance.Invoke(TimeSpan.FromMilliseconds(250), () => { float fps = GameState.Instance.FrameRateCounter.FPS; PlayerPreferences.Instance.VSync = (VSyncType)_VSync.SelectedIndex; if (fps > 125) ApplyQualitySetting(QualityType.Epic); else if (fps > 100) ApplyQualitySetting(QualityType.High); else if (fps > 75) ApplyQualitySetting(QualityType.Medium); else ApplyQualitySetting(QualityType.Low); }); return; default: break; } _ApplyEnabled = true; Apply(); } public override void Show() { base.Show(); if (Application.isEditor || RuntimeSettings.Instance.IsDeveloperMode || PlayerPreferences.Instance.ConquestEnvironment == EnvironmentType.LocalDevelopment) _NetworkTab.Visibility = Visibility.Visible; else _NetworkTab.Visibility = Visibility.Collapsed; #if (UNITY_GAMECORE) _CorsairTab.Visibility = Visibility.Collapsed; _DevicesStackPanel.Visibility = Visibility.Collapsed; _ResolutionStackPanel.Visibility = Visibility.Collapsed; _QualityStackPanel.Visibility = Visibility.Collapsed; _FieldOfViewStackPanel.Visibility = Visibility.Collapsed; _WindowDragEnabled.Parent.Visibility = Visibility.Collapsed; _UIEnabled.Parent.Visibility = Visibility.Collapsed; _GameMenuEnabled.Parent.Visibility = Visibility.Collapsed; _GenerativeAIStackPanel.Visibility = Visibility.Collapsed; #endif InputHelpManager.Instance.UpdateRGBKeysForUI(); } public override void Hide() { base.Hide(); // update preferences that should change only once, upon save PlayerPreferences.Instance.ClientToServerNetworkUpdateRate = _ClientToServerSlider.Value; PlayerPreferences.Instance.ServerToClientNetworkUpdateRate = _ServerToClientSlider.Value; // save preferences PlayerPreferences.Instance.SaveRGB(); PlayerPreferences.Instance.SavePreferences(); } public void Apply(bool updateUI = true, bool updateAudio = true, bool updateDisplay = true, bool updateRGB = true, bool updateWorld = true, Action completed = null) { if (_ApplyEnabled) { if (updateRGB) { // RGB state if (_RGBLightingEnabled.IsChecked.Value) { // create device UI if it does not exist, and Corsair RGB is ready if (_CorsairStackPanel.Children.Count == 0) UnityDispatcher.Instance.Invoke(async () => { int tries = 0; while (tries++ < 4) { if (RGBBehavior.Instance.IsAvailable) { CreateRGBLightingUI(); break; } else await Task.Delay(50); } if (RGBBehavior.Instance.IsAvailable) { _RGBStackPanel.Visibility = Visibility.Visible; _CorsairNotFoundTextBlock.Visibility = Visibility.Collapsed; } else { _RGBStackPanel.Visibility = Visibility.Collapsed; _CorsairNotFoundTextBlock.Visibility = Visibility.Visible; } }); } else { _RGBStackPanel.Visibility = Visibility.Collapsed; _CorsairNotFoundTextBlock.Visibility = Visibility.Collapsed; _CorsairStackPanel.Children.Clear(); } } PlayerPreferences.Instance.Apply(updateUI, updateAudio, updateDisplay, updateRGB, updateWorld, completed); if (RGBBehavior.Instance.IsAvailable && updateRGB) RGBBehavior.Instance.LoadDevices(); } } private void UpdateButtonVisibility() { if (_MasterVolumeEnabled.IsChecked.Value) { _MasterVolumeSlider.IsEnabled = true; _MasterVolumeSlider.Opacity = 1.0f; } else { _MasterVolumeSlider.IsEnabled = false; _MasterVolumeSlider.Opacity = 0.5f; } if (_MusicVolumeEnabled.IsChecked.Value) { _MusicVolumeSlider.IsEnabled = true; _MusicVolumeSlider.Opacity = 1.0f; } else { _MusicVolumeSlider.IsEnabled = false; _MusicVolumeSlider.Opacity = 0.5f; } if (_EffectsVolumeEnabled.IsChecked.Value) { _EffectsVolumeSlider.IsEnabled = true; _EffectsVolumeSlider.Opacity = 1.0f; } else { _EffectsVolumeSlider.IsEnabled = false; _EffectsVolumeSlider.Opacity = 0.5f; } if (_AmbientVolumeEnabled.IsChecked.Value) { _AmbientVolumeSlider.IsEnabled = true; _AmbientVolumeSlider.Opacity = 1.0f; } else { _AmbientVolumeSlider.IsEnabled = false; _AmbientVolumeSlider.Opacity = 0.5f; } if (!_RGBLightingEnabled.IsChecked.Value) { _RGBStackPanel.Visibility = Visibility.Collapsed; _CorsairNotFoundTextBlock.Visibility = Visibility.Collapsed; } if (_WindowMode.SelectedIndex == (int)FullScreenMode.ExclusiveFullScreen || _WindowMode.SelectedIndex == (int)FullScreenMode.FullScreenWindow) _DisplayResolutionStackPanel.Visibility = Visibility.Visible; else _DisplayResolutionStackPanel.Visibility = Visibility.Hidden; } private void CreateRGBLightingUI() { if (RGBBehavior.Instance.IsAvailable) foreach (RGBDeviceMetadata metadata in RGBBehavior.Instance.Devices) { string deviceName = RGBConfiguration.SantitizeDeviceName(metadata.Device.DeviceInfo.DeviceName); StackPanel stackPanel = new StackPanel(); stackPanel.Orientation = Orientation.Horizontal; stackPanel.Margin = new Thickness(0, 0, 0, 12); _CorsairStackPanel.Children.Add(stackPanel); TextBlock textBlock = new TextBlock(); textBlock.Style = (Style)_Root.FindResource("Heading4Primary"); textBlock.HorizontalAlignment = HorizontalAlignment.Right; textBlock.VerticalAlignment = VerticalAlignment.Center; textBlock.Width = 250; textBlock.Margin = new Thickness(0, 0, 5, 0); textBlock.Text = deviceName; ToolTipService.SetToolTip(textBlock, textBlock.Text); stackPanel.Children.Add(textBlock); ComboBox comboBox = new ComboBox(); comboBox.Width = 315; stackPanel.Children.Add(comboBox); Array values = Enum.GetValues(typeof(LightingAssignmentType)); for (int i = 0; i < values.Length; i++) { LightingAssignmentType lightingAssignmentType = (LightingAssignmentType)i; ComboBoxItem comboBoxItem = new ComboBoxItem(); comboBoxItem.Tag = lightingAssignmentType; comboBoxItem.Content = lightingAssignmentType.ToString().Replace("_", " "); comboBox.Items.Add(comboBoxItem); } comboBox.SelectedIndex = (int)metadata.Binding.Assignment; comboBox.SelectionChanged += (sender, e) => { ComboBoxItem selectedItem = (ComboBoxItem)e.AddedItems[0]; LightingAssignmentType assignment = (LightingAssignmentType)selectedItem.Tag; metadata.Binding.Assignment = assignment; Apply(updateUI: false, updateAudio: false, updateDisplay: false, updateRGB: true); }; } } private void ShowSoftwareLicenseAttribution() { Hide(); LicenseAttributionControl control = new LicenseAttributionControl(); control.Hidden += (sender, e) => Show(); control.Show(); } public override void UpdateInput() { if (OpenFrame != Time.frameCount) { if (Input.GetKeyDown(KeyCode.Escape) || Input.GetButtonDown(InputNames.GamePad.B) || Input.GetButtonDown(InputNames.GamePad.Start) || Input.GetKeyDown(KeyCode.F1)) { Hide(); } } } } }