diff --git a/Funk Engine.csproj b/Funk Engine.csproj
index e7321286..e6707425 100644
--- a/Funk Engine.csproj
+++ b/Funk Engine.csproj
@@ -8,7 +8,6 @@
-
diff --git a/Globals/BgAudioPlayer.cs b/Globals/BgAudioPlayer.cs
index 95fae32a..35f17e75 100644
--- a/Globals/BgAudioPlayer.cs
+++ b/Globals/BgAudioPlayer.cs
@@ -7,6 +7,7 @@ public partial class BgAudioPlayer : AudioStreamPlayer
private void PlayMusic(AudioStream music, float volume)
{
+ ProcessMode = ProcessModeEnum.Always;
if (Playing && music.Equals(Stream))
{
return;
diff --git a/Globals/FunkEngineNameSpace.cs b/Globals/FunkEngineNameSpace.cs
index f5343125..99f790fa 100644
--- a/Globals/FunkEngineNameSpace.cs
+++ b/Globals/FunkEngineNameSpace.cs
@@ -167,7 +167,6 @@ private void CreateCommonChildren(int width, int height)
continue;
if (_map[curPos.X, curPos.Y + 1] == 0)
continue;
- GD.Print("Added child on same X.");
room.AddChild(_map[curPos.X, curPos.Y + 1]);
}
}
diff --git a/Globals/StageProducer.cs b/Globals/StageProducer.cs
index b2578a9b..fc990abe 100644
--- a/Globals/StageProducer.cs
+++ b/Globals/StageProducer.cs
@@ -25,6 +25,21 @@ public partial class StageProducer : Node
//TODO: Allow for permanent changes and battle temporary stat changes.
public static PlayerStats PlayerStats;
+ public override void _EnterTree()
+ {
+ InitFromCfg();
+ }
+
+ private void InitFromCfg()
+ {
+ OptionsMenu.ChangeVolume(
+ SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.Volume).As()
+ );
+ TranslationServer.SetLocale(
+ SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.LanguageKey).As()
+ );
+ }
+
public void StartGame()
{
Map.InitMapGrid(MapSize.X, MapSize.Y, 3);
@@ -63,12 +78,6 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
Config = MakeConfig(nextStage, nextRoomIdx);
GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn");
break;
- case Stages.Controls:
- GetTree().ChangeSceneToFile("res://scenes/Remapping/Remap.tscn");
- break;
- case Stages.Options:
- GetTree().ChangeSceneToFile("res://scenes/Options/OptionsMenu.tscn");
- break;
case Stages.Chest:
Config = MakeConfig(nextStage, nextRoomIdx);
GetTree().ChangeSceneToFile("res://scenes/ChestScene/ChestScene.tscn");
diff --git a/Globals/translations.cn.translation b/Globals/translations.cn.translation
index 73c6810d..40b4e958 100644
Binary files a/Globals/translations.cn.translation and b/Globals/translations.cn.translation differ
diff --git a/Globals/translations.csv b/Globals/translations.csv
index 3c950d7a..5bba08ad 100644
--- a/Globals/translations.csv
+++ b/Globals/translations.csv
@@ -11,7 +11,7 @@ CONTROLS_TITLE_SELECTED,Selected,已选择
CONTROLS_WASD_BUTTON,WASD,WASD
CONTROLS_QWER_BUTTON,QWER,QWER
CONTROLS_ARROW_BUTTON,Arrow Keys,箭头键
-CONTROLS_RETURN_BUTTON,Return to Title Screen,返回主菜单
+CONTROLS_RETURN_BUTTON,Return,返回
ESCAPE_MENU_RESUME,Resume,继续
ESCAPE_MENU_QUIT,Quit,退出
ESCAPE_MENU_TITLE,Quit to Title,返回标题
@@ -50,3 +50,5 @@ RELIC_COLORBOROS_NAME,Colorboros,彩蛇轮回
RELIC_COLORBOROS_TOOLTIP,"Taste the rainbow. Charges the freestyle bar every riff.","品尝临岛,每次现场充值自由格条"
INVENTORY_TAB_NOTES,Notes,乐谱
INVENTORY_TAB_RELICS,Relics,遗物
+OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置
+OPTIONS_CONTRAST_LABEL,High Contrast,高对比度模式
diff --git a/Globals/translations.en.translation b/Globals/translations.en.translation
index 0e9a5a5d..6eadb733 100644
Binary files a/Globals/translations.en.translation and b/Globals/translations.en.translation differ
diff --git a/SaveData/SaveData.json b/SaveData/SaveData.json
deleted file mode 100644
index 1aeaf3cc..00000000
--- a/SaveData/SaveData.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "AccountName": null,
- "Notes": {
- "PlayerBase": 2,
- "PlayerDouble": 1
- },
- "Relics": {},
- "Settings": {}
-}
\ No newline at end of file
diff --git a/SaveData/SaveSystem.cs b/SaveData/SaveSystem.cs
index 7cc7af03..fa9159fd 100644
--- a/SaveData/SaveSystem.cs
+++ b/SaveData/SaveSystem.cs
@@ -1,48 +1,127 @@
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text.Json;
using Godot;
+using FileAccess = Godot.FileAccess;
// TODO: implement saving
public static class SaveSystem
{
- private static string SavePath => "res://SaveData/SaveData.json"; // Update if needed
+ public static string UserConfigPath = "user://Options.cfg";
+ private static ConfigFile _curConfigData;
- // Loads only the notes section
- public static Dictionary LoadNotes()
+ private const float DefaultVolume = 80f;
+ private const string DefaultInput = "WASD";
+ private const string DefaultLanguage = "en";
+ private const bool DefaultHighCon = false;
+
+ public enum ConfigSettings
+ {
+ Volume,
+ InputKey,
+ LanguageKey,
+ HighContrast,
+ }
+
+ private static void InitConfig()
+ {
+ _curConfigData = new ConfigFile();
+ UpdateConfig(ConfigSettings.Volume, DefaultVolume);
+ UpdateConfig(ConfigSettings.InputKey, DefaultInput);
+ UpdateConfig(ConfigSettings.LanguageKey, DefaultLanguage);
+ UpdateConfig(ConfigSettings.HighContrast, DefaultHighCon);
+ }
+
+ private static void SaveConfig()
+ {
+ AssertConfigFile();
+ _curConfigData.Save(UserConfigPath);
+ }
+
+ public static void UpdateConfig(ConfigSettings setting, Variant value)
{
- var saveData = LoadSaveData();
- if (saveData != null && saveData.Notes != null)
+ AssertConfigFile();
+ switch (setting)
{
- return saveData.Notes;
+ case ConfigSettings.Volume:
+ _curConfigData.SetValue("Options", "Volume", value);
+ break;
+ case ConfigSettings.InputKey:
+ _curConfigData.SetValue("Options", "InputKey", value);
+ break;
+ case ConfigSettings.LanguageKey:
+ _curConfigData.SetValue("Options", "LanguageKey", value);
+ break;
+ case ConfigSettings.HighContrast:
+ _curConfigData.SetValue("Options", "HighContrast", value);
+ break;
}
- else
+ SaveConfig();
+ }
+
+ public static void AssertConfigFile()
+ {
+ if (_curConfigData == null)
{
- return new Dictionary();
+ LoadConfigData();
}
}
// This method loads the entire save data
- public static SaveData LoadSaveData()
+ private static void LoadConfigData()
{
- string path = ProjectSettings.GlobalizePath(SavePath);
- if (!File.Exists(path))
- {
- GD.PrintErr("Can't load save game");
- return null;
- }
+ _curConfigData = new ConfigFile();
+ VerifyConfig();
+ if (_curConfigData.Load(UserConfigPath) == Error.Ok)
+ return;
+ GD.Print("No config could be found, creating a new one.");
+ InitConfig();
+ SaveConfig();
+ }
- string json = File.ReadAllText(path);
- SaveData data = JsonSerializer.Deserialize(json);
- return data;
+ //Really naive approach to verifying config integrity, could I have just changed back to JSON? yes. But I'm a real programmer.
+ //In theory ConfigFiles should be more stable across any version changes.
+ private static void VerifyConfig()
+ {
+ if (!FileAccess.FileExists(UserConfigPath))
+ return;
+ string[] sus = new[]
+ {
+ "init",
+ "object",
+ "script",
+ "source",
+ "extends",
+ "RefCounted",
+ "sus",
+ };
+ FileAccess file = FileAccess.Open(UserConfigPath, FileAccess.ModeFlags.Read);
+ if (!sus.Any(s => file.GetAsText().Contains(s)))
+ return;
+ file.Close();
+ InitConfig();
}
-}
-public class SaveData
-{
- public string AccountName { get; set; }
- public Dictionary Notes { get; set; } = new Dictionary();
- public Dictionary Relics { get; set; } = new Dictionary();
- public Dictionary Settings { get; set; } = new Dictionary();
+ public static Variant GetConfigValue(ConfigSettings setting)
+ {
+ AssertConfigFile();
+ switch (setting)
+ {
+ case ConfigSettings.Volume:
+ return _curConfigData.GetValue("Options", "Volume", DefaultVolume);
+ case ConfigSettings.InputKey:
+ return _curConfigData.GetValue("Options", "InputKey", DefaultInput);
+ case ConfigSettings.LanguageKey:
+ return _curConfigData.GetValue("Options", "LanguageKey", DefaultLanguage);
+ case ConfigSettings.HighContrast:
+ return _curConfigData.GetValue("Options", "HighContrast", DefaultHighCon);
+ default:
+ GD.PushError(
+ "SaveSystem.GetConfigValue: Invalid config setting passed. " + setting
+ );
+ return float.MinValue;
+ }
+ }
}
diff --git a/project.godot b/project.godot
index 4ee1a3e3..c29c5c15 100644
--- a/project.godot
+++ b/project.godot
@@ -15,11 +15,15 @@ run/main_scene="res://scenes/SceneTransitions/TitleScreen.tscn"
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
config/icon="res://scenes/BattleDirector/assets/Character1.png"
+[audio]
+
+buses/default_bus_layout=""
+
[autoload]
+StageProducer="*res://Globals/StageProducer.cs"
TimeKeeper="*res://Globals/TimeKeeper.cs"
Scribe="*res://Globals/Scribe.cs"
-StageProducer="*res://Globals/StageProducer.cs"
BgAudioPlayer="*res://Globals/BGAudioPlayer.tscn"
[display]
@@ -39,12 +43,45 @@ input_scheme="ARROWS"
[input]
+ui_left={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
+]
+}
+ui_right={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
+]
+}
+ui_up={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
+]
+}
+ui_down={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
+]
+}
arrowUp={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":88,"key_label":0,"unicode":120,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":50,"key_label":0,"unicode":50,"location":0,"echo":false,"script":null)
]
}
arrowDown={
@@ -53,6 +90,7 @@ arrowDown={
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":51,"key_label":0,"unicode":51,"location":0,"echo":false,"script":null)
]
}
arrowLeft={
@@ -61,6 +99,7 @@ arrowLeft={
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":90,"key_label":0,"unicode":122,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":49,"key_label":0,"unicode":49,"location":0,"echo":false,"script":null)
]
}
arrowRight={
@@ -69,6 +108,7 @@ arrowRight={
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":86,"key_label":0,"unicode":118,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":52,"key_label":0,"unicode":52,"location":0,"echo":false,"script":null)
]
}
Pause={
diff --git a/scenes/NoteManager/scripts/InputHandler.cs b/scenes/NoteManager/scripts/InputHandler.cs
index 4bc8f85c..1b6f32c5 100644
--- a/scenes/NoteManager/scripts/InputHandler.cs
+++ b/scenes/NoteManager/scripts/InputHandler.cs
@@ -86,9 +86,7 @@ public override void _Ready()
private void LoadControlScheme()
{
- string scheme = ProjectSettings.HasSetting("game/input_scheme")
- ? (string)ProjectSettings.GetSetting("game/input_scheme")
- : "ARROWS";
+ string scheme = SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.InputKey).As();
foreach (var arrow in Arrows)
{
var events = InputMap.ActionGetEvents(arrow.Key);
diff --git a/scenes/Options/OptionsMenu.cs b/scenes/Options/OptionsMenu.cs
new file mode 100644
index 00000000..5396175c
--- /dev/null
+++ b/scenes/Options/OptionsMenu.cs
@@ -0,0 +1,100 @@
+using System;
+using Godot;
+
+public partial class OptionsMenu : CanvasLayer
+{
+ private Node _previousScene;
+
+ [Export]
+ private Control _focused;
+ private ProcessModeEnum _previousProcessMode;
+
+ [Export]
+ private HSlider _volumeSlider;
+
+ [Export]
+ private Button _closeButton;
+
+ [Export]
+ private Button _controlsButton;
+
+ [Export]
+ private CheckBox _highContrastToggle;
+
+ private const float MinVolumeVal = 50f;
+
+ public override void _Ready()
+ {
+ _focused.GrabFocus();
+ _volumeSlider.MinValue = MinVolumeVal;
+ _volumeSlider.Value = AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("Master")) + 80;
+ _highContrastToggle.ButtonPressed = SaveSystem
+ .GetConfigValue(SaveSystem.ConfigSettings.HighContrast)
+ .AsBool();
+ _volumeSlider.DragEnded += VolumeChanged;
+ _volumeSlider.ValueChanged += ChangeVolume;
+ _closeButton.Pressed += CloseMenu;
+ _controlsButton.Pressed += OpenControls;
+ _highContrastToggle.Toggled += HighContrastChanged;
+ }
+
+ public override void _Process(double delta) //TODO: Better method for returning focus
+ {
+ if (GetViewport().GuiGetFocusOwner() == null)
+ {
+ _focused.GrabFocus();
+ }
+ }
+
+ public override void _Input(InputEvent @event)
+ {
+ if (@event.IsActionPressed("Pause"))
+ {
+ CloseMenu();
+ GetViewport().SetInputAsHandled();
+ }
+ }
+
+ public void OpenMenu(Node prevScene)
+ {
+ _previousScene = prevScene;
+ _previousProcessMode = _previousScene.GetProcessMode();
+ prevScene.ProcessMode = ProcessModeEnum.Disabled;
+ }
+
+ private void CloseMenu()
+ {
+ _previousScene.ProcessMode = _previousProcessMode;
+ QueueFree();
+ }
+
+ private void OpenControls()
+ {
+ ControlSettings controlSettings = GD.Load("res://scenes/Remapping/Remap.tscn")
+ .Instantiate();
+ AddChild(controlSettings);
+ controlSettings.OpenMenu(this);
+ }
+
+ private void VolumeChanged(bool valueChanged)
+ {
+ if (!valueChanged)
+ return;
+ ChangeVolume((float)_volumeSlider.Value);
+ SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.Volume, _volumeSlider.Value);
+ }
+
+ public static void ChangeVolume(double value)
+ {
+ AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), (float)value - 80);
+ AudioServer.SetBusMute(
+ AudioServer.GetBusIndex("Master"),
+ Math.Abs(value - MinVolumeVal) < .1
+ );
+ }
+
+ private void HighContrastChanged(bool toggled)
+ {
+ SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.HighContrast, toggled);
+ }
+}
diff --git a/scenes/Options/OptionsMenu.tscn b/scenes/Options/OptionsMenu.tscn
index 32c68a8f..f6e3859f 100644
--- a/scenes/Options/OptionsMenu.tscn
+++ b/scenes/Options/OptionsMenu.tscn
@@ -1,32 +1,117 @@
[gd_scene load_steps=3 format=3 uid="uid://buejv62lwtymc"]
[ext_resource type="Script" path="res://scenes/Options/scripts/LanguageSelection.cs" id="1_qyvkw"]
-[ext_resource type="Script" path="res://scenes/SceneTransitions/scripts/SceneChange.cs" id="2_3o1oo"]
+[ext_resource type="Script" path="res://scenes/Options/OptionsMenu.cs" id="1_yjq7i"]
-[node name="OptionsMenu" type="Node2D"]
+[node name="OptionsMenu" type="CanvasLayer" node_paths=PackedStringArray("_focused", "_volumeSlider", "_closeButton", "_controlsButton", "_highContrastToggle")]
+process_mode = 3
+script = ExtResource("1_yjq7i")
+_focused = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/LanguageSelection")
+_volumeSlider = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/Container/Volume")
+_closeButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/TitleButton")
+_controlsButton = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/ControlsButton")
+_highContrastToggle = NodePath("Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/CheckBox")
-[node name="Title" type="Label" parent="."]
-offset_top = 9.0
-offset_right = 642.0
-offset_bottom = 32.0
+[node name="Control" type="Control" parent="."]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="ColorRect" type="ColorRect" parent="Control"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+color = Color(0.133, 0.133, 0.133, 1)
+
+[node name="CenterContainer" type="CenterContainer" parent="Control"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="Control/CenterContainer"]
+layout_mode = 2
+theme_override_constants/margin_top = 5
+theme_override_constants/margin_bottom = 5
+
+[node name="ColorRect" type="ColorRect" parent="Control/CenterContainer/MarginContainer"]
+layout_mode = 2
+color = Color(0.24, 0.24, 0.24, 0.854902)
+
+[node name="MarginContainer" type="MarginContainer" parent="Control/CenterContainer/MarginContainer"]
+layout_mode = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Control/CenterContainer/MarginContainer/MarginContainer"]
+custom_minimum_size = Vector2(240, 0)
+layout_mode = 2
+size_flags_horizontal = 0
+theme_override_constants/separation = 25
+alignment = 1
+
+[node name="Title" type="Label" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
text = "TITLE_OPTIONS"
horizontal_alignment = 1
-[node name="LanguageSelection" type="OptionButton" parent="."]
-offset_left = 225.0
-offset_top = 122.0
-offset_right = 451.0
-offset_bottom = 159.0
+[node name="HSeparator" type="HSeparator" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="CheckBox" type="CheckBox" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 8
+text = "OPTIONS_CONTRAST_LABEL"
+horizontal_alignment = 1
+
+[node name="Container" type="VBoxContainer" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
+theme_override_constants/separation = 0
+
+[node name="Label" type="Label" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/Container"]
+layout_mode = 2
+text = "OPTIONS_VOLUME_LABEL"
+horizontal_alignment = 1
+
+[node name="Volume" type="HSlider" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer/Container"]
+layout_mode = 2
+tooltip_text = "OPTIONS_VOLUME_LABEL"
+min_value = 50.0
+max_value = 80.0
+value = 80.0
+
+[node name="LanguageSelection" type="OptionButton" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+unique_name_in_owner = true
+layout_mode = 2
item_count = 2
popup/item_0/text = "English"
popup/item_1/text = "中文"
popup/item_1/id = 1
script = ExtResource("1_qyvkw")
-[node name="TitleButton" type="Button" parent="."]
-offset_left = 232.0
-offset_top = 320.0
-offset_right = 408.0
-offset_bottom = 351.0
+[node name="ControlsButton" type="Button" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
+text = "TITLE_CONTROLS"
+
+[node name="TitleButton" type="Button" parent="Control/CenterContainer/MarginContainer/MarginContainer/VBoxContainer"]
+layout_mode = 2
text = "CONTROLS_RETURN_BUTTON"
-script = ExtResource("2_3o1oo")
diff --git a/scenes/Options/scripts/LanguageSelection.cs b/scenes/Options/scripts/LanguageSelection.cs
index 14599c27..5f5e9ec5 100644
--- a/scenes/Options/scripts/LanguageSelection.cs
+++ b/scenes/Options/scripts/LanguageSelection.cs
@@ -6,12 +6,11 @@ public partial class LanguageSelection : OptionButton
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
- this.Connect("item_selected", new Callable(this, nameof(OnLanguageSelected)));
- GD.Print("getlocale: " + TranslationServer.GetLocale());
+ Connect("item_selected", new Callable(this, nameof(OnLanguageSelected)));
PresetDropdown(TranslationServer.GetLocale());
}
- private void OnLanguageSelected(int index)
+ public void OnLanguageSelected(int index)
{
switch (index)
{
@@ -27,6 +26,7 @@ private void OnLanguageSelected(int index)
private void ChangeLanguage(string language)
{
TranslationServer.SetLocale(language);
+ SaveSystem.UpdateConfig(SaveSystem.ConfigSettings.LanguageKey, language);
}
private void PresetDropdown(string language)
diff --git a/scenes/Remapping/ControlSettings.cs b/scenes/Remapping/ControlSettings.cs
index f35dcacc..21d3d3b0 100644
--- a/scenes/Remapping/ControlSettings.cs
+++ b/scenes/Remapping/ControlSettings.cs
@@ -15,6 +15,12 @@ public partial class ControlSettings : Node2D
[Export]
public Sprite2D downKey;
+ private Node _previousScene;
+ private ProcessModeEnum _previousProcessMode;
+
+ [Export]
+ private Button _closeButton;
+
public override void _Ready()
{
GetNode