using System.Collections; using System.Collections.Generic; using System.ComponentModel; using Godot; using Godot.Bridge; using Godot.Collections; using Godot.NativeInterop; using Newtonsoft.Json; [ScriptPath("res://Scripts/UI/Settings.cs")] public partial class Settings : RichTextLabel { public enum SettingIndex { MusicVol, SFXVol, AlwaysRun, AutoFire, Fullscreen, Inputs, Return, Exit } private Coroutine doingInputs; public static SettingsFile file = new SettingsFile(); [Export(PropertyHint.None, "")] private Sprite2D soul; private int option; private bool wait; private const int max = 7; private const string path = "user://Settings.dat"; private Key? lastKey; private int currentKey; public override void _EnterTree() { base.Text = Texts.common[59].Replace("@", "\t") + file.musVol + "%\n" + Texts.common[60].Replace("@", "\t") + file.sfxVol + "%\n" + Texts.common[61].Replace("@", "\t") + (file.run ? "ON" : "OFF") + "\n" + Texts.common[62].Replace("@", "\t") + (file.autoFire ? "ON" : "OFF") + "\n" + Texts.common[63].Replace("@", "\t") + (file.fullScreen ? "ON" : "OFF") + "\n" + Texts.common[64] + "\n" + Texts.common[65] + "\n"; if (MainMenu.instance == null) { base.Text += Texts.common[66]; } else { base.Text += Texts.common[67]; } } public override void _Process(double delta) { Coroutine coroutine = doingInputs; if (coroutine != null && coroutine.done) { doingInputs = null; } if (doingInputs != null) { return; } if (!wait) { wait = true; return; } soul.Position = new Vector2(-8f, 8 + option * 15); if (Input.IsActionJustPressed(Main.keys[0])) { if (option > 0) { option--; } Audio.PlaySound(Audio.commonSounds[0]); } else if (Input.IsActionJustPressed(Main.keys[1])) { if (option < 7) { option++; } Audio.PlaySound(Audio.commonSounds[0]); } else if (Input.IsActionJustPressed(Main.keys[2])) { ToggleSettings(-1); Audio.PlaySound(Audio.commonSounds[0]); } else if (Input.IsActionJustPressed(Main.keys[3])) { ToggleSettings(1); Audio.PlaySound(Audio.commonSounds[0]); } else if (Input.IsActionJustPressed(Main.keys[4])) { ToggleSettings(1); Audio.PlaySound(Audio.commonSounds[2]); } else if (Input.IsActionJustPressed(Main.keys[5])) { Audio.PlaySound(Audio.commonSounds[2]); SaveSettings(); QueueFree(); } } private void ToggleSettings(int i) { switch ((SettingIndex)option) { case SettingIndex.SFXVol: file.sfxVol = Mathf.Clamp(file.sfxVol + i * 10, 0, 100); UpdateVolume(); break; case SettingIndex.MusicVol: file.musVol = Mathf.Clamp(file.musVol + i * 10, 0, 100); UpdateVolume(); break; case SettingIndex.AutoFire: file.autoFire = !file.autoFire; break; case SettingIndex.Exit: SaveSettings(); if (MainMenu.instance == null) { CameraController.instance.GlobalPosition = Vector2.Zero; GetTree().ReloadCurrentScene(); } else { GetTree().Quit(); } break; case SettingIndex.Inputs: doingInputs = Coroutine.Start(InputRebind()); break; case SettingIndex.Return: SaveSettings(); QueueFree(); break; case SettingIndex.AlwaysRun: file.run = !file.run; break; case SettingIndex.Fullscreen: file.fullScreen = !file.fullScreen; break; } _EnterTree(); } public static void SaveSettings() { FileAccess fileAccess = FileAccess.Open("user://Settings.dat", FileAccess.ModeFlags.Write); fileAccess.StoreString(JsonConvert.SerializeObject(file)); fileAccess.Close(); ApplySettings(); } public override void _Input(InputEvent @event) { if (doingInputs != null && !lastKey.HasValue && @event is InputEventKey inputEventKey) { if (SettingsFile.allowed.Contains(inputEventKey.Keycode)) { lastKey = inputEventKey.Keycode; } else { Audio.PlaySound(Audio.commonSounds[1]); } } } private IEnumerator InputRebind() { int[] k = new int[8] { 68, 69, 70, 71, 72, 73, 74, 90 }; soul.Visible = false; base.Text = ""; while (Input.IsAnythingPressed()) { yield return null; } yield return null; lastKey = null; for (int currentKey = 0; currentKey < k.Length; currentKey++) { Array array = InputMap.ActionGetEvents(Main.keys[currentKey]); base.Text = Texts.common[75].Replace("@", "\n" + Texts.common[k[currentKey]]) + "\n" + Texts.common[94].Replace("#", ((InputEventKey)array[0]).Keycode.ToString()) + "\n" + Texts.common[76] + "\n\n" + Texts.common[95].Replace("@", "\n"); while (true) { if (Input.IsActionJustPressed(Main.keys[8])) { while (Input.IsAnythingPressed()) { yield return null; } break; } if (lastKey.HasValue) { file.keys[currentKey] = lastKey.Value; while (Input.IsAnythingPressed()) { yield return null; } lastKey = null; break; } yield return null; } } soul.Visible = true; UpdateKeys(); _EnterTree(); } public static void UpdateKeys() { for (int i = 0; i < 8; i++) { ((InputEventKey)InputMap.ActionGetEvents(Main.keys[i])[0]).Keycode = file.keys[i]; } } public static void LoadSettings() { if (FileAccess.FileExists("user://Settings.dat")) { try { FileAccess fileAccess = FileAccess.Open("user://Settings.dat", FileAccess.ModeFlags.Read); file = JsonConvert.DeserializeObject(fileAccess.GetAsText()); fileAccess.Close(); } catch { GD.Print("Settings file invalid, skipping..."); } } ApplySettings(); } private static void ApplySettings() { try { UpdateVolume(); UpdateKeys(); UpdateWindow(); } catch { GD.Print("Settings file invalid, skipping..."); } } public static void UpdateWindow() { if (!Engine.IsEmbeddedInEditor()) { if (file.fullScreen) { Main.tree.Root.ContentScaleStretch = Window.ContentScaleStretchEnum.Fractional; DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen); return; } Main.tree.Root.ContentScaleStretch = Window.ContentScaleStretchEnum.Integer; DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed); DisplayServer.WindowSetSize(new Vector2I(641, 480)); Window window = Main.instance.GetWindow(); Rect2I rect2I = DisplayServer.ScreenGetUsableRect(window.CurrentScreen); Vector2I sizeWithDecorations = window.GetSizeWithDecorations(); window.Position = rect2I.Position + (rect2I.Size / 2 - sizeWithDecorations / 2); DisplayServer.WindowSetSize(new Vector2I(640, 480)); } } private static void UpdateVolume() { AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Music"), Mathf.LinearToDb((float)file.musVol / 100f)); AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Sound"), Mathf.LinearToDb((float)file.sfxVol / 100f)); } }