using Godot; using System; using Newtonsoft.Json; public partial class Settings : TabContainer { Control _GameSettings; Control _DisplaySettings; Control _AudioSettings; Control _InputSettings; Options _Options; Reference _Reference; public override void _Ready() { _Reference = GetNode("/root/Reference"); _Options = GetNode( "/root/Options" ); _Reference.SettingsFrame = this; // Get Locations For Settings _GameSettings = GetChild( ( int )Tabs.Game ).GetChild( 0 ).GetChild( 0 ); _DisplaySettings = GetChild( ( int )Tabs.Display ).GetChild( 0 ).GetChild( 0 ); _AudioSettings = GetChild( ( int )Tabs.Audio ).GetChild( 0 ).GetChild( 0 ); _InputSettings = GetChild( ( int )Tabs.Input ).GetChild( 0 ).GetChild( 0 ); if( !_Options.isServer ) { // Load Settings _Options._SettingsFile = new SettingsFile( "Settings.json" ); SetSettings(); // Game Settings // Display Settings Action wm = ( DisplayServer.WindowMode mode ) => { _Options._SettingsFile.Display.WindowMode = mode; }; BuildSetting( "Window Mode", _DisplaySettings, _Options._SettingsFile.Display.WindowMode, wm ); Action rs = ( float mode ) => { _Options._SettingsFile.Display.ScreenScalingFactor = mode; }; BuildSetting( "Resolution Scale", _DisplaySettings, _Options._SettingsFile.Display.ScreenScalingFactor, rs ); Action mf = ( int mode ) => { _Options._SettingsFile.Display.MaxFPS = mode; }; BuildSetting( "Max FPS", _DisplaySettings, _Options._SettingsFile.Display.MaxFPS, mf ); Action vs = ( DisplayServer.VSyncMode mode ) => { _Options._SettingsFile.Display.VSync = mode; }; BuildSetting( "VSync", _DisplaySettings, _Options._SettingsFile.Display.VSync, vs ); Action ss = ( Viewport.Scaling3DModeEnum mode ) => { _Options._SettingsFile.Display.ScreenScaling = mode; }; BuildSetting( "Screen Scaling", _DisplaySettings, _Options._SettingsFile.Display.ScreenScaling, ss ); Action fs = (float mode) => { _Options._SettingsFile.Display.FSRSharpness = mode; }; BuildSetting( "FSR Sharpness", _DisplaySettings, _Options._SettingsFile.Display.FSRSharpness, fs ); Action msaa = ( Viewport.Msaa mode ) => { _Options._SettingsFile.Display.Msaa = mode; }; BuildSetting( "MSAA", _DisplaySettings, _Options._SettingsFile.Display.Msaa, msaa ); Action ssaa = ( Viewport.ScreenSpaceAAEnum mode ) => { _Options._SettingsFile.Display.ScreenSpaceAA = mode; }; BuildSetting( "SSAA", _DisplaySettings, _Options._SettingsFile.Display.ScreenSpaceAA, ssaa ); Action taa = ( bool mode ) => { _Options._SettingsFile.Display.TAA = mode; }; BuildSetting( "TAA", _DisplaySettings, _Options._SettingsFile.Display.TAA, taa ); Action SSR = ( bool mode ) => { _Options._SettingsFile.Display.ScreenSpaceReflections = mode; }; BuildSetting( "Screen Space Reflections", _DisplaySettings, _Options._SettingsFile.Display.ScreenSpaceReflections, SSR ); Action SSIL = ( bool mode ) => { _Options._SettingsFile.Display.ScreenSpaceIndirectLighting = mode; }; BuildSetting( "Indirect Lighting", _DisplaySettings, _Options._SettingsFile.Display.ScreenSpaceIndirectLighting, SSIL ); Action SSAO = ( bool mode ) => { _Options._SettingsFile.Display.ScreenSpaceAmbiantOcclusion = mode; }; BuildSetting( "Ambiant Occlusion", _DisplaySettings, _Options._SettingsFile.Display.ScreenSpaceAmbiantOcclusion, SSAO ); Action GI = ( bool mode ) => { _Options._SettingsFile.Display.GlobalIllumination = mode; }; BuildSetting( "Global Ilumination", _DisplaySettings, _Options._SettingsFile.Display.GlobalIllumination, GI ); // Audio Settings // Input Settings } } bool settingsVisible = true; public void ToggleSettingsVisibility() { if( _Options.isAlive ) { } else { GetNode( "/root/GameRoot/UI/SettingsFrame" ).Visible = settingsVisible; GetNode( "/root/GameRoot/UI/MainMenu/ButtonList" ).Visible = !settingsVisible; GetNode( "/root/GameRoot/UI/MainMenu/SelectedAbility" ).Visible = !settingsVisible; settingsVisible = !settingsVisible; } } public void OnSaveButtonDown() { SetSettings(); _Options._SettingsFile.Save(); _Reference.Alert.PerformAlert( "Settings Saved" ); if ( !settingsVisible ) { ToggleSettingsVisibility(); } } public void OnCancelButtonDown() { if ( !settingsVisible ) { ToggleSettingsVisibility(); } } void BuildSetting( string SettingName, Control Parent, T DefaultSetting, Action SettingEvent ) { Control SettingFrameControl = new Control{ CustomMinimumSize = new Vector2(0, 50) }; Panel Background = new Panel{ LayoutMode = 1 }; Background.SetAnchorsPreset( LayoutPreset.TopWide ); Background.SetSize( new Vector2( 780, 50 ) ); Background.Position = new Vector2( 10, 10 ); SettingFrameControl.AddChild( Background ); HBoxContainer container = new HBoxContainer{ LayoutMode = 1 }; container.SetAnchorsPreset( LayoutPreset.FullRect ); Background.AddChild( container ); Label SettingTitle = new Label{ Text = SettingName, VerticalAlignment = VerticalAlignment.Center, Uppercase = true, CustomMinimumSize = new Vector2(390, 0) }; container.AddChild( SettingTitle ); if( typeof( T ) == typeof( float ) ) { // Slider 0 - 2 HSlider slider = new HSlider{ CustomMinimumSize = new Vector2(390, 50), MinValue = 0, MaxValue = 20, TickCount = 21, Rounded = true, Value = Convert.ToSingle(DefaultSetting) * 10 }; slider.DragEnded += (bool changed) => { SettingEvent((T)(object)( Convert.ToSingle( slider.Value ) / 10 )); }; container.AddChild( slider ); } else if( typeof( T ) == typeof( int ) ) { // Number Input LineEdit numberEdit = new LineEdit{ CustomMinimumSize = new Vector2(390, 50), Text = DefaultSetting.ToString() }; numberEdit.TextChanged += ( string newText ) => { if ( int.TryParse( newText, out int value ) ) { SettingEvent((T)(object)( value )); } else { numberEdit.Text = DefaultSetting.ToString(); } }; container.AddChild( numberEdit ); } else if( typeof( T ).IsEnum ) { OptionButton menuButton = new OptionButton{ CustomMinimumSize = new Vector2(390, 0), Text = DefaultSetting.ToString() }; foreach (var settingOption in Enum.GetValues( typeof( T ) ) ) { menuButton.AddItem( settingOption.ToString() ); } menuButton.Selected = Convert.ToInt32( DefaultSetting ); menuButton.ItemSelected += ( long index ) => { SettingEvent((T)(object)index); }; container.AddChild( menuButton ); } else if ( typeof( T ) == typeof( bool ) ) { // check box CheckBox checkBox = new CheckBox{ CustomMinimumSize = new Vector2(390, 50), ToggleMode = true, ButtonPressed = Convert.ToBoolean(DefaultSetting) }; checkBox.Toggled += (bool value) => { checkBox.ButtonPressed = value; SettingEvent((T)(object)value ); }; container.AddChild( checkBox ); } Parent.AddChild( SettingFrameControl ); } void SetSettings() { // Display Settings DisplayServer.WindowSetMode( _Options._SettingsFile.Display.WindowMode ); Engine.MaxFps = _Options._SettingsFile.Display.MaxFPS; DisplayServer.WindowSetVsyncMode( _Options._SettingsFile.Display.VSync ); GetViewport().Scaling3DMode = _Options._SettingsFile.Display.ScreenScaling; GetViewport().FsrSharpness = _Options._SettingsFile.Display.FSRSharpness; GetViewport().Scaling3DScale = _Options._SettingsFile.Display.ScreenScalingFactor; GetViewport().Msaa2D = _Options._SettingsFile.Display.Msaa; GetViewport().Msaa3D = _Options._SettingsFile.Display.Msaa; GetViewport().ScreenSpaceAA = _Options._SettingsFile.Display.ScreenSpaceAA; GetViewport().UseTaa = _Options._SettingsFile.Display.TAA; } } enum Tabs { Game = 0, Display = 1, Audio = 2, Input = 3 } [Serializable] public class SettingsFile { string FilePath = string.Empty; public GameSettings Game { get; set; } public DisplaySettings Display { get; set; } public AudioSettings Audio { get; set; } public InputSettings Input { get; set; } public SettingsFile( string Path ) { FilePath = "user://" + Path; using (Godot.FileAccess file = Godot.FileAccess.Open(FilePath, Godot.FileAccess.ModeFlags.Read)) { if ( file != null ) { string content = file.GetAsText(); SettingsFile temp = JsonConvert.DeserializeObject(content); Game = temp.Game != null ? temp.Game : new GameSettings(); Display = temp.Display != null ? temp.Display : new DisplaySettings(); Audio = temp.Audio != null ? temp.Audio : new AudioSettings(); Input = temp.Input != null ? temp.Input : new InputSettings(); }else{ Game = new GameSettings(); Display = new DisplaySettings(); Audio = new AudioSettings(); Input = new InputSettings(); } } } public void Save() { using (Godot.FileAccess file = Godot.FileAccess.Open( FilePath, Godot.FileAccess.ModeFlags.Write ) ) { file.StoreString( JsonConvert.SerializeObject( this, Formatting.Indented ) ); } } } /// /// Settings File Settings /// public class GameSettings { public string UserName { get; set; } = String.Empty; public string SessionToken { get; set; } = String.Empty; } public class DisplaySettings { public DisplayServer.WindowMode WindowMode { get; set; } public float ScreenScalingFactor { get; set; } public int MaxFPS { get; set; } public DisplayServer.VSyncMode VSync { get; set; } public Viewport.Scaling3DModeEnum ScreenScaling { get; set; } public float FSRSharpness { get; set; } public Viewport.Msaa Msaa { get; set; } public Viewport.ScreenSpaceAAEnum ScreenSpaceAA { get; set; } public bool TAA { get; set; } public bool ScreenSpaceReflections { get; set; } public bool ScreenSpaceIndirectLighting { get; set; } public bool ScreenSpaceAmbiantOcclusion { get; set; } public bool GlobalIllumination { get; set; } } public class AudioSettings { } public class InputSettings { }