aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/builds.yml2
-rw-r--r--game/audio/music/Brunels_Waltz_2.mp3.import19
-rw-r--r--game/audio/music/Deliverance.mp3.import19
-rw-r--r--game/audio/music/The_Crown.mp3.import19
-rw-r--r--game/project.godot5
-rw-r--r--game/splash_assets/splash_end.pngbin0 -> 1264857 bytes
-rw-r--r--game/splash_assets/splash_end.png.import34
-rw-r--r--game/splash_assets/splash_image.pngbin0 -> 1756225 bytes
-rw-r--r--game/splash_assets/splash_image.png.import34
-rw-r--r--game/splash_assets/splash_startup.ogvbin0 -> 2964974 bytes
-rw-r--r--game/src/Autoload/GameDebug.gd20
-rw-r--r--game/src/CreditsMenu/CreditsMenu.gd (renamed from game/src/Credits/Credits.gd)2
-rw-r--r--game/src/CreditsMenu/CreditsMenu.tscn (renamed from game/src/Credits/Credits.tscn)4
-rw-r--r--game/src/GameMenu.gd38
-rw-r--r--game/src/GameMenu.tscn41
-rw-r--r--game/src/GameStart.tscn52
-rw-r--r--game/src/LocaleButton.gd17
-rw-r--r--game/src/MainMenu/MainMenu.gd14
-rw-r--r--game/src/MainMenu/MainMenu.tscn10
-rw-r--r--game/src/MusicConductor/MusicConductor.gd78
-rw-r--r--game/src/MusicConductor/MusicConductor.tscn4
-rw-r--r--game/src/MusicConductor/MusicPlayer.gd68
-rw-r--r--game/src/MusicConductor/MusicPlayer.tscn61
-rw-r--r--game/src/MusicConductor/MusicUIController.gd66
-rw-r--r--game/src/MusicConductor/MusicUIController.tscn64
-rw-r--r--game/src/MusicConductor/SongInfo.gd12
-rw-r--r--game/src/OptionMenu/AutosaveIntervalSelector.gd2
-rw-r--r--game/src/OptionMenu/GeneralTab.gd8
-rw-r--r--game/src/OptionMenu/GeneralTab.tscn82
-rw-r--r--game/src/OptionMenu/OptionsMenu.gd9
-rw-r--r--game/src/OptionMenu/OptionsMenu.tscn50
-rw-r--r--game/src/OptionMenu/QualityPresetSelector.gd4
-rw-r--r--game/src/OptionMenu/RefreshRateSelector.gd5
-rw-r--r--game/src/OptionMenu/VideoTab.gd8
-rw-r--r--game/src/OptionMenu/VideoTab.tscn73
-rw-r--r--game/src/SplashContainer.gd30
36 files changed, 680 insertions, 274 deletions
diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml
index bd8ca20..69ea324 100644
--- a/.github/workflows/builds.yml
+++ b/.github/workflows/builds.yml
@@ -1,6 +1,6 @@
name: Builds
-#on: [pull_request]
+on: [pull_request]
concurrency:
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos
diff --git a/game/audio/music/Brunels_Waltz_2.mp3.import b/game/audio/music/Brunels_Waltz_2.mp3.import
new file mode 100644
index 0000000..bca8e72
--- /dev/null
+++ b/game/audio/music/Brunels_Waltz_2.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://jv2gmmla7efh"
+path="res://.godot/imported/Brunels_Waltz_2.mp3-9089b7cea8551690620c78deb2f5893e.mp3str"
+
+[deps]
+
+source_file="res://audio/music/Brunels_Waltz_2.mp3"
+dest_files=["res://.godot/imported/Brunels_Waltz_2.mp3-9089b7cea8551690620c78deb2f5893e.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/game/audio/music/Deliverance.mp3.import b/game/audio/music/Deliverance.mp3.import
new file mode 100644
index 0000000..673eba8
--- /dev/null
+++ b/game/audio/music/Deliverance.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://b3l1dxak84lmw"
+path="res://.godot/imported/Deliverance.mp3-503781482297f95faeb04be77c6c4a8e.mp3str"
+
+[deps]
+
+source_file="res://audio/music/Deliverance.mp3"
+dest_files=["res://.godot/imported/Deliverance.mp3-503781482297f95faeb04be77c6c4a8e.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/game/audio/music/The_Crown.mp3.import b/game/audio/music/The_Crown.mp3.import
new file mode 100644
index 0000000..85dd783
--- /dev/null
+++ b/game/audio/music/The_Crown.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://cvlvbcifaif0p"
+path="res://.godot/imported/The_Crown.mp3-cac26a6fb3ac34d1dc06e96fb0b873c1.mp3str"
+
+[deps]
+
+source_file="res://audio/music/The_Crown.mp3"
+dest_files=["res://.godot/imported/The_Crown.mp3-cac26a6fb3ac34d1dc06e96fb0b873c1.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/game/project.godot b/game/project.godot
index ddeddb2..323bf41 100644
--- a/game/project.godot
+++ b/game/project.godot
@@ -11,8 +11,10 @@ config_version=5
[application]
config/name="OpenVic2"
-run/main_scene="res://src/GameMenu.tscn"
+run/main_scene="res://src/GameStart.tscn"
config/features=PackedStringArray("4.0", "Forward Plus")
+boot_splash/bg_color=Color(0.380392, 0.145098, 0.14902, 1)
+boot_splash/image="res://splash_assets/splash_image.png"
config/icon="res://icon.svg"
config/project_settings_override.template="user://settings.cfg"
@@ -23,6 +25,7 @@ Resolution="*res://src/Autoload/Resolution.gd"
MusicConductor="*res://src/MusicConductor/MusicConductor.tscn"
SoundManager="*res://src/Autoload/SoundManager.gd"
Keychain="*res://addons/keychain/Keychain.gd"
+GameDebug="*res://src/Autoload/GameDebug.gd"
[display]
diff --git a/game/splash_assets/splash_end.png b/game/splash_assets/splash_end.png
new file mode 100644
index 0000000..ac7b1da
--- /dev/null
+++ b/game/splash_assets/splash_end.png
Binary files differ
diff --git a/game/splash_assets/splash_end.png.import b/game/splash_assets/splash_end.png.import
new file mode 100644
index 0000000..64a7f9a
--- /dev/null
+++ b/game/splash_assets/splash_end.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://deef5hufq0j61"
+path="res://.godot/imported/splash_end.png-967b7882642610d3be0d67e2695b1564.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://splash_assets/splash_end.png"
+dest_files=["res://.godot/imported/splash_end.png-967b7882642610d3be0d67e2695b1564.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=true
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/game/splash_assets/splash_image.png b/game/splash_assets/splash_image.png
new file mode 100644
index 0000000..5f7cff9
--- /dev/null
+++ b/game/splash_assets/splash_image.png
Binary files differ
diff --git a/game/splash_assets/splash_image.png.import b/game/splash_assets/splash_image.png.import
new file mode 100644
index 0000000..ce7e72c
--- /dev/null
+++ b/game/splash_assets/splash_image.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cgdnixsyh7bja"
+path="res://.godot/imported/splash_image.png-e2810276ec1ba470c15ca32f0eb76f88.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://splash_assets/splash_image.png"
+dest_files=["res://.godot/imported/splash_image.png-e2810276ec1ba470c15ca32f0eb76f88.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=true
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/game/splash_assets/splash_startup.ogv b/game/splash_assets/splash_startup.ogv
new file mode 100644
index 0000000..950d9a6
--- /dev/null
+++ b/game/splash_assets/splash_startup.ogv
Binary files differ
diff --git a/game/src/Autoload/GameDebug.gd b/game/src/Autoload/GameDebug.gd
new file mode 100644
index 0000000..6f10bf5
--- /dev/null
+++ b/game/src/Autoload/GameDebug.gd
@@ -0,0 +1,20 @@
+extends Node
+
+# REQUIREMENTS:
+# * SS-56
+func _ready():
+ for engine_args in OS.get_cmdline_args():
+ match(engine_args):
+ "--game-debug":
+ set_debug_mode(true)
+
+ for engine_args in OS.get_cmdline_user_args():
+ match(engine_args):
+ "--game-debug", "-d", "--debug", "--debug-mode":
+ set_debug_mode(true)
+
+func set_debug_mode(value : bool) -> void:
+ ProjectSettings.set_setting("openvic2/debug/enabled", value)
+
+func is_debug_mode() -> bool:
+ return ProjectSettings.get_setting("openvic2/debug/enabled", false)
diff --git a/game/src/Credits/Credits.gd b/game/src/CreditsMenu/CreditsMenu.gd
index a69732c..be992ef 100644
--- a/game/src/Credits/Credits.gd
+++ b/game/src/CreditsMenu/CreditsMenu.gd
@@ -17,8 +17,6 @@ signal back_button_pressed
@export_file("*.csv")
var core_credits_path : String
-# TODO: implement for theme instead
-# waiting for https://github.com/OpenVic2Project/OpenVic2/pull/48
@export_group("Label Variants", "label_variants_")
@export
var label_variants_project : StringName
diff --git a/game/src/Credits/Credits.tscn b/game/src/CreditsMenu/CreditsMenu.tscn
index fce29fa..8a81823 100644
--- a/game/src/Credits/Credits.tscn
+++ b/game/src/CreditsMenu/CreditsMenu.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=2 format=3 uid="uid://c8knthxkwj1uj"]
-[ext_resource type="Script" path="res://src/Credits/Credits.gd" id="1_csd7i"]
+[ext_resource type="Script" path="res://src/CreditsMenu/CreditsMenu.gd" id="1_csd7i"]
-[node name="Credits" type="Control" node_paths=PackedStringArray("credits_list")]
+[node name="CreditsMenu" type="Control" node_paths=PackedStringArray("credits_list")]
editor_description = "UI-34"
layout_mode = 3
anchors_preset = 15
diff --git a/game/src/GameMenu.gd b/game/src/GameMenu.gd
index 3a4c88f..4b589f9 100644
--- a/game/src/GameMenu.gd
+++ b/game/src/GameMenu.gd
@@ -1,41 +1,47 @@
extends Control
+@export var _main_menu : Control
+@export var _options_menu : Control
+@export var _lobby_menu : Control
+@export var _credits_menu : Control
+
# REQUIREMENTS
# * SS-10
func _ready():
Events.Options.load_settings_from_file()
func _on_main_menu_new_game_button_pressed():
- $OptionsMenu.toggle_locale_button_visibility(false)
- $LobbyMenu.show()
- $MainMenu.hide()
+ _lobby_menu.show()
+ _main_menu.hide()
# REQUIREMENTS
# * SS-6
# * UIFUN-5
func _on_main_menu_options_button_pressed():
- $OptionsMenu.toggle_locale_button_visibility(false)
- $OptionsMenu.show()
- $MainMenu.hide()
+ _options_menu.show()
+ _main_menu.hide()
func _on_options_menu_back_button_pressed():
- $MainMenu.show()
- $OptionsMenu.hide()
- $OptionsMenu.toggle_locale_button_visibility(true)
+ _main_menu.show()
+ _options_menu.hide()
func _on_lobby_menu_back_button_pressed():
- $MainMenu.show()
- $LobbyMenu.hide()
- $OptionsMenu.toggle_locale_button_visibility(true)
+ _main_menu.show()
+ _lobby_menu.hide()
func _on_credits_back_button_pressed():
- $Credits.hide()
- $MainMenu.show()
+ _credits_menu.hide()
+ _main_menu.show()
func _on_main_menu_credits_button_pressed():
- $Credits.show()
- $MainMenu.hide()
+ _credits_menu.show()
+ _main_menu.hide()
+
+
+
+func _on_splash_container_splash_end():
+ show()
diff --git a/game/src/GameMenu.tscn b/game/src/GameMenu.tscn
index 5493870..ab892df 100644
--- a/game/src/GameMenu.tscn
+++ b/game/src/GameMenu.tscn
@@ -1,15 +1,14 @@
-[gd_scene load_steps=8 format=3 uid="uid://b4pg2y2ivib8f"]
+[gd_scene load_steps=8 format=3 uid="uid://o4u142w4qkln"]
[ext_resource type="Script" path="res://src/GameMenu.gd" id="1_cafwe"]
[ext_resource type="Theme" uid="uid://cr4lh0vraucx7" path="res://default_theme.tres" id="1_q3b4c"]
[ext_resource type="PackedScene" uid="uid://dvoin538iby54" path="res://src/MainMenu/MainMenu.tscn" id="2_2jbkh"]
[ext_resource type="PackedScene" uid="uid://cnbfxjy1m6wja" path="res://src/OptionMenu/OptionsMenu.tscn" id="3_111lv"]
-[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="4_jno35"]
-[ext_resource type="PackedScene" uid="uid://c8knthxkwj1uj" path="res://src/Credits/Credits.tscn" id="4_n0hoo"]
+[ext_resource type="PackedScene" uid="uid://c8knthxkwj1uj" path="res://src/CreditsMenu/CreditsMenu.tscn" id="4_n0hoo"]
[ext_resource type="PackedScene" uid="uid://crhkgngfnxf4y" path="res://src/LobbyMenu/LobbyMenu.tscn" id="4_nofk1"]
-[ext_resource type="PackedScene" uid="uid://dmnqyvl3qfq2e" path="res://src/MusicConductor/MusicUIController.tscn" id="6_lts1m"]
+[ext_resource type="PackedScene" uid="uid://cvl76duuym1wq" path="res://src/MusicConductor/MusicPlayer.tscn" id="6_lts1m"]
-[node name="GameMenu" type="Control"]
+[node name="GameMenu" type="Control" node_paths=PackedStringArray("_main_menu", "_options_menu", "_lobby_menu", "_credits_menu")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -18,19 +17,15 @@ grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_q3b4c")
script = ExtResource("1_cafwe")
+_main_menu = NodePath("MainMenu")
+_options_menu = NodePath("OptionsMenu")
+_lobby_menu = NodePath("LobbyMenu")
+_credits_menu = NodePath("CreditsMenu")
[node name="MainMenu" parent="." instance=ExtResource("2_2jbkh")]
layout_mode = 1
metadata/_edit_vertical_guides_ = [251.0, 269.0, 504.0, 523.0, 15.0, 759.0, 777.0]
-[node name="MusicUIController" parent="." instance=ExtResource("6_lts1m")]
-layout_mode = 1
-anchor_left = 0.843
-anchor_right = 0.953
-offset_left = -0.0400391
-offset_right = 0.159912
-metadata/_edit_use_anchors_ = true
-
[node name="OptionsMenu" parent="." instance=ExtResource("3_111lv")]
visible = false
layout_mode = 1
@@ -39,29 +34,23 @@ layout_mode = 1
visible = false
layout_mode = 1
-[node name="Credits" parent="." instance=ExtResource("4_n0hoo")]
+[node name="CreditsMenu" parent="." instance=ExtResource("4_n0hoo")]
visible = false
layout_mode = 1
-[node name="HBox" type="HBoxContainer" parent="."]
+[node name="MusicPlayer" parent="." instance=ExtResource("6_lts1m")]
layout_mode = 1
-anchors_preset = 3
+anchors_preset = 1
anchor_left = 1.0
-anchor_top = 1.0
anchor_right = 1.0
-anchor_bottom = 1.0
-offset_left = -150.0
-offset_top = -20.0
+offset_left = -184.0
+offset_right = -34.0
+offset_bottom = 110.0
grow_horizontal = 0
-grow_vertical = 0
-alignment = 2
-
-[node name="LocaleButton" parent="HBox" instance=ExtResource("4_jno35")]
-layout_mode = 2
[connection signal="credits_button_pressed" from="MainMenu" to="." method="_on_main_menu_credits_button_pressed"]
[connection signal="new_game_button_pressed" from="MainMenu" to="." method="_on_main_menu_new_game_button_pressed"]
[connection signal="options_button_pressed" from="MainMenu" to="." method="_on_main_menu_options_button_pressed"]
[connection signal="back_button_pressed" from="OptionsMenu" to="." method="_on_options_menu_back_button_pressed"]
[connection signal="back_button_pressed" from="LobbyMenu" to="." method="_on_lobby_menu_back_button_pressed"]
-[connection signal="back_button_pressed" from="Credits" to="." method="_on_credits_back_button_pressed"]
+[connection signal="back_button_pressed" from="CreditsMenu" to="." method="_on_credits_back_button_pressed"]
diff --git a/game/src/GameStart.tscn b/game/src/GameStart.tscn
new file mode 100644
index 0000000..2046bb5
--- /dev/null
+++ b/game/src/GameStart.tscn
@@ -0,0 +1,52 @@
+[gd_scene load_steps=6 format=3 uid="uid://1udsn4mggep2"]
+
+[ext_resource type="PackedScene" uid="uid://o4u142w4qkln" path="res://src/GameMenu.tscn" id="1_wlojq"]
+[ext_resource type="Script" path="res://src/SplashContainer.gd" id="2_xmcgv"]
+[ext_resource type="Texture2D" uid="uid://deef5hufq0j61" path="res://splash_assets/splash_end.png" id="3_qfv12"]
+[ext_resource type="Texture2D" uid="uid://cgdnixsyh7bja" path="res://splash_assets/splash_image.png" id="4_5b6yq"]
+[ext_resource type="VideoStream" path="res://splash_assets/splash_startup.ogv" id="5_8euyy"]
+
+[node name="GameStartup" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="GameMenu" parent="." instance=ExtResource("1_wlojq")]
+visible = false
+layout_mode = 1
+
+[node name="SplashContainer" type="AspectRatioContainer" parent="." node_paths=PackedStringArray("_splash_finish", "_splash_image", "_splash_video")]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+ratio = 1.7778
+stretch_mode = 3
+script = ExtResource("2_xmcgv")
+_splash_finish = NodePath("SplashFinish")
+_splash_image = NodePath("SplashImage")
+_splash_video = NodePath("SplashVideo")
+
+[node name="SplashFinish" type="TextureRect" parent="SplashContainer"]
+layout_mode = 2
+texture = ExtResource("3_qfv12")
+expand_mode = 1
+
+[node name="SplashImage" type="TextureRect" parent="SplashContainer"]
+layout_mode = 2
+texture = ExtResource("4_5b6yq")
+expand_mode = 1
+
+[node name="SplashVideo" type="VideoStreamPlayer" parent="SplashContainer"]
+layout_mode = 2
+stream = ExtResource("5_8euyy")
+autoplay = true
+expand = true
+
+[connection signal="splash_end" from="SplashContainer" to="GameMenu" method="_on_splash_container_splash_end"]
+[connection signal="finished" from="SplashContainer/SplashVideo" to="SplashContainer" method="_on_splash_startup_finished"]
diff --git a/game/src/LocaleButton.gd b/game/src/LocaleButton.gd
index a8220de..c3c6925 100644
--- a/game/src/LocaleButton.gd
+++ b/game/src/LocaleButton.gd
@@ -23,6 +23,11 @@ func _ready():
Events.Options.load_settings.connect(load_setting)
Events.Options.save_settings.connect(save_setting)
+
+func _notification(what):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _select_locale_by_string(TranslationServer.get_locale())
func _valid_index(index : int) -> bool:
return 0 <= index and index < _locales_list.size()
@@ -32,12 +37,18 @@ func load_setting(file : ConfigFile) -> void:
var load_value = file.get_value(section_name, setting_name, TranslationServer.get_locale())
match typeof(load_value):
TYPE_STRING, TYPE_STRING_NAME:
- var locale_index := _locales_list.find(load_value as String)
- if locale_index != -1:
- selected = locale_index
+ if _select_locale_by_string(load_value as String):
+ item_selected.emit(selected)
return
push_error("Setting value '%s' invalid for setting [%s] %s" % [load_value, section_name, setting_name])
reset_setting()
+
+func _select_locale_by_string(locale : String) -> bool:
+ var locale_index := _locales_list.find(locale)
+ if locale_index != -1:
+ selected = locale_index
+ return true
+ return false
# REQUIREMENTS:
# * UIFUN-74
diff --git a/game/src/MainMenu/MainMenu.gd b/game/src/MainMenu/MainMenu.gd
index 7e790c0..662cd90 100644
--- a/game/src/MainMenu/MainMenu.gd
+++ b/game/src/MainMenu/MainMenu.gd
@@ -16,12 +16,10 @@ var _checksum_label : Label
func _ready():
print("From GDScript")
TestSingleton.hello_singleton()
- # UIFUN-97
- var checksum := Checksum.get_checksum_text()
- _checksum_label.tooltip_text = "Checksum " + checksum
- _checksum_label.text = "(" + checksum.substr(0, 4) + ")"
- _new_game_button.grab_focus()
-
+ # UI-111
+ _checksum_label.tooltip_text = "Checksum " + Checksum.get_checksum_text()
+ _checksum_label.text = "(" + Checksum.get_checksum_text().substr(0, 4) + ")"
+ _on_new_game_button_visibility_changed()
# REQUIREMENTS:
# * SS-14
@@ -55,3 +53,7 @@ func _on_credits_button_pressed():
func _on_exit_button_pressed():
print("See you later!")
get_tree().quit()
+
+func _on_new_game_button_visibility_changed():
+ if visible:
+ _new_game_button.grab_focus.call_deferred()
diff --git a/game/src/MainMenu/MainMenu.tscn b/game/src/MainMenu/MainMenu.tscn
index af2d975..4fc95d8 100644
--- a/game/src/MainMenu/MainMenu.tscn
+++ b/game/src/MainMenu/MainMenu.tscn
@@ -1,7 +1,8 @@
-[gd_scene load_steps=3 format=3 uid="uid://dvoin538iby54"]
+[gd_scene load_steps=4 format=3 uid="uid://dvoin538iby54"]
[ext_resource type="Theme" uid="uid://cr4lh0vraucx7" path="res://default_theme.tres" id="1_dfm41"]
[ext_resource type="Script" path="res://src/MainMenu/MainMenu.gd" id="2_nm1fq"]
+[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="3_amonp"]
[node name="MainMenu" type="Control" node_paths=PackedStringArray("_new_game_button", "_checksum_label")]
editor_description = "UI-13"
@@ -152,7 +153,14 @@ mouse_filter = 1
theme_type_variation = &"Label_Checksum"
text = "(0000)"
+[node name="LocaleButton" parent="Panel/VBox/Margin2" instance=ExtResource("3_amonp")]
+layout_mode = 2
+size_flags_horizontal = 8
+alignment = 0
+text_overrun_behavior = 4
+
[connection signal="pressed" from="Panel/VBox/Margin/ButtonList/NewGameButton" to="." method="_on_new_game_button_pressed"]
+[connection signal="visibility_changed" from="Panel/VBox/Margin/ButtonList/NewGameButton" to="." method="_on_new_game_button_visibility_changed"]
[connection signal="pressed" from="Panel/VBox/Margin/ButtonList/ContinueButton" to="." method="_on_continue_button_pressed"]
[connection signal="pressed" from="Panel/VBox/Margin/ButtonList/MultiplayerButton" to="." method="_on_multi_player_button_pressed"]
[connection signal="pressed" from="Panel/VBox/Margin/ButtonList/OptionsButton" to="." method="_on_options_button_pressed"]
diff --git a/game/src/MusicConductor/MusicConductor.gd b/game/src/MusicConductor/MusicConductor.gd
index a463d6d..c0cfc46 100644
--- a/game/src/MusicConductor/MusicConductor.gd
+++ b/game/src/MusicConductor/MusicConductor.gd
@@ -1,68 +1,72 @@
extends Node
# SS-67
-@export_dir var musicDir : String
-@export_file var firstSongName : String
+@export_dir var music_directory : String
+@export var first_song_name : String
-var selectedTrack = 0
-var availableSongs : Array[SongInfo] = []
-var autoPlayNextSong : bool = true
+var _selected_track = 0
+var _available_songs : Array[SongInfo] = []
+var _auto_play_next_song : bool = true
-func getAllSongNames() -> Array[String]:
+## True if music player should be visible.
+## Used to keep keep consistency between scene changes
+var is_music_player_visible : bool = true
+
+func get_all_song_names() -> Array[String]:
var songNames : Array[String] = []
- for si in availableSongs:
- songNames.append(si.readableName)
+ for si in _available_songs:
+ songNames.append(si.song_name)
return songNames
-func getCurrentSongIndex() -> int:
- return selectedTrack
+func get_current_song_index() -> int:
+ return _selected_track
-func getCurrentSongName() -> String:
- return availableSongs[selectedTrack].readableName
+func get_current_song_name() -> String:
+ return _available_songs[_selected_track].song_name
-func scrubSongByPercentage(percentage: float) -> void:
+func scrub_song_by_percentage(percentage: float) -> void:
var percentInSeconds : float = (percentage / 100.0) * $AudioStreamPlayer.stream.get_length()
$AudioStreamPlayer.play(percentInSeconds)
-func getCurrentSongProgressPercentage() -> float:
+func get_current_song_progress_percentage() -> float:
return 100 * ($AudioStreamPlayer.get_playback_position() / $AudioStreamPlayer.stream.get_length())
-func isPaused() -> bool:
+func is_paused() -> bool:
return $AudioStreamPlayer.stream_paused
-func togglePlayPause() -> void:
+func toggle_play_pause() -> void:
$AudioStreamPlayer.stream_paused = !$AudioStreamPlayer.stream_paused
-func startCurrentSong() -> void:
- $AudioStreamPlayer.stream = availableSongs[selectedTrack].loadedStream
+func start_current_song() -> void:
+ $AudioStreamPlayer.stream = _available_songs[_selected_track].song_stream
$AudioStreamPlayer.play()
# SS-70
-func startSongByIndex(id: int) -> void:
- selectedTrack = id
- startCurrentSong()
+func start_song_by_index(id: int) -> void:
+ _selected_track = id
+ start_current_song()
# SS-69
-func nextSong() -> void:
- selectedTrack = (selectedTrack + 1) % len(availableSongs)
- startCurrentSong()
+func select_next_song() -> void:
+ _selected_track = (_selected_track + 1) % len(_available_songs)
+ start_current_song()
-func prevSong() -> void:
- selectedTrack = (len(availableSongs) - 1) if (selectedTrack == 0) else (selectedTrack - 1)
- startCurrentSong()
+func select_previous_song() -> void:
+ _selected_track = (len(_available_songs) - 1) if (_selected_track == 0) else (_selected_track - 1)
+ start_current_song()
-# Called when the node enters the scene tree for the first time.
func _ready():
- var dir = DirAccess.open(musicDir)
+ var dir = DirAccess.open(music_directory)
for fname in dir.get_files():
- if !fname.ends_with(".import"):
- if fname.get_basename() == firstSongName:
- selectedTrack = availableSongs.size()
- availableSongs.append(SongInfo.new(musicDir, fname))
- startCurrentSong()
+ if fname.ends_with(".import"):
+ fname = fname.get_basename()
+ if fname.get_basename() == first_song_name:
+ _selected_track = _available_songs.size()
+ _available_songs.append(SongInfo.new(music_directory, fname))
+ start_current_song()
func _on_audio_stream_player_finished():
- if autoPlayNextSong:
- nextSong()
- startCurrentSong()
+ if _auto_play_next_song:
+ select_next_song()
+ start_current_song()
diff --git a/game/src/MusicConductor/MusicConductor.tscn b/game/src/MusicConductor/MusicConductor.tscn
index 69529d8..7194f0b 100644
--- a/game/src/MusicConductor/MusicConductor.tscn
+++ b/game/src/MusicConductor/MusicConductor.tscn
@@ -4,8 +4,8 @@
[node name="MusicConductor" type="Node"]
script = ExtResource("1_56t1b")
-musicDir = "res://audio/music/"
-firstSongName = "The_Crown"
+music_directory = "res://audio/music"
+first_song_name = "The_Crown"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
bus = &"Music"
diff --git a/game/src/MusicConductor/MusicPlayer.gd b/game/src/MusicConductor/MusicPlayer.gd
new file mode 100644
index 0000000..baf8a43
--- /dev/null
+++ b/game/src/MusicConductor/MusicPlayer.gd
@@ -0,0 +1,68 @@
+extends Control
+
+@export var _song_selector_button : OptionButton
+@export var _progress_slider : HSlider
+@export var _previous_song_button : Button
+@export var _play_pause_button : Button
+@export var _next_song_button : Button
+@export var _visbility_button : Button
+
+var _is_user_dragging_progress_slider : bool = false
+
+func _ready():
+ for songName in MusicConductor.get_all_song_names():
+ _song_selector_button.add_item(songName, _song_selector_button.item_count)
+ _update_song_name_visual()
+ _update_play_pause_button()
+ _set_music_player_visible(MusicConductor.is_music_player_visible)
+
+
+func _process(_delta):
+ if !_is_user_dragging_progress_slider:
+ _progress_slider.value = MusicConductor.get_current_song_progress_percentage()
+
+func _update_song_name_visual():
+ _song_selector_button.selected = MusicConductor.get_current_song_index()
+
+func _update_play_pause_button():
+ _play_pause_button.text = "◼" if MusicConductor.is_paused() else "▶"
+
+func _on_play_pause_button_pressed():
+ MusicConductor.toggle_play_pause()
+ _update_play_pause_button()
+
+func _on_next_song_button_pressed():
+ MusicConductor.select_next_song()
+ _update_song_name_visual()
+ _update_play_pause_button()
+
+func _on_previous_song_button_pressed():
+ MusicConductor.select_previous_song()
+ _update_song_name_visual()
+ _update_play_pause_button()
+
+func _on_option_button_item_selected(index):
+ # UIFUN-92
+ MusicConductor.start_song_by_index(index)
+
+
+func _on_progress_slider_drag_started():
+ _is_user_dragging_progress_slider = true
+
+
+func _on_progress_slider_drag_ended(_value_changed):
+ MusicConductor.scrub_song_by_percentage(_progress_slider.value)
+ _is_user_dragging_progress_slider = false
+ _update_play_pause_button()
+
+func _set_music_player_visible(is_player_visible : bool) -> void:
+ MusicConductor.is_music_player_visible = is_player_visible
+ _visbility_button.text = "⬆️" if is_player_visible else "⬇"
+ _song_selector_button.visible = is_player_visible
+ _progress_slider.visible = is_player_visible
+ _previous_song_button.visible = is_player_visible
+ _play_pause_button.visible = is_player_visible
+ _next_song_button.visible = is_player_visible
+
+func _on_music_ui_visibility_button_pressed():
+ _set_music_player_visible(not MusicConductor.is_music_player_visible)
diff --git a/game/src/MusicConductor/MusicPlayer.tscn b/game/src/MusicConductor/MusicPlayer.tscn
new file mode 100644
index 0000000..91b6fd3
--- /dev/null
+++ b/game/src/MusicConductor/MusicPlayer.tscn
@@ -0,0 +1,61 @@
+[gd_scene load_steps=2 format=3 uid="uid://cvl76duuym1wq"]
+
+[ext_resource type="Script" path="res://src/MusicConductor/MusicPlayer.gd" id="1_gcm4m"]
+
+[node name="MusicPlayer" type="BoxContainer" node_paths=PackedStringArray("_song_selector_button", "_progress_slider", "_previous_song_button", "_play_pause_button", "_next_song_button", "_visbility_button")]
+editor_description = "UI-104"
+mouse_filter = 2
+script = ExtResource("1_gcm4m")
+_song_selector_button = NodePath("Control/SongSelectorButton")
+_progress_slider = NodePath("Control/ProgressSlider")
+_previous_song_button = NodePath("Control/HBoxContainer/PreviousSongButton")
+_play_pause_button = NodePath("Control/HBoxContainer/PlayPauseButton")
+_next_song_button = NodePath("Control/HBoxContainer/NextSongButton")
+_visbility_button = NodePath("Control/MusicUIVisibilityButton")
+
+[node name="Control" type="VBoxContainer" parent="."]
+custom_minimum_size = Vector2(150, 0)
+layout_mode = 2
+mouse_filter = 2
+
+[node name="SongSelectorButton" type="OptionButton" parent="Control"]
+editor_description = "UI-107"
+layout_mode = 2
+alignment = 1
+text_overrun_behavior = 3
+fit_to_longest_item = false
+
+[node name="ProgressSlider" type="HSlider" parent="Control"]
+layout_mode = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Control"]
+layout_mode = 2
+size_flags_horizontal = 4
+mouse_filter = 2
+
+[node name="PreviousSongButton" type="Button" parent="Control/HBoxContainer"]
+layout_mode = 2
+text = "<"
+
+[node name="PlayPauseButton" type="Button" parent="Control/HBoxContainer"]
+custom_minimum_size = Vector2(30, 0)
+layout_mode = 2
+text = "▶"
+
+[node name="NextSongButton" type="Button" parent="Control/HBoxContainer"]
+layout_mode = 2
+text = ">"
+
+[node name="MusicUIVisibilityButton" type="Button" parent="Control"]
+editor_description = "UI-106"
+layout_mode = 2
+size_flags_horizontal = 4
+text = "⬆"
+
+[connection signal="item_selected" from="Control/SongSelectorButton" to="." method="_on_option_button_item_selected"]
+[connection signal="drag_ended" from="Control/ProgressSlider" to="." method="_on_progress_slider_drag_ended"]
+[connection signal="drag_started" from="Control/ProgressSlider" to="." method="_on_progress_slider_drag_started"]
+[connection signal="pressed" from="Control/HBoxContainer/PreviousSongButton" to="." method="_on_previous_song_button_pressed"]
+[connection signal="pressed" from="Control/HBoxContainer/PlayPauseButton" to="." method="_on_play_pause_button_pressed"]
+[connection signal="pressed" from="Control/HBoxContainer/NextSongButton" to="." method="_on_next_song_button_pressed"]
+[connection signal="pressed" from="Control/MusicUIVisibilityButton" to="." method="_on_music_ui_visibility_button_pressed"]
diff --git a/game/src/MusicConductor/MusicUIController.gd b/game/src/MusicConductor/MusicUIController.gd
deleted file mode 100644
index f2c9225..0000000
--- a/game/src/MusicConductor/MusicUIController.gd
+++ /dev/null
@@ -1,66 +0,0 @@
-extends Control
-
-@export var songSelectorButton : OptionButton
-@export var progressSlider : HSlider
-@export var prevSongButton : Button
-@export var playPauseButton : Button
-@export var nextSongButton : Button
-@export var widgetVisibilityButton : Button
-
-var isMusicPlayerVisible : bool = true
-var isUserDraggingProgressSlider : bool = false
-
-# Called when the node enters the scene tree for the first time.
-func _ready():
- for songName in MusicConductor.getAllSongNames():
- songSelectorButton.add_item(songName, songSelectorButton.item_count)
- updateSongNameVisual()
-
-
-# Called every frame. 'delta' is the elapsed time since the previous frame.
-func _process(_delta):
- if !isUserDraggingProgressSlider:
- progressSlider.value = MusicConductor.getCurrentSongProgressPercentage()
-
-func updateSongNameVisual():
- songSelectorButton.selected = MusicConductor.getCurrentSongIndex()
-
-func updatePlayPauseButtonVisual():
- playPauseButton.text = "||" if MusicConductor.isPaused() else ">"
-
-func _on_play_pause_button_pressed():
- MusicConductor.togglePlayPause()
- updatePlayPauseButtonVisual()
-
-func _on_next_song_button_pressed():
- MusicConductor.nextSong()
- updateSongNameVisual()
- updatePlayPauseButtonVisual()
-
-func _on_previous_song_button_pressed():
- MusicConductor.prevSong()
- updateSongNameVisual()
- updatePlayPauseButtonVisual()
-
-func _on_option_button_item_selected(index):
- # UIFUN-92
- MusicConductor.startSongByIndex(index)
-
-
-func _on_progress_slider_drag_started():
- isUserDraggingProgressSlider = true
-
-
-func _on_progress_slider_drag_ended(_value_changed):
- MusicConductor.scrubSongByPercentage(progressSlider.value)
- isUserDraggingProgressSlider = false
- updatePlayPauseButtonVisual()
-
-func _on_music_ui_visibility_button_pressed():
- isMusicPlayerVisible = !isMusicPlayerVisible
- widgetVisibilityButton.text = "Hide Player" if isMusicPlayerVisible else "Show Player"
- songSelectorButton.visible = isMusicPlayerVisible
- progressSlider.visible = isMusicPlayerVisible
- prevSongButton.visible = isMusicPlayerVisible
- playPauseButton.visible = isMusicPlayerVisible
- nextSongButton.visible = isMusicPlayerVisible
diff --git a/game/src/MusicConductor/MusicUIController.tscn b/game/src/MusicConductor/MusicUIController.tscn
deleted file mode 100644
index 49ea355..0000000
--- a/game/src/MusicConductor/MusicUIController.tscn
+++ /dev/null
@@ -1,64 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://dmnqyvl3qfq2e"]
-
-[ext_resource type="Script" path="res://src/MusicConductor/MusicUIController.gd" id="1_u4qbn"]
-
-[node name="MusicUIController" type="Control" node_paths=PackedStringArray("songSelectorButton", "progressSlider", "prevSongButton", "playPauseButton", "nextSongButton", "widgetVisibilityButton")]
-editor_description = "UI-104"
-layout_mode = 3
-anchor_right = 0.11
-anchor_bottom = 0.165
-offset_right = 0.199997
-offset_bottom = 0.199997
-grow_horizontal = 2
-grow_vertical = 2
-script = ExtResource("1_u4qbn")
-songSelectorButton = NodePath("VBoxContainer/SongSelectorButton")
-progressSlider = NodePath("VBoxContainer/ProgressSlider")
-prevSongButton = NodePath("VBoxContainer/HBoxContainer/PreviousSongButton")
-playPauseButton = NodePath("VBoxContainer/HBoxContainer/PlayPauseButton")
-nextSongButton = NodePath("VBoxContainer/HBoxContainer/NextSongButton")
-widgetVisibilityButton = NodePath("VBoxContainer/MusicUIVisibilityButton")
-
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
-layout_mode = 0
-offset_right = 40.0
-offset_bottom = 40.0
-
-[node name="SongSelectorButton" type="OptionButton" parent="VBoxContainer"]
-editor_description = "UI-107"
-layout_mode = 2
-
-[node name="ProgressSlider" type="HSlider" parent="VBoxContainer"]
-layout_mode = 2
-
-[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
-layout_mode = 2
-size_flags_horizontal = 4
-
-[node name="PreviousSongButton" type="Button" parent="VBoxContainer/HBoxContainer"]
-layout_mode = 2
-text = "Prev"
-
-[node name="PlayPauseButton" type="Button" parent="VBoxContainer/HBoxContainer"]
-custom_minimum_size = Vector2(30, 0)
-layout_mode = 2
-text = ">"
-
-[node name="NextSongButton" type="Button" parent="VBoxContainer/HBoxContainer"]
-layout_mode = 2
-text = "Next"
-
-[node name="MusicUIVisibilityButton" type="Button" parent="VBoxContainer"]
-editor_description = "UI-106"
-layout_mode = 2
-size_flags_horizontal = 4
-size_flags_vertical = 3
-text = "Hide Player"
-
-[connection signal="item_selected" from="VBoxContainer/SongSelectorButton" to="." method="_on_option_button_item_selected"]
-[connection signal="drag_ended" from="VBoxContainer/ProgressSlider" to="." method="_on_progress_slider_drag_ended"]
-[connection signal="drag_started" from="VBoxContainer/ProgressSlider" to="." method="_on_progress_slider_drag_started"]
-[connection signal="pressed" from="VBoxContainer/HBoxContainer/PreviousSongButton" to="." method="_on_previous_song_button_pressed"]
-[connection signal="pressed" from="VBoxContainer/HBoxContainer/PlayPauseButton" to="." method="_on_play_pause_button_pressed"]
-[connection signal="pressed" from="VBoxContainer/HBoxContainer/NextSongButton" to="." method="_on_next_song_button_pressed"]
-[connection signal="pressed" from="VBoxContainer/MusicUIVisibilityButton" to="." method="_on_music_ui_visibility_button_pressed"]
diff --git a/game/src/MusicConductor/SongInfo.gd b/game/src/MusicConductor/SongInfo.gd
index 85ef96a..f7343c0 100644
--- a/game/src/MusicConductor/SongInfo.gd
+++ b/game/src/MusicConductor/SongInfo.gd
@@ -1,11 +1,11 @@
extends Node
class_name SongInfo
-var fullyQualifiedPath : String = ""
-var readableName : String = ""
-var loadedStream : Resource
+var song_path : String = ""
+var song_name : String = ""
+var song_stream : Resource
func _init(dirname:String, fname:String):
- fullyQualifiedPath = dirname + fname
- readableName = fname.get_basename().replace("_", " ")
- loadedStream = load(fullyQualifiedPath)
+ song_path = dirname.path_join(fname)
+ song_name = fname.get_basename().replace("_", " ")
+ song_stream = load(song_path)
diff --git a/game/src/OptionMenu/AutosaveIntervalSelector.gd b/game/src/OptionMenu/AutosaveIntervalSelector.gd
new file mode 100644
index 0000000..2c55862
--- /dev/null
+++ b/game/src/OptionMenu/AutosaveIntervalSelector.gd
@@ -0,0 +1,2 @@
+extends SettingOptionButton
+
diff --git a/game/src/OptionMenu/GeneralTab.gd b/game/src/OptionMenu/GeneralTab.gd
new file mode 100644
index 0000000..8aed783
--- /dev/null
+++ b/game/src/OptionMenu/GeneralTab.gd
@@ -0,0 +1,8 @@
+extends HBoxContainer
+
+@export var initial_focus: Button
+
+func _notification(what : int) -> void:
+ match(what):
+ NOTIFICATION_VISIBILITY_CHANGED:
+ if visible: initial_focus.grab_focus()
diff --git a/game/src/OptionMenu/GeneralTab.tscn b/game/src/OptionMenu/GeneralTab.tscn
new file mode 100644
index 0000000..b38f548
--- /dev/null
+++ b/game/src/OptionMenu/GeneralTab.tscn
@@ -0,0 +1,82 @@
+[gd_scene load_steps=5 format=3 uid="uid://duwjal7sd7p6w"]
+
+[ext_resource type="Script" path="res://src/OptionMenu/GeneralTab.gd" id="1_gbutn"]
+[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="2_5cfd7"]
+[ext_resource type="Script" path="res://src/OptionMenu/SettingNodes/SettingOptionButton.gd" id="2_msx2u"]
+[ext_resource type="Script" path="res://src/OptionMenu/AutosaveIntervalSelector.gd" id="2_t06tb"]
+
+[node name="GeneralTab" type="HBoxContainer" node_paths=PackedStringArray("initial_focus")]
+editor_description = "UI-48"
+alignment = 1
+script = ExtResource("1_gbutn")
+initial_focus = NodePath("VBoxContainer/GridContainer/SavegameFormatSelector")
+
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+layout_mode = 2
+
+[node name="Control" type="Control" parent="VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.1
+
+[node name="GridContainer" type="GridContainer" parent="VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+columns = 2
+
+[node name="SavegameFormatLabel" type="Label" parent="VBoxContainer/GridContainer"]
+layout_mode = 2
+text = "Savegame Format"
+
+[node name="SavegameFormatSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
+editor_description = "UI-50"
+layout_mode = 2
+focus_neighbor_bottom = NodePath("../AutosaveIntervalSelector")
+item_count = 2
+selected = 0
+popup/item_0/text = "Binary"
+popup/item_0/id = 0
+popup/item_1/text = "Text"
+popup/item_1/id = 1
+script = ExtResource("2_msx2u")
+section_name = "General"
+setting_name = "Savegame Format"
+default_selected = 0
+
+[node name="AutosaveIntervalLabel" type="Label" parent="VBoxContainer/GridContainer"]
+layout_mode = 2
+text = "Autosave Interval"
+horizontal_alignment = 1
+
+[node name="AutosaveIntervalSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
+editor_description = "UI-15"
+layout_mode = 2
+focus_neighbor_top = NodePath("../SavegameFormatSelector")
+focus_neighbor_bottom = NodePath("../LocaleButton")
+item_count = 5
+selected = 0
+popup/item_0/text = "Monthly"
+popup/item_0/id = 0
+popup/item_1/text = "Bi-Monthly"
+popup/item_1/id = 1
+popup/item_2/text = "Bi-Yearly"
+popup/item_2/id = 2
+popup/item_3/text = "Yearly"
+popup/item_3/id = 3
+popup/item_4/text = "Never"
+popup/item_4/id = 4
+script = ExtResource("2_t06tb")
+section_name = "General"
+setting_name = "Autosave Interval"
+default_selected = 0
+
+[node name="LocaleLabel" type="Label" parent="VBoxContainer/GridContainer"]
+layout_mode = 2
+text = "Language"
+
+[node name="LocaleButton" parent="VBoxContainer/GridContainer" instance=ExtResource("2_5cfd7")]
+editor_description = "UI-79"
+layout_mode = 2
+focus_neighbor_top = NodePath("../AutosaveIntervalSelector")
+alignment = 0
+text_overrun_behavior = 4
diff --git a/game/src/OptionMenu/OptionsMenu.gd b/game/src/OptionMenu/OptionsMenu.gd
index e7ad7f6..d5f128c 100644
--- a/game/src/OptionMenu/OptionsMenu.gd
+++ b/game/src/OptionMenu/OptionsMenu.gd
@@ -31,7 +31,6 @@ func _ready():
back_button.text = "X"
back_button.pressed.connect(_on_back_button_pressed)
button_list.add_child(back_button)
-
get_viewport().get_window().close_requested.connect(_on_window_close_requested)
_save_overrides.call_deferred()
Events.Options.save_settings.connect(func(_f): self._save_overrides.call_deferred())
@@ -41,10 +40,10 @@ func _notification(what):
NOTIFICATION_CRASH:
_on_window_close_requested()
-# Could pass the LocaleButton between the MainMenu and OptionsMenu
-# but that seems a bit excessive
-func toggle_locale_button_visibility(locale_visible : bool):
- $LocaleVBox/LocaleHBox/LocaleButton.visible = locale_visible
+func _input(event):
+ if self.is_visible_in_tree():
+ if event.is_action_pressed("ui_cancel"):
+ _on_back_button_pressed()
func _on_back_button_pressed():
Events.Options.save_settings_to_file()
diff --git a/game/src/OptionMenu/OptionsMenu.tscn b/game/src/OptionMenu/OptionsMenu.tscn
index bdb80f1..1ff2022 100644
--- a/game/src/OptionMenu/OptionsMenu.tscn
+++ b/game/src/OptionMenu/OptionsMenu.tscn
@@ -1,43 +1,43 @@
-[gd_scene load_steps=7 format=3 uid="uid://cnbfxjy1m6wja"]
+[gd_scene load_steps=8 format=3 uid="uid://cnbfxjy1m6wja"]
[ext_resource type="Script" path="res://src/OptionMenu/OptionsMenu.gd" id="1_tlein"]
-[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="2_d7wvq"]
+[ext_resource type="Theme" uid="uid://cr4lh0vraucx7" path="res://default_theme.tres" id="2_8cfng"]
[ext_resource type="PackedScene" uid="uid://bq3awxxjn1tuw" path="res://src/OptionMenu/VideoTab.tscn" id="2_ji8xr"]
[ext_resource type="PackedScene" uid="uid://cbtgwpx2wxi33" path="res://src/OptionMenu/SoundTab.tscn" id="3_4w35t"]
+[ext_resource type="PackedScene" uid="uid://duwjal7sd7p6w" path="res://src/OptionMenu/GeneralTab.tscn" id="3_6gvf6"]
[ext_resource type="PackedScene" uid="uid://bq7ibhm0txl5p" path="res://addons/keychain/ShortcutEdit.tscn" id="4_vdhjp"]
[ext_resource type="PackedScene" uid="uid://dp2grvybtecqu" path="res://src/OptionMenu/OtherTab.tscn" id="5_ahefp"]
-[node name="OptionsMenu" type="Control"]
+[node name="OptionsMenu" type="PanelContainer"]
editor_description = "UI-25"
-layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
+theme = ExtResource("2_8cfng")
+theme_type_variation = &"Panel_MainMenu"
script = ExtResource("1_tlein")
[node name="Margin" type="MarginContainer" parent="."]
-layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-theme_override_constants/margin_left = 250
-theme_override_constants/margin_top = 100
-theme_override_constants/margin_right = 250
-theme_override_constants/margin_bottom = 200
+layout_mode = 2
+theme_override_constants/margin_left = 180
+theme_override_constants/margin_top = 150
+theme_override_constants/margin_right = 180
+theme_override_constants/margin_bottom = 150
[node name="Tab" type="TabContainer" parent="Margin"]
editor_description = "UI-45"
layout_mode = 2
-size_flags_vertical = 3
tab_alignment = 1
use_hidden_tabs_for_min_size = true
+[node name="General" parent="Margin/Tab" instance=ExtResource("3_6gvf6")]
+layout_mode = 2
+
[node name="Video" parent="Margin/Tab" instance=ExtResource("2_ji8xr")]
editor_description = "UI-46, UIFUN-43"
+visible = false
layout_mode = 2
[node name="Sound" parent="Margin/Tab" instance=ExtResource("3_4w35t")]
@@ -49,25 +49,7 @@ layout_mode = 2
editor_description = "SS-27, UI-49, UIFUN-46"
visible = false
layout_mode = 2
+alignment = 1
[node name="Other" parent="Margin/Tab" instance=ExtResource("5_ahefp")]
layout_mode = 2
-
-[node name="LocaleVBox" type="VBoxContainer" parent="."]
-layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-mouse_filter = 2
-alignment = 2
-
-[node name="LocaleHBox" type="HBoxContainer" parent="LocaleVBox"]
-layout_mode = 2
-mouse_filter = 2
-alignment = 2
-
-[node name="LocaleButton" parent="LocaleVBox/LocaleHBox" instance=ExtResource("2_d7wvq")]
-editor_description = "UI-79"
-layout_mode = 2
diff --git a/game/src/OptionMenu/QualityPresetSelector.gd b/game/src/OptionMenu/QualityPresetSelector.gd
new file mode 100644
index 0000000..57ba4ab
--- /dev/null
+++ b/game/src/OptionMenu/QualityPresetSelector.gd
@@ -0,0 +1,4 @@
+extends SettingOptionButton
+
+func _setup_button():
+ pass
diff --git a/game/src/OptionMenu/RefreshRateSelector.gd b/game/src/OptionMenu/RefreshRateSelector.gd
new file mode 100644
index 0000000..31b115b
--- /dev/null
+++ b/game/src/OptionMenu/RefreshRateSelector.gd
@@ -0,0 +1,5 @@
+extends SettingOptionButton
+
+
+func _setup_button():
+ pass
diff --git a/game/src/OptionMenu/VideoTab.gd b/game/src/OptionMenu/VideoTab.gd
new file mode 100644
index 0000000..8aed783
--- /dev/null
+++ b/game/src/OptionMenu/VideoTab.gd
@@ -0,0 +1,8 @@
+extends HBoxContainer
+
+@export var initial_focus: Button
+
+func _notification(what : int) -> void:
+ match(what):
+ NOTIFICATION_VISIBILITY_CHANGED:
+ if visible: initial_focus.grab_focus()
diff --git a/game/src/OptionMenu/VideoTab.tscn b/game/src/OptionMenu/VideoTab.tscn
index 245d15d..c060b19 100644
--- a/game/src/OptionMenu/VideoTab.tscn
+++ b/game/src/OptionMenu/VideoTab.tscn
@@ -1,12 +1,18 @@
-[gd_scene load_steps=4 format=3 uid="uid://bq3awxxjn1tuw"]
+[gd_scene load_steps=7 format=3 uid="uid://bq3awxxjn1tuw"]
[ext_resource type="Script" path="res://src/OptionMenu/ResolutionSelector.gd" id="1_i8nro"]
+[ext_resource type="Script" path="res://src/OptionMenu/VideoTab.gd" id="1_jvv62"]
[ext_resource type="Script" path="res://src/OptionMenu/ScreenModeSelector.gd" id="2_wa7vw"]
[ext_resource type="Script" path="res://src/OptionMenu/MonitorDisplaySelector.gd" id="3_y6lyb"]
+[ext_resource type="Script" path="res://src/OptionMenu/RefreshRateSelector.gd" id="4_381mg"]
+[ext_resource type="Script" path="res://src/OptionMenu/QualityPresetSelector.gd" id="5_srg4v"]
-[node name="Video" type="HBoxContainer"]
+[node name="Video" type="HBoxContainer" node_paths=PackedStringArray("initial_focus")]
+editor_description = "UI-46"
tooltip_text = "This is my cool and very nice tooltip"
alignment = 1
+script = ExtResource("1_jvv62")
+initial_focus = NodePath("VBoxContainer/GridContainer/ResolutionSelector")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
@@ -28,6 +34,7 @@ text = "Resolution"
[node name="ResolutionSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
editor_description = "UI-19"
layout_mode = 2
+focus_neighbor_bottom = NodePath("../ScreenModeSelector")
item_count = 1
selected = 0
popup/item_0/text = "MISSING"
@@ -43,6 +50,8 @@ text = "Screen Mode"
[node name="ScreenModeSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
layout_mode = 2
+focus_neighbor_top = NodePath("../ResolutionSelector")
+focus_neighbor_bottom = NodePath("../MonitorDisplaySelector")
item_count = 3
selected = 0
popup/item_0/text = "Fullscreen"
@@ -61,6 +70,8 @@ text = "Monitor Selection"
[node name="MonitorDisplaySelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
layout_mode = 2
+focus_neighbor_top = NodePath("../ScreenModeSelector")
+focus_neighbor_bottom = NodePath("../RefreshRateSelector")
item_count = 1
selected = 0
popup/item_0/text = "MISSING"
@@ -69,6 +80,64 @@ script = ExtResource("3_y6lyb")
section_name = "Video"
setting_name = "Current Screen"
+[node name="RefreshRateLabel" type="Label" parent="VBoxContainer/GridContainer"]
+layout_mode = 2
+text = "Refresh Rate"
+
+[node name="RefreshRateSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
+editor_description = "UI-18"
+layout_mode = 2
+tooltip_text = "Only change from VSYNC if you are having issues with screen tearing."
+focus_neighbor_top = NodePath("../MonitorDisplaySelector")
+focus_neighbor_bottom = NodePath("../QualityPresetSelector")
+item_count = 8
+selected = 0
+popup/item_0/text = "VSYNC"
+popup/item_0/id = 0
+popup/item_1/text = "30hz"
+popup/item_1/id = 1
+popup/item_2/text = "60hz"
+popup/item_2/id = 2
+popup/item_3/text = "90hz"
+popup/item_3/id = 3
+popup/item_4/text = "120hz"
+popup/item_4/id = 4
+popup/item_5/text = "144hz"
+popup/item_5/id = 5
+popup/item_6/text = "365hz"
+popup/item_6/id = 6
+popup/item_7/text = "Unlimited"
+popup/item_7/id = 7
+script = ExtResource("4_381mg")
+section_name = "Video"
+setting_name = "Refresh Rate"
+default_selected = 0
+
+[node name="QualityPresetLabel" type="Label" parent="VBoxContainer/GridContainer"]
+layout_mode = 2
+text = "Quality Preset"
+
+[node name="QualityPresetSelector" type="OptionButton" parent="VBoxContainer/GridContainer"]
+editor_description = "UI-21"
+layout_mode = 2
+focus_neighbor_top = NodePath("../RefreshRateSelector")
+item_count = 5
+selected = 1
+popup/item_0/text = "Low"
+popup/item_0/id = 0
+popup/item_1/text = "Medium"
+popup/item_1/id = 1
+popup/item_2/text = "High"
+popup/item_2/id = 2
+popup/item_3/text = "Ultra"
+popup/item_3/id = 3
+popup/item_4/text = "Custom"
+popup/item_4/id = 4
+script = ExtResource("5_srg4v")
+section_name = "Video"
+setting_name = "Quality Preset"
+default_selected = 1
+
[connection signal="item_selected" from="VBoxContainer/GridContainer/ResolutionSelector" to="VBoxContainer/GridContainer/ResolutionSelector" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/GridContainer/ScreenModeSelector" to="VBoxContainer/GridContainer/ScreenModeSelector" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/GridContainer/MonitorDisplaySelector" to="VBoxContainer/GridContainer/MonitorDisplaySelector" method="_on_item_selected"]
diff --git a/game/src/SplashContainer.gd b/game/src/SplashContainer.gd
new file mode 100644
index 0000000..524d314
--- /dev/null
+++ b/game/src/SplashContainer.gd
@@ -0,0 +1,30 @@
+extends Control
+
+signal splash_end
+
+@export var _splash_finish : TextureRect
+@export var _splash_image : TextureRect
+@export var _splash_video : VideoStreamPlayer
+
+func _process(_delta):
+ var stream_texture := _splash_video.get_video_texture()
+ if stream_texture != null and not stream_texture.get_image().is_invisible():
+ _splash_image.hide()
+ _splash_finish.show()
+ set_process(false)
+
+func _input(event):
+ if (event is InputEventKey\
+ or event is InputEventMouse\
+ or event is InputEventScreenTouch\
+ or event is InputEventJoypadButton) and event.is_pressed():
+ _splash_finish.hide()
+ _on_splash_startup_finished()
+ accept_event()
+
+func _on_splash_startup_finished():
+ set_process_input(false)
+ splash_end.emit()
+ var tween := create_tween()
+ tween.tween_property(self, "modulate:a", 0, 0.5)
+ tween.tween_callback(self.queue_free)