2025-05-13 19:22:01 +08:00

291 lines
6.7 KiB
C#

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<InputEvent> 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<SettingsFile>(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));
}
}