Recommiting glbs for LFS
Deploy Promiscuity Auth API / deploy (push) Successful in 1m59s
Deploy Promiscuity Character API / deploy (push) Successful in 1m16s
Deploy Promiscuity Inventory API / deploy (push) Has been cancelled
Deploy Promiscuity Locations API / deploy (push) Has been cancelled
Deploy Promiscuity Mail API / deploy (push) Has been cancelled
Deploy Promiscuity World API / deploy (push) Has been cancelled
Deploy Promiscuity Crafting API / deploy (push) Has been cancelled
k8s smoke test / test (push) Has been cancelled
Deploy Promiscuity Auth API / deploy (push) Successful in 1m59s
Deploy Promiscuity Character API / deploy (push) Successful in 1m16s
Deploy Promiscuity Inventory API / deploy (push) Has been cancelled
Deploy Promiscuity Locations API / deploy (push) Has been cancelled
Deploy Promiscuity Mail API / deploy (push) Has been cancelled
Deploy Promiscuity World API / deploy (push) Has been cancelled
Deploy Promiscuity Crafting API / deploy (push) Has been cancelled
k8s smoke test / test (push) Has been cancelled
This commit is contained in:
+112
-112
@@ -1,112 +1,112 @@
|
||||
extends Node2D
|
||||
|
||||
@onready var _tab_bar: TabBar = $MarginContainer/VBoxContainer/TabBar
|
||||
@onready var _tab_container: TabContainer = $MarginContainer/VBoxContainer/TabContainer
|
||||
@onready var _music_volume_slider: HSlider = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicVolumeSlider
|
||||
@onready var _music_volume_value: Label = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicVolumeValue
|
||||
@onready var _music_mute_checkbox: CheckBox = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicMuteCheckBox
|
||||
@onready var _sfx_volume_slider: HSlider = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxVolumeSlider
|
||||
@onready var _sfx_volume_value: Label = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxVolumeValue
|
||||
@onready var _sfx_mute_checkbox: CheckBox = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxMuteCheckBox
|
||||
@onready var _menu_music: AudioStreamPlayer = get_tree().get_root().get_node_or_null("MenuMusic")
|
||||
@onready var _menu_sfx: AudioStreamPlayer = get_tree().get_root().get_node_or_null("MenuSfx")
|
||||
|
||||
func _ready() -> void:
|
||||
_tab_bar.tab_changed.connect(_on_tab_bar_tab_changed)
|
||||
_tab_container.tab_changed.connect(_on_tab_container_tab_changed)
|
||||
_tab_container.current_tab = _tab_bar.current_tab
|
||||
_music_volume_slider.value_changed.connect(_on_music_volume_changed)
|
||||
_music_mute_checkbox.toggled.connect(_on_music_mute_toggled)
|
||||
_sfx_volume_slider.value_changed.connect(_on_sfx_volume_changed)
|
||||
_sfx_mute_checkbox.toggled.connect(_on_sfx_mute_toggled)
|
||||
_sync_audio_controls()
|
||||
_register_focus_sounds()
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
get_tree().change_scene_to_file("uid://b4k81taauef4q")
|
||||
|
||||
func _on_tab_bar_tab_changed(tab_index: int) -> void:
|
||||
if _tab_container.current_tab != tab_index:
|
||||
_tab_container.current_tab = tab_index
|
||||
|
||||
func _on_tab_container_tab_changed(tab_index: int) -> void:
|
||||
if _tab_bar.current_tab != tab_index:
|
||||
_tab_bar.current_tab = tab_index
|
||||
|
||||
func _sync_audio_controls() -> void:
|
||||
var value: float = 0.7
|
||||
var muted: bool = false
|
||||
if _menu_music:
|
||||
if _menu_music.has_method("get_user_volume"):
|
||||
value = _menu_music.get_user_volume()
|
||||
if _menu_music.has_method("is_user_muted"):
|
||||
muted = _menu_music.is_user_muted()
|
||||
_apply_audio_control_state(_music_volume_slider, _music_mute_checkbox, _music_volume_value, value, muted)
|
||||
|
||||
var sfx_value: float = 0.7
|
||||
var sfx_muted: bool = false
|
||||
if _menu_sfx:
|
||||
if _menu_sfx.has_method("get_user_volume"):
|
||||
sfx_value = _menu_sfx.get_user_volume()
|
||||
if _menu_sfx.has_method("is_user_muted"):
|
||||
sfx_muted = _menu_sfx.is_user_muted()
|
||||
_apply_audio_control_state(_sfx_volume_slider, _sfx_mute_checkbox, _sfx_volume_value, sfx_value, sfx_muted)
|
||||
|
||||
func _on_music_volume_changed(value: float) -> void:
|
||||
if _menu_music and _menu_music.has_method("set_user_volume"):
|
||||
_menu_music.set_user_volume(value)
|
||||
_update_volume_label(_music_volume_value, value, _music_mute_checkbox.button_pressed)
|
||||
|
||||
func _on_music_mute_toggled(pressed: bool) -> void:
|
||||
if _menu_music and _menu_music.has_method("set_user_muted"):
|
||||
_menu_music.set_user_muted(pressed)
|
||||
_music_volume_slider.editable = not pressed
|
||||
_update_volume_label(_music_volume_value, _music_volume_slider.value, pressed)
|
||||
|
||||
func _on_sfx_volume_changed(value: float) -> void:
|
||||
if _menu_sfx and _menu_sfx.has_method("set_user_volume"):
|
||||
_menu_sfx.set_user_volume(value)
|
||||
_update_volume_label(_sfx_volume_value, value, _sfx_mute_checkbox.button_pressed)
|
||||
|
||||
func _on_sfx_mute_toggled(pressed: bool) -> void:
|
||||
if _menu_sfx and _menu_sfx.has_method("set_user_muted"):
|
||||
_menu_sfx.set_user_muted(pressed)
|
||||
_sfx_volume_slider.editable = not pressed
|
||||
_update_volume_label(_sfx_volume_value, _sfx_volume_slider.value, pressed)
|
||||
|
||||
func _apply_audio_control_state(slider: HSlider, checkbox: CheckBox, value_label: Label, value: float, muted: bool) -> void:
|
||||
slider.set_block_signals(true)
|
||||
slider.value = value
|
||||
slider.set_block_signals(false)
|
||||
slider.editable = not muted
|
||||
checkbox.set_block_signals(true)
|
||||
checkbox.button_pressed = muted
|
||||
checkbox.set_block_signals(false)
|
||||
_update_volume_label(value_label, value, muted)
|
||||
|
||||
func _update_volume_label(value_label: Label, value: float, muted: bool) -> void:
|
||||
if muted:
|
||||
value_label.text = "Muted"
|
||||
else:
|
||||
var percent: int = int(round(value * 100.0))
|
||||
value_label.text = str(percent) + "%"
|
||||
|
||||
func _register_focus_sounds() -> void:
|
||||
_connect_focus_recursive(self)
|
||||
|
||||
func _connect_focus_recursive(node: Node) -> void:
|
||||
if node is Control:
|
||||
var control: Control = node
|
||||
if control.focus_mode != Control.FOCUS_NONE:
|
||||
if not control.is_connected("focus_entered", Callable(self, "_on_menu_item_focus")):
|
||||
control.focus_entered.connect(_on_menu_item_focus)
|
||||
if control.has_signal("mouse_entered") and (control is BaseButton or control.focus_mode != Control.FOCUS_NONE):
|
||||
if not control.is_connected("mouse_entered", Callable(self, "_on_menu_item_focus")):
|
||||
control.mouse_entered.connect(_on_menu_item_focus)
|
||||
for child in node.get_children():
|
||||
_connect_focus_recursive(child)
|
||||
|
||||
func _on_menu_item_focus() -> void:
|
||||
if MenuSfx:
|
||||
MenuSfx.play_hover()
|
||||
extends Node2D
|
||||
|
||||
@onready var _tab_bar: TabBar = $MarginContainer/VBoxContainer/TabBar
|
||||
@onready var _tab_container: TabContainer = $MarginContainer/VBoxContainer/TabContainer
|
||||
@onready var _music_volume_slider: HSlider = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicVolumeSlider
|
||||
@onready var _music_volume_value: Label = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicVolumeValue
|
||||
@onready var _music_mute_checkbox: CheckBox = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup/MusicMuteCheckBox
|
||||
@onready var _sfx_volume_slider: HSlider = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxVolumeSlider
|
||||
@onready var _sfx_volume_value: Label = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxVolumeValue
|
||||
@onready var _sfx_mute_checkbox: CheckBox = $MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup/SfxMuteCheckBox
|
||||
@onready var _menu_music: AudioStreamPlayer = get_tree().get_root().get_node_or_null("MenuMusic")
|
||||
@onready var _menu_sfx: AudioStreamPlayer = get_tree().get_root().get_node_or_null("MenuSfx")
|
||||
|
||||
func _ready() -> void:
|
||||
_tab_bar.tab_changed.connect(_on_tab_bar_tab_changed)
|
||||
_tab_container.tab_changed.connect(_on_tab_container_tab_changed)
|
||||
_tab_container.current_tab = _tab_bar.current_tab
|
||||
_music_volume_slider.value_changed.connect(_on_music_volume_changed)
|
||||
_music_mute_checkbox.toggled.connect(_on_music_mute_toggled)
|
||||
_sfx_volume_slider.value_changed.connect(_on_sfx_volume_changed)
|
||||
_sfx_mute_checkbox.toggled.connect(_on_sfx_mute_toggled)
|
||||
_sync_audio_controls()
|
||||
_register_focus_sounds()
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
get_tree().change_scene_to_file("uid://b4k81taauef4q")
|
||||
|
||||
func _on_tab_bar_tab_changed(tab_index: int) -> void:
|
||||
if _tab_container.current_tab != tab_index:
|
||||
_tab_container.current_tab = tab_index
|
||||
|
||||
func _on_tab_container_tab_changed(tab_index: int) -> void:
|
||||
if _tab_bar.current_tab != tab_index:
|
||||
_tab_bar.current_tab = tab_index
|
||||
|
||||
func _sync_audio_controls() -> void:
|
||||
var value: float = 0.7
|
||||
var muted: bool = false
|
||||
if _menu_music:
|
||||
if _menu_music.has_method("get_user_volume"):
|
||||
value = _menu_music.get_user_volume()
|
||||
if _menu_music.has_method("is_user_muted"):
|
||||
muted = _menu_music.is_user_muted()
|
||||
_apply_audio_control_state(_music_volume_slider, _music_mute_checkbox, _music_volume_value, value, muted)
|
||||
|
||||
var sfx_value: float = 0.7
|
||||
var sfx_muted: bool = false
|
||||
if _menu_sfx:
|
||||
if _menu_sfx.has_method("get_user_volume"):
|
||||
sfx_value = _menu_sfx.get_user_volume()
|
||||
if _menu_sfx.has_method("is_user_muted"):
|
||||
sfx_muted = _menu_sfx.is_user_muted()
|
||||
_apply_audio_control_state(_sfx_volume_slider, _sfx_mute_checkbox, _sfx_volume_value, sfx_value, sfx_muted)
|
||||
|
||||
func _on_music_volume_changed(value: float) -> void:
|
||||
if _menu_music and _menu_music.has_method("set_user_volume"):
|
||||
_menu_music.set_user_volume(value)
|
||||
_update_volume_label(_music_volume_value, value, _music_mute_checkbox.button_pressed)
|
||||
|
||||
func _on_music_mute_toggled(pressed: bool) -> void:
|
||||
if _menu_music and _menu_music.has_method("set_user_muted"):
|
||||
_menu_music.set_user_muted(pressed)
|
||||
_music_volume_slider.editable = not pressed
|
||||
_update_volume_label(_music_volume_value, _music_volume_slider.value, pressed)
|
||||
|
||||
func _on_sfx_volume_changed(value: float) -> void:
|
||||
if _menu_sfx and _menu_sfx.has_method("set_user_volume"):
|
||||
_menu_sfx.set_user_volume(value)
|
||||
_update_volume_label(_sfx_volume_value, value, _sfx_mute_checkbox.button_pressed)
|
||||
|
||||
func _on_sfx_mute_toggled(pressed: bool) -> void:
|
||||
if _menu_sfx and _menu_sfx.has_method("set_user_muted"):
|
||||
_menu_sfx.set_user_muted(pressed)
|
||||
_sfx_volume_slider.editable = not pressed
|
||||
_update_volume_label(_sfx_volume_value, _sfx_volume_slider.value, pressed)
|
||||
|
||||
func _apply_audio_control_state(slider: HSlider, checkbox: CheckBox, value_label: Label, value: float, muted: bool) -> void:
|
||||
slider.set_block_signals(true)
|
||||
slider.value = value
|
||||
slider.set_block_signals(false)
|
||||
slider.editable = not muted
|
||||
checkbox.set_block_signals(true)
|
||||
checkbox.button_pressed = muted
|
||||
checkbox.set_block_signals(false)
|
||||
_update_volume_label(value_label, value, muted)
|
||||
|
||||
func _update_volume_label(value_label: Label, value: float, muted: bool) -> void:
|
||||
if muted:
|
||||
value_label.text = "Muted"
|
||||
else:
|
||||
var percent: int = int(round(value * 100.0))
|
||||
value_label.text = str(percent) + "%"
|
||||
|
||||
func _register_focus_sounds() -> void:
|
||||
_connect_focus_recursive(self)
|
||||
|
||||
func _connect_focus_recursive(node: Node) -> void:
|
||||
if node is Control:
|
||||
var control: Control = node
|
||||
if control.focus_mode != Control.FOCUS_NONE:
|
||||
if not control.is_connected("focus_entered", Callable(self, "_on_menu_item_focus")):
|
||||
control.focus_entered.connect(_on_menu_item_focus)
|
||||
if control.has_signal("mouse_entered") and (control is BaseButton or control.focus_mode != Control.FOCUS_NONE):
|
||||
if not control.is_connected("mouse_entered", Callable(self, "_on_menu_item_focus")):
|
||||
control.mouse_entered.connect(_on_menu_item_focus)
|
||||
for child in node.get_children():
|
||||
_connect_focus_recursive(child)
|
||||
|
||||
func _on_menu_item_focus() -> void:
|
||||
if MenuSfx:
|
||||
MenuSfx.play_hover()
|
||||
|
||||
+157
-157
@@ -1,157 +1,157 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://d3tqrm4ry4l88"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://h1slqbemgwvr" path="res://scenes/UI/Settings.gd" id="1_1dggd"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="1_i47rn"]
|
||||
[ext_resource type="FontFile" uid="uid://m5ceou0rk6j6" path="res://assets/fonts/PlayfairDisplay-VariableFont_wght.ttf" id="2_46duy"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="3_46duy"]
|
||||
|
||||
|
||||
[node name="settings_screen" type="Node2D"]
|
||||
script = ExtResource("1_1dggd")
|
||||
metadata/_edit_vertical_guides_ = [1152.0]
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
offset_left = -192.0
|
||||
offset_top = -188.0
|
||||
offset_right = 1344.0
|
||||
offset_bottom = 836.0
|
||||
texture = ExtResource("1_i47rn")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 648.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_46duy")
|
||||
theme_override_font_sizes/font_size = 42
|
||||
text = "Settings"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="TabBar" type="TabBar" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_46duy")
|
||||
current_tab = 0
|
||||
tab_count = 4
|
||||
tab_0/title = "Gameplay"
|
||||
tab_1/title = "Video"
|
||||
tab_2/title = "Audio"
|
||||
tab_3/title = "Dev"
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
tabs_visible = false
|
||||
|
||||
[node name="Gameplay" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Video" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Audio" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="AudioVBox" type="VBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/separation = 10
|
||||
offset_left = 120.0
|
||||
offset_top = 240.0
|
||||
offset_right = -120.0
|
||||
offset_bottom = -40.0
|
||||
|
||||
[node name="MusicVolumeLabel" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
text = "Music Volume"
|
||||
horizontal_alignment = 1
|
||||
size_flags_horizontal = 4
|
||||
|
||||
[node name="MusicVolumeGroup" type="HBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
alignment = 1
|
||||
custom_minimum_size = Vector2(0, 40)
|
||||
|
||||
[node name="MusicVolumeSlider" type="HSlider" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
min_value = 0.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
size_flags_horizontal = 3
|
||||
custom_minimum_size = Vector2(320, 0)
|
||||
|
||||
[node name="MusicVolumeValue" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "70%"
|
||||
size_flags_horizontal = 1
|
||||
horizontal_alignment = 1
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
|
||||
[node name="MusicMuteCheckBox" type="CheckBox" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "Mute"
|
||||
size_flags_horizontal = 1
|
||||
|
||||
[node name="SfxVolumeLabel" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
text = "Menu SFX Volume"
|
||||
horizontal_alignment = 1
|
||||
size_flags_horizontal = 4
|
||||
|
||||
[node name="SfxVolumeGroup" type="HBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
alignment = 1
|
||||
custom_minimum_size = Vector2(0, 40)
|
||||
|
||||
[node name="SfxVolumeSlider" type="HSlider" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
min_value = 0.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
size_flags_horizontal = 3
|
||||
custom_minimum_size = Vector2(320, 0)
|
||||
|
||||
[node name="SfxVolumeValue" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "70%"
|
||||
size_flags_horizontal = 1
|
||||
horizontal_alignment = 1
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
|
||||
[node name="SfxMuteCheckBox" type="CheckBox" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "Mute"
|
||||
size_flags_horizontal = 1
|
||||
|
||||
[node name="Dev" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
[gd_scene load_steps=5 format=3 uid="uid://d3tqrm4ry4l88"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://h1slqbemgwvr" path="res://scenes/UI/Settings.gd" id="1_1dggd"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="1_i47rn"]
|
||||
[ext_resource type="FontFile" uid="uid://m5ceou0rk6j6" path="res://assets/fonts/PlayfairDisplay-VariableFont_wght.ttf" id="2_46duy"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="3_46duy"]
|
||||
|
||||
|
||||
[node name="settings_screen" type="Node2D"]
|
||||
script = ExtResource("1_1dggd")
|
||||
metadata/_edit_vertical_guides_ = [1152.0]
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
offset_left = -192.0
|
||||
offset_top = -188.0
|
||||
offset_right = 1344.0
|
||||
offset_bottom = 836.0
|
||||
texture = ExtResource("1_i47rn")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 648.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_46duy")
|
||||
theme_override_font_sizes/font_size = 42
|
||||
text = "Settings"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="TabBar" type="TabBar" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_46duy")
|
||||
current_tab = 0
|
||||
tab_count = 4
|
||||
tab_0/title = "Gameplay"
|
||||
tab_1/title = "Video"
|
||||
tab_2/title = "Audio"
|
||||
tab_3/title = "Dev"
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
tabs_visible = false
|
||||
|
||||
[node name="Gameplay" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Video" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Audio" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="AudioVBox" type="VBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/separation = 10
|
||||
offset_left = 120.0
|
||||
offset_top = 240.0
|
||||
offset_right = -120.0
|
||||
offset_bottom = -40.0
|
||||
|
||||
[node name="MusicVolumeLabel" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
text = "Music Volume"
|
||||
horizontal_alignment = 1
|
||||
size_flags_horizontal = 4
|
||||
|
||||
[node name="MusicVolumeGroup" type="HBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
alignment = 1
|
||||
custom_minimum_size = Vector2(0, 40)
|
||||
|
||||
[node name="MusicVolumeSlider" type="HSlider" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
min_value = 0.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
size_flags_horizontal = 3
|
||||
custom_minimum_size = Vector2(320, 0)
|
||||
|
||||
[node name="MusicVolumeValue" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "70%"
|
||||
size_flags_horizontal = 1
|
||||
horizontal_alignment = 1
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
|
||||
[node name="MusicMuteCheckBox" type="CheckBox" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/MusicVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "Mute"
|
||||
size_flags_horizontal = 1
|
||||
|
||||
[node name="SfxVolumeLabel" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
text = "Menu SFX Volume"
|
||||
horizontal_alignment = 1
|
||||
size_flags_horizontal = 4
|
||||
|
||||
[node name="SfxVolumeGroup" type="HBoxContainer" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
alignment = 1
|
||||
custom_minimum_size = Vector2(0, 40)
|
||||
|
||||
[node name="SfxVolumeSlider" type="HSlider" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
min_value = 0.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
size_flags_horizontal = 3
|
||||
custom_minimum_size = Vector2(320, 0)
|
||||
|
||||
[node name="SfxVolumeValue" type="Label" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "70%"
|
||||
size_flags_horizontal = 1
|
||||
horizontal_alignment = 1
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
|
||||
[node name="SfxMuteCheckBox" type="CheckBox" parent="MarginContainer/VBoxContainer/TabContainer/Audio/AudioVBox/SfxVolumeGroup"]
|
||||
layout_mode = 2
|
||||
text = "Mute"
|
||||
size_flags_horizontal = 1
|
||||
|
||||
[node name="Dev" type="Control" parent="MarginContainer/VBoxContainer/TabContainer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
extends Node
|
||||
|
||||
var is_logged_in: bool = false
|
||||
var access_token: String = ""
|
||||
var username: String = ""
|
||||
|
||||
func set_session(new_username: String, token: String) -> void:
|
||||
is_logged_in = true
|
||||
username = new_username
|
||||
access_token = token
|
||||
|
||||
func clear_session() -> void:
|
||||
is_logged_in = false
|
||||
username = ""
|
||||
access_token = ""
|
||||
extends Node
|
||||
|
||||
var is_logged_in: bool = false
|
||||
var access_token: String = ""
|
||||
var username: String = ""
|
||||
|
||||
func set_session(new_username: String, token: String) -> void:
|
||||
is_logged_in = true
|
||||
username = new_username
|
||||
access_token = token
|
||||
|
||||
func clear_session() -> void:
|
||||
is_logged_in = false
|
||||
username = ""
|
||||
access_token = ""
|
||||
|
||||
+122
-122
@@ -1,99 +1,99 @@
|
||||
extends Control
|
||||
|
||||
const AUTH_LOGOUT_URL := "https://pauth.ranaze.com/api/Auth/logout"
|
||||
|
||||
@onready var _status_label: Label = %StatusLabel
|
||||
@onready var _character_list: ItemList = %CharacterList
|
||||
@onready var _name_input: LineEdit = %NameInput
|
||||
@onready var _logout_request: HTTPRequest = %LogoutRequest
|
||||
|
||||
var _characters: Array = []
|
||||
|
||||
func _ready() -> void:
|
||||
if not AuthState.is_logged_in:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
return
|
||||
_load_characters()
|
||||
|
||||
func _log_failure(action: String, response: Dictionary) -> void:
|
||||
push_warning("%s failed: status=%s error=%s body=%s" % [
|
||||
action,
|
||||
response.get("status", "n/a"),
|
||||
response.get("error", ""),
|
||||
response.get("body", "")
|
||||
])
|
||||
|
||||
func _load_characters() -> void:
|
||||
_status_label.text = "Loading characters..."
|
||||
var response := await CharacterService.list_characters()
|
||||
if not response.get("ok", false):
|
||||
_log_failure("List characters", response)
|
||||
_status_label.text = "Failed to load characters."
|
||||
return
|
||||
|
||||
var parsed: Variant = JSON.parse_string(String(response.get("body", "")))
|
||||
if typeof(parsed) != TYPE_ARRAY:
|
||||
_status_label.text = "Unexpected character response."
|
||||
return
|
||||
|
||||
_characters = parsed
|
||||
_character_list.clear()
|
||||
for character in _characters:
|
||||
var character_name := String(character.get("name", "Unnamed"))
|
||||
_character_list.add_item(character_name)
|
||||
|
||||
if _characters.is_empty():
|
||||
_status_label.text = "No characters yet. Add one below."
|
||||
else:
|
||||
_status_label.text = ""
|
||||
|
||||
func _on_add_button_pressed() -> void:
|
||||
var character_name := _name_input.text.strip_edges()
|
||||
if character_name.is_empty():
|
||||
_status_label.text = "Enter a character name first."
|
||||
return
|
||||
|
||||
_status_label.text = "Creating character..."
|
||||
var response := await CharacterService.create_character(character_name)
|
||||
if not response.get("ok", false):
|
||||
_log_failure("Create character", response)
|
||||
_status_label.text = "Failed to create character."
|
||||
return
|
||||
|
||||
var parsed: Variant = JSON.parse_string(String(response.get("body", "")))
|
||||
if typeof(parsed) == TYPE_DICTIONARY:
|
||||
_characters.append(parsed)
|
||||
_character_list.add_item(String(parsed.get("name", character_name)))
|
||||
_name_input.text = ""
|
||||
_status_label.text = "Character added."
|
||||
else:
|
||||
_status_label.text = "Character created, but response was unexpected."
|
||||
|
||||
extends Control
|
||||
|
||||
const AUTH_LOGOUT_URL := "https://pauth.ranaze.com/api/Auth/logout"
|
||||
|
||||
@onready var _status_label: Label = %StatusLabel
|
||||
@onready var _character_list: ItemList = %CharacterList
|
||||
@onready var _name_input: LineEdit = %NameInput
|
||||
@onready var _logout_request: HTTPRequest = %LogoutRequest
|
||||
|
||||
var _characters: Array = []
|
||||
|
||||
func _ready() -> void:
|
||||
if not AuthState.is_logged_in:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
return
|
||||
_load_characters()
|
||||
|
||||
func _log_failure(action: String, response: Dictionary) -> void:
|
||||
push_warning("%s failed: status=%s error=%s body=%s" % [
|
||||
action,
|
||||
response.get("status", "n/a"),
|
||||
response.get("error", ""),
|
||||
response.get("body", "")
|
||||
])
|
||||
|
||||
func _load_characters() -> void:
|
||||
_status_label.text = "Loading characters..."
|
||||
var response := await CharacterService.list_characters()
|
||||
if not response.get("ok", false):
|
||||
_log_failure("List characters", response)
|
||||
_status_label.text = "Failed to load characters."
|
||||
return
|
||||
|
||||
var parsed: Variant = JSON.parse_string(String(response.get("body", "")))
|
||||
if typeof(parsed) != TYPE_ARRAY:
|
||||
_status_label.text = "Unexpected character response."
|
||||
return
|
||||
|
||||
_characters = parsed
|
||||
_character_list.clear()
|
||||
for character in _characters:
|
||||
var character_name := String(character.get("name", "Unnamed"))
|
||||
_character_list.add_item(character_name)
|
||||
|
||||
if _characters.is_empty():
|
||||
_status_label.text = "No characters yet. Add one below."
|
||||
else:
|
||||
_status_label.text = ""
|
||||
|
||||
func _on_add_button_pressed() -> void:
|
||||
var character_name := _name_input.text.strip_edges()
|
||||
if character_name.is_empty():
|
||||
_status_label.text = "Enter a character name first."
|
||||
return
|
||||
|
||||
_status_label.text = "Creating character..."
|
||||
var response := await CharacterService.create_character(character_name)
|
||||
if not response.get("ok", false):
|
||||
_log_failure("Create character", response)
|
||||
_status_label.text = "Failed to create character."
|
||||
return
|
||||
|
||||
var parsed: Variant = JSON.parse_string(String(response.get("body", "")))
|
||||
if typeof(parsed) == TYPE_DICTIONARY:
|
||||
_characters.append(parsed)
|
||||
_character_list.add_item(String(parsed.get("name", character_name)))
|
||||
_name_input.text = ""
|
||||
_status_label.text = "Character added."
|
||||
else:
|
||||
_status_label.text = "Character created, but response was unexpected."
|
||||
|
||||
func _on_delete_button_pressed() -> void:
|
||||
var selected := _character_list.get_selected_items()
|
||||
if selected.is_empty():
|
||||
_status_label.text = "Select a character to delete."
|
||||
return
|
||||
|
||||
var index := selected[0]
|
||||
if index < 0 or index >= _characters.size():
|
||||
_status_label.text = "Invalid selection."
|
||||
return
|
||||
|
||||
var character: Dictionary = _characters[index]
|
||||
var character_id := String(character.get("id", character.get("Id", "")))
|
||||
if character_id.is_empty():
|
||||
_status_label.text = "Missing character id."
|
||||
return
|
||||
|
||||
_status_label.text = "Deleting character..."
|
||||
var response := await CharacterService.delete_character(character_id)
|
||||
if not response.get("ok", false):
|
||||
_log_failure("Delete character", response)
|
||||
_status_label.text = "Failed to delete character."
|
||||
return
|
||||
|
||||
_characters.remove_at(index)
|
||||
|
||||
var index := selected[0]
|
||||
if index < 0 or index >= _characters.size():
|
||||
_status_label.text = "Invalid selection."
|
||||
return
|
||||
|
||||
var character: Dictionary = _characters[index]
|
||||
var character_id := String(character.get("id", character.get("Id", "")))
|
||||
if character_id.is_empty():
|
||||
_status_label.text = "Missing character id."
|
||||
return
|
||||
|
||||
_status_label.text = "Deleting character..."
|
||||
var response := await CharacterService.delete_character(character_id)
|
||||
if not response.get("ok", false):
|
||||
_log_failure("Delete character", response)
|
||||
_status_label.text = "Failed to delete character."
|
||||
return
|
||||
|
||||
_characters.remove_at(index)
|
||||
_character_list.remove_item(index)
|
||||
_status_label.text = "Character deleted."
|
||||
|
||||
@@ -111,34 +111,34 @@ func _on_select_button_pressed() -> void:
|
||||
var character: Dictionary = _characters[index]
|
||||
SelectedCharacter.set_character(character)
|
||||
get_tree().change_scene_to_file("res://scenes/Levels/location_level.tscn")
|
||||
|
||||
func _on_refresh_button_pressed() -> void:
|
||||
_load_characters()
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _on_logout_button_pressed() -> void:
|
||||
_request_logout()
|
||||
|
||||
func _request_logout() -> void:
|
||||
if AuthState.access_token.is_empty():
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
return
|
||||
|
||||
var headers := PackedStringArray([
|
||||
"Authorization: Bearer %s" % AuthState.access_token,
|
||||
])
|
||||
var err := _logout_request.request(AUTH_LOGOUT_URL, headers, HTTPClient.METHOD_POST)
|
||||
if err != OK:
|
||||
push_warning("Failed to send logout request: %s" % err)
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _on_logout_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
var body_text := body.get_string_from_utf8()
|
||||
if result != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300:
|
||||
push_warning("Logout failed (%s/%s): %s" % [result, response_code, body_text])
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _on_refresh_button_pressed() -> void:
|
||||
_load_characters()
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _on_logout_button_pressed() -> void:
|
||||
_request_logout()
|
||||
|
||||
func _request_logout() -> void:
|
||||
if AuthState.access_token.is_empty():
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
return
|
||||
|
||||
var headers := PackedStringArray([
|
||||
"Authorization: Bearer %s" % AuthState.access_token,
|
||||
])
|
||||
var err := _logout_request.request(AUTH_LOGOUT_URL, headers, HTTPClient.METHOD_POST)
|
||||
if err != OK:
|
||||
push_warning("Failed to send logout request: %s" % err)
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _on_logout_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
var body_text := body.get_string_from_utf8()
|
||||
if result != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300:
|
||||
push_warning("Logout failed (%s/%s): %s" % [result, response_code, body_text])
|
||||
AuthState.clear_session()
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
@@ -1,92 +1,92 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://cw3b7n7k2c4h6"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/character_screen.gd" id="1_0p3qk"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_5g2t1"]
|
||||
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="3_k2j6k"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="4_5b3b7"]
|
||||
|
||||
[node name="CharacterScreen" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_0p3qk")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("2_5g2t1")
|
||||
|
||||
[node name="MarginContainer" 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 = 80
|
||||
theme_override_constants/margin_top = 40
|
||||
theme_override_constants/margin_right = 80
|
||||
theme_override_constants/margin_bottom = 40
|
||||
|
||||
[node name="ContentCenter" type="CenterContainer" parent="MarginContainer"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/separation = 18
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("3_k2j6k")
|
||||
text = "YOUR CHARACTERS"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterList" type="ItemList" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
custom_minimum_size = Vector2(520, 240)
|
||||
|
||||
[node name="AddHBox" type="HBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="NameInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/AddHBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "character name"
|
||||
|
||||
[node name="AddButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/AddHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "ADD"
|
||||
text_alignment = 1
|
||||
|
||||
[gd_scene load_steps=5 format=3 uid="uid://cw3b7n7k2c4h6"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/character_screen.gd" id="1_0p3qk"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_5g2t1"]
|
||||
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="3_k2j6k"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="4_5b3b7"]
|
||||
|
||||
[node name="CharacterScreen" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_0p3qk")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("2_5g2t1")
|
||||
|
||||
[node name="MarginContainer" 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 = 80
|
||||
theme_override_constants/margin_top = 40
|
||||
theme_override_constants/margin_right = 80
|
||||
theme_override_constants/margin_bottom = 40
|
||||
|
||||
[node name="ContentCenter" type="CenterContainer" parent="MarginContainer"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/separation = 18
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("3_k2j6k")
|
||||
text = "YOUR CHARACTERS"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterList" type="ItemList" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
custom_minimum_size = Vector2(520, 240)
|
||||
|
||||
[node name="AddHBox" type="HBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="NameInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/AddHBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "character name"
|
||||
|
||||
[node name="AddButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/AddHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "ADD"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="ActionHBox" type="HBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
@@ -104,36 +104,36 @@ layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "REFRESH"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="DeleteButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "DELETE"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="BackButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "BACK"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LogoutButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "LOG OUT"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LogoutRequest" type="HTTPRequest" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
text_alignment = 1
|
||||
|
||||
[node name="DeleteButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "DELETE"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="BackButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "BACK"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LogoutButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ActionHBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_5b3b7")
|
||||
text = "LOG OUT"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LogoutRequest" type="HTTPRequest" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/AddHBox/AddButton" to="." method="_on_add_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ActionHBox/SelectButton" to="." method="_on_select_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ActionHBox/RefreshButton" to="." method="_on_refresh_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ActionHBox/DeleteButton" to="." method="_on_delete_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ActionHBox/BackButton" to="." method="_on_back_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ActionHBox/LogoutButton" to="." method="_on_logout_button_pressed"]
|
||||
[connection signal="request_completed" from="LogoutRequest" to="." method="_on_logout_request_completed"]
|
||||
[connection signal="request_completed" from="LogoutRequest" to="." method="_on_logout_request_completed"]
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
extends Node
|
||||
|
||||
const CHARACTER_API_URL := "https://pchar.ranaze.com/api/Characters"
|
||||
|
||||
func list_characters() -> Dictionary:
|
||||
return await _request(HTTPClient.METHOD_GET, CHARACTER_API_URL)
|
||||
|
||||
func create_character(character_name: String) -> Dictionary:
|
||||
var payload := JSON.stringify({
|
||||
"name": character_name
|
||||
})
|
||||
return await _request(HTTPClient.METHOD_POST, CHARACTER_API_URL, payload)
|
||||
|
||||
extends Node
|
||||
|
||||
const CHARACTER_API_URL := "https://pchar.ranaze.com/api/Characters"
|
||||
|
||||
func list_characters() -> Dictionary:
|
||||
return await _request(HTTPClient.METHOD_GET, CHARACTER_API_URL)
|
||||
|
||||
func create_character(character_name: String) -> Dictionary:
|
||||
var payload := JSON.stringify({
|
||||
"name": character_name
|
||||
})
|
||||
return await _request(HTTPClient.METHOD_POST, CHARACTER_API_URL, payload)
|
||||
|
||||
func delete_character(character_id: String) -> Dictionary:
|
||||
var url := "%s/%s" % [CHARACTER_API_URL, character_id]
|
||||
return await _request(HTTPClient.METHOD_DELETE, url)
|
||||
@@ -28,45 +28,45 @@ func update_character_coord(character_id: String, coord: Vector2i) -> Dictionary
|
||||
func heartbeat_character(character_id: String) -> Dictionary:
|
||||
var url := "%s/%s/heartbeat" % [CHARACTER_API_URL, character_id]
|
||||
return await _request(HTTPClient.METHOD_POST, url, "")
|
||||
|
||||
func _request(method: int, url: String, body: String = "") -> Dictionary:
|
||||
var request := HTTPRequest.new()
|
||||
add_child(request)
|
||||
|
||||
var headers := PackedStringArray()
|
||||
if not AuthState.access_token.is_empty():
|
||||
headers.append("Authorization: Bearer %s" % AuthState.access_token)
|
||||
if method == HTTPClient.METHOD_POST or method == HTTPClient.METHOD_PUT:
|
||||
headers.append("Content-Type: application/json")
|
||||
|
||||
var err := request.request(url, headers, method, body)
|
||||
if err != OK:
|
||||
request.queue_free()
|
||||
return {
|
||||
"ok": false,
|
||||
"status": 0,
|
||||
"error": "Failed to send request (%s)." % err,
|
||||
"body": ""
|
||||
}
|
||||
|
||||
var result: Array = await request.request_completed
|
||||
request.queue_free()
|
||||
|
||||
var result_code: int = result[0]
|
||||
var response_code: int = result[1]
|
||||
var response_body: String = result[3].get_string_from_utf8()
|
||||
|
||||
if result_code != HTTPRequest.RESULT_SUCCESS:
|
||||
return {
|
||||
"ok": false,
|
||||
"status": response_code,
|
||||
"error": "Network error (%s)." % result_code,
|
||||
"body": response_body
|
||||
}
|
||||
|
||||
return {
|
||||
"ok": response_code >= 200 and response_code < 300,
|
||||
"status": response_code,
|
||||
"error": "",
|
||||
"body": response_body
|
||||
}
|
||||
|
||||
func _request(method: int, url: String, body: String = "") -> Dictionary:
|
||||
var request := HTTPRequest.new()
|
||||
add_child(request)
|
||||
|
||||
var headers := PackedStringArray()
|
||||
if not AuthState.access_token.is_empty():
|
||||
headers.append("Authorization: Bearer %s" % AuthState.access_token)
|
||||
if method == HTTPClient.METHOD_POST or method == HTTPClient.METHOD_PUT:
|
||||
headers.append("Content-Type: application/json")
|
||||
|
||||
var err := request.request(url, headers, method, body)
|
||||
if err != OK:
|
||||
request.queue_free()
|
||||
return {
|
||||
"ok": false,
|
||||
"status": 0,
|
||||
"error": "Failed to send request (%s)." % err,
|
||||
"body": ""
|
||||
}
|
||||
|
||||
var result: Array = await request.request_completed
|
||||
request.queue_free()
|
||||
|
||||
var result_code: int = result[0]
|
||||
var response_code: int = result[1]
|
||||
var response_body: String = result[3].get_string_from_utf8()
|
||||
|
||||
if result_code != HTTPRequest.RESULT_SUCCESS:
|
||||
return {
|
||||
"ok": false,
|
||||
"status": response_code,
|
||||
"error": "Network error (%s)." % result_code,
|
||||
"body": response_body
|
||||
}
|
||||
|
||||
return {
|
||||
"ok": response_code >= 200 and response_code < 300,
|
||||
"status": response_code,
|
||||
"error": "",
|
||||
"body": response_body
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Control
|
||||
|
||||
const AUTH_LOGIN_URL := "https://pauth.ranaze.com/api/Auth/login"
|
||||
|
||||
extends Control
|
||||
|
||||
const AUTH_LOGIN_URL := "https://pauth.ranaze.com/api/Auth/login"
|
||||
|
||||
@onready var _username_input: LineEdit = %UsernameInput
|
||||
@onready var _password_input: LineEdit = %PasswordInput
|
||||
@onready var _login_request: HTTPRequest = %LoginRequest
|
||||
@@ -18,38 +18,38 @@ func _on_log_in_button_pressed() -> void:
|
||||
var password := _password_input.text
|
||||
if username.is_empty() or password.is_empty():
|
||||
_show_error("Username and password required.")
|
||||
return
|
||||
|
||||
var payload := {
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
var headers := PackedStringArray(["Content-Type: application/json"])
|
||||
var err := _login_request.request(AUTH_LOGIN_URL, headers, HTTPClient.METHOD_POST, JSON.stringify(payload))
|
||||
if err != OK:
|
||||
_show_error("Failed to send login request.")
|
||||
|
||||
func _on_login_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
var body_text := body.get_string_from_utf8()
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
_show_error("Network error. Please try again.")
|
||||
return
|
||||
|
||||
if response_code >= 200 and response_code < 300:
|
||||
var response: Variant = JSON.parse_string(body_text)
|
||||
if typeof(response) == TYPE_DICTIONARY:
|
||||
#print("Login success for %s" % response.get("username", "unknown"))
|
||||
#print("Access Token: %s" % response.get("accessToken", ""))
|
||||
var token := String(response.get("accessToken", ""))
|
||||
var username := String(response.get("username", ""))
|
||||
AuthState.set_session(username, token)
|
||||
get_tree().change_scene_to_file("res://scenes/UI/character_screen.tscn")
|
||||
else:
|
||||
_show_error("Login failed. Check your credentials.")
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
return
|
||||
|
||||
var payload := {
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
var headers := PackedStringArray(["Content-Type: application/json"])
|
||||
var err := _login_request.request(AUTH_LOGIN_URL, headers, HTTPClient.METHOD_POST, JSON.stringify(payload))
|
||||
if err != OK:
|
||||
_show_error("Failed to send login request.")
|
||||
|
||||
func _on_login_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
var body_text := body.get_string_from_utf8()
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
_show_error("Network error. Please try again.")
|
||||
return
|
||||
|
||||
if response_code >= 200 and response_code < 300:
|
||||
var response: Variant = JSON.parse_string(body_text)
|
||||
if typeof(response) == TYPE_DICTIONARY:
|
||||
#print("Login success for %s" % response.get("username", "unknown"))
|
||||
#print("Access Token: %s" % response.get("accessToken", ""))
|
||||
var token := String(response.get("accessToken", ""))
|
||||
var username := String(response.get("username", ""))
|
||||
AuthState.set_session(username, token)
|
||||
get_tree().change_scene_to_file("res://scenes/UI/character_screen.tscn")
|
||||
else:
|
||||
_show_error("Login failed. Check your credentials.")
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")
|
||||
|
||||
func _show_error(message: String) -> void:
|
||||
_error_label.text = message
|
||||
|
||||
|
||||
+117
-117
@@ -1,117 +1,117 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://fmp1tah03kew"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/login_screen.gd" id="1_jqkpi"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_2n6di"]
|
||||
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="3_c4k70"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="4_gx673"]
|
||||
|
||||
[node name="LoginScreen" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_jqkpi")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("2_2n6di")
|
||||
|
||||
[node name="MarginContainer" 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 = 80
|
||||
theme_override_constants/margin_top = 40
|
||||
theme_override_constants/margin_right = 80
|
||||
theme_override_constants/margin_bottom = 40
|
||||
|
||||
[node name="ContentCenter" type="CenterContainer" parent="MarginContainer"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("3_c4k70")
|
||||
text = "ACCOUNT LOGIN"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FormVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 8
|
||||
custom_minimum_size = Vector2(480, 0)
|
||||
|
||||
[node name="UsernameLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
layout_mode = 2
|
||||
text = "Username"
|
||||
|
||||
[node name="UsernameInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
placeholder_text = "enter username"
|
||||
caret_blink = true
|
||||
|
||||
[node name="PasswordLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
layout_mode = 2
|
||||
text = "Password"
|
||||
|
||||
[node name="PasswordInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
placeholder_text = "enter password"
|
||||
secret = true
|
||||
|
||||
[node name="ButtonVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="ErrorLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_c4k70")
|
||||
horizontal_alignment = 1
|
||||
theme_override_font_sizes/font_size = 26
|
||||
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
|
||||
|
||||
[node name="LogInButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_gx673")
|
||||
text = "LOG IN"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="BackButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_gx673")
|
||||
text = "BACK"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LoginRequest" type="HTTPRequest" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/LogInButton" to="." method="_on_log_in_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/BackButton" to="." method="_on_back_button_pressed"]
|
||||
[connection signal="request_completed" from="LoginRequest" to="." method="_on_login_request_completed"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://fmp1tah03kew"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/login_screen.gd" id="1_jqkpi"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhuosr0p605gj" path="res://assets/images/pp_start_bg.png" id="2_2n6di"]
|
||||
[ext_resource type="Theme" uid="uid://tn8qndst18d6" path="res://themes/title_font_theme.tres" id="3_c4k70"]
|
||||
[ext_resource type="Theme" uid="uid://wpxmub0n2dr3" path="res://themes/button_theme.tres" id="4_gx673"]
|
||||
|
||||
[node name="LoginScreen" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_jqkpi")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("2_2n6di")
|
||||
|
||||
[node name="MarginContainer" 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 = 80
|
||||
theme_override_constants/margin_top = 40
|
||||
theme_override_constants/margin_right = 80
|
||||
theme_override_constants/margin_bottom = 40
|
||||
|
||||
[node name="ContentCenter" type="CenterContainer" parent="MarginContainer"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="ContentVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("3_c4k70")
|
||||
text = "ACCOUNT LOGIN"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="FormVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 8
|
||||
custom_minimum_size = Vector2(480, 0)
|
||||
|
||||
[node name="UsernameLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
layout_mode = 2
|
||||
text = "Username"
|
||||
|
||||
[node name="UsernameInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
placeholder_text = "enter username"
|
||||
caret_blink = true
|
||||
|
||||
[node name="PasswordLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
layout_mode = 2
|
||||
text = "Password"
|
||||
|
||||
[node name="PasswordInput" type="LineEdit" parent="MarginContainer/ContentCenter/ContentVBox/FormVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
placeholder_text = "enter password"
|
||||
secret = true
|
||||
|
||||
[node name="ButtonVBox" type="VBoxContainer" parent="MarginContainer/ContentCenter/ContentVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="ErrorLabel" type="Label" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme = ExtResource("3_c4k70")
|
||||
horizontal_alignment = 1
|
||||
theme_override_font_sizes/font_size = 26
|
||||
theme_override_colors/font_color = Color(1, 0.2, 0.2, 1)
|
||||
|
||||
[node name="LogInButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_gx673")
|
||||
text = "LOG IN"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="BackButton" type="Button" parent="MarginContainer/ContentCenter/ContentVBox/ButtonVBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("4_gx673")
|
||||
text = "BACK"
|
||||
text_alignment = 1
|
||||
|
||||
[node name="LoginRequest" type="HTTPRequest" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/LogInButton" to="." method="_on_log_in_button_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/ContentCenter/ContentVBox/ButtonVBox/BackButton" to="." method="_on_back_button_pressed"]
|
||||
[connection signal="request_completed" from="LoginRequest" to="." method="_on_login_request_completed"]
|
||||
|
||||
+107
-107
@@ -1,107 +1,107 @@
|
||||
extends AudioStreamPlayer
|
||||
|
||||
const MENU_SCENES: Dictionary = {
|
||||
"res://scenes/UI/start_screen.tscn": true,
|
||||
"res://scenes/UI/Settings.tscn": true,
|
||||
"res://scenes/UI/login_screen.tscn": true,
|
||||
}
|
||||
|
||||
const CONFIG_PATH := "user://settings.cfg"
|
||||
const CONFIG_SECTION := "audio"
|
||||
const CONFIG_KEY_MUSIC_VOLUME := "menu_music_volume"
|
||||
const CONFIG_KEY_MUSIC_MUTED := "menu_music_muted"
|
||||
const DEFAULT_VOLUME := 0.7
|
||||
|
||||
var _last_scene: Node = null
|
||||
var _user_volume_linear: float = DEFAULT_VOLUME
|
||||
var _is_muted: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(true)
|
||||
_load_settings()
|
||||
_apply_volume()
|
||||
_update_playback(get_tree().current_scene)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var current := get_tree().current_scene
|
||||
if current != _last_scene:
|
||||
_update_playback(current)
|
||||
elif _should_play_scene(current) and not playing and not _is_muted and _user_volume_linear > 0.0:
|
||||
play()
|
||||
|
||||
func _update_playback(scene: Node) -> void:
|
||||
if scene == null:
|
||||
_last_scene = null
|
||||
return
|
||||
_last_scene = scene
|
||||
if _should_play_scene(scene):
|
||||
if not playing:
|
||||
play()
|
||||
elif playing:
|
||||
stop()
|
||||
|
||||
func _should_play_scene(scene: Node) -> bool:
|
||||
if scene == null:
|
||||
return false
|
||||
var scene_path: String = scene.get_scene_file_path()
|
||||
if scene_path.is_empty():
|
||||
return false
|
||||
return MENU_SCENES.has(scene_path)
|
||||
|
||||
func set_user_volume(value: float) -> void:
|
||||
var clamped_value: float = clamp(value, 0.0, 1.0)
|
||||
if is_equal_approx(_user_volume_linear, clamped_value):
|
||||
return
|
||||
_user_volume_linear = clamped_value
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func get_user_volume() -> float:
|
||||
return _user_volume_linear
|
||||
|
||||
func set_user_muted(muted: bool) -> void:
|
||||
var new_muted: bool = muted
|
||||
if _is_muted == new_muted:
|
||||
return
|
||||
_is_muted = new_muted
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func is_user_muted() -> bool:
|
||||
return _is_muted
|
||||
|
||||
func _apply_volume() -> void:
|
||||
if _is_muted or _user_volume_linear <= 0.0:
|
||||
volume_db = -80.0
|
||||
else:
|
||||
volume_db = linear_to_db(_user_volume_linear)
|
||||
|
||||
func _load_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err == OK:
|
||||
var stored_volume: float = float(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_VOLUME, DEFAULT_VOLUME))
|
||||
_user_volume_linear = clamp(stored_volume, 0.0, 1.0)
|
||||
var stored_muted: bool = bool(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_MUTED, false))
|
||||
_is_muted = stored_muted
|
||||
elif err == ERR_DOES_NOT_EXIST:
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
else:
|
||||
push_warning("Failed to load settings.cfg: %s" % err)
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
|
||||
func _save_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err != OK and err != ERR_DOES_NOT_EXIST:
|
||||
push_warning("Failed to load settings.cfg before saving: %s" % err)
|
||||
config = ConfigFile.new()
|
||||
elif err != OK:
|
||||
config = ConfigFile.new()
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_VOLUME, _user_volume_linear)
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_MUTED, _is_muted)
|
||||
var save_err: int = config.save(CONFIG_PATH)
|
||||
if save_err != OK:
|
||||
push_warning("Failed to save settings.cfg: %s" % save_err)
|
||||
extends AudioStreamPlayer
|
||||
|
||||
const MENU_SCENES: Dictionary = {
|
||||
"res://scenes/UI/start_screen.tscn": true,
|
||||
"res://scenes/UI/Settings.tscn": true,
|
||||
"res://scenes/UI/login_screen.tscn": true,
|
||||
}
|
||||
|
||||
const CONFIG_PATH := "user://settings.cfg"
|
||||
const CONFIG_SECTION := "audio"
|
||||
const CONFIG_KEY_MUSIC_VOLUME := "menu_music_volume"
|
||||
const CONFIG_KEY_MUSIC_MUTED := "menu_music_muted"
|
||||
const DEFAULT_VOLUME := 0.7
|
||||
|
||||
var _last_scene: Node = null
|
||||
var _user_volume_linear: float = DEFAULT_VOLUME
|
||||
var _is_muted: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(true)
|
||||
_load_settings()
|
||||
_apply_volume()
|
||||
_update_playback(get_tree().current_scene)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var current := get_tree().current_scene
|
||||
if current != _last_scene:
|
||||
_update_playback(current)
|
||||
elif _should_play_scene(current) and not playing and not _is_muted and _user_volume_linear > 0.0:
|
||||
play()
|
||||
|
||||
func _update_playback(scene: Node) -> void:
|
||||
if scene == null:
|
||||
_last_scene = null
|
||||
return
|
||||
_last_scene = scene
|
||||
if _should_play_scene(scene):
|
||||
if not playing:
|
||||
play()
|
||||
elif playing:
|
||||
stop()
|
||||
|
||||
func _should_play_scene(scene: Node) -> bool:
|
||||
if scene == null:
|
||||
return false
|
||||
var scene_path: String = scene.get_scene_file_path()
|
||||
if scene_path.is_empty():
|
||||
return false
|
||||
return MENU_SCENES.has(scene_path)
|
||||
|
||||
func set_user_volume(value: float) -> void:
|
||||
var clamped_value: float = clamp(value, 0.0, 1.0)
|
||||
if is_equal_approx(_user_volume_linear, clamped_value):
|
||||
return
|
||||
_user_volume_linear = clamped_value
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func get_user_volume() -> float:
|
||||
return _user_volume_linear
|
||||
|
||||
func set_user_muted(muted: bool) -> void:
|
||||
var new_muted: bool = muted
|
||||
if _is_muted == new_muted:
|
||||
return
|
||||
_is_muted = new_muted
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func is_user_muted() -> bool:
|
||||
return _is_muted
|
||||
|
||||
func _apply_volume() -> void:
|
||||
if _is_muted or _user_volume_linear <= 0.0:
|
||||
volume_db = -80.0
|
||||
else:
|
||||
volume_db = linear_to_db(_user_volume_linear)
|
||||
|
||||
func _load_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err == OK:
|
||||
var stored_volume: float = float(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_VOLUME, DEFAULT_VOLUME))
|
||||
_user_volume_linear = clamp(stored_volume, 0.0, 1.0)
|
||||
var stored_muted: bool = bool(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_MUTED, false))
|
||||
_is_muted = stored_muted
|
||||
elif err == ERR_DOES_NOT_EXIST:
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
else:
|
||||
push_warning("Failed to load settings.cfg: %s" % err)
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
|
||||
func _save_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err != OK and err != ERR_DOES_NOT_EXIST:
|
||||
push_warning("Failed to load settings.cfg before saving: %s" % err)
|
||||
config = ConfigFile.new()
|
||||
elif err != OK:
|
||||
config = ConfigFile.new()
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_VOLUME, _user_volume_linear)
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUSIC_MUTED, _is_muted)
|
||||
var save_err: int = config.save(CONFIG_PATH)
|
||||
if save_err != OK:
|
||||
push_warning("Failed to save settings.cfg: %s" % save_err)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dfmq1n507y7d3"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://txgki0ijeuud" path="res://assets/audio/silly-test.ogg" id="1_ek0t3"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/menu_music.gd" id="2_21d4q"]
|
||||
|
||||
[node name="MenuMusic" type="AudioStreamPlayer"]
|
||||
bus = &"Music"
|
||||
stream = ExtResource("1_ek0t3")
|
||||
autoplay = true
|
||||
volume_db = -3.0
|
||||
priority = 10.0
|
||||
script = ExtResource("2_21d4q")
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dfmq1n507y7d3"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://txgki0ijeuud" path="res://assets/audio/silly-test.ogg" id="1_ek0t3"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/UI/menu_music.gd" id="2_21d4q"]
|
||||
|
||||
[node name="MenuMusic" type="AudioStreamPlayer"]
|
||||
bus = &"Music"
|
||||
stream = ExtResource("1_ek0t3")
|
||||
autoplay = true
|
||||
volume_db = -3.0
|
||||
priority = 10.0
|
||||
script = ExtResource("2_21d4q")
|
||||
|
||||
+76
-76
@@ -1,76 +1,76 @@
|
||||
extends AudioStreamPlayer
|
||||
|
||||
const CONFIG_PATH := "user://settings.cfg"
|
||||
const CONFIG_SECTION := "audio"
|
||||
const CONFIG_KEY_VOLUME := "menu_sfx_volume"
|
||||
const CONFIG_KEY_MUTED := "menu_sfx_muted"
|
||||
const DEFAULT_VOLUME := 0.7
|
||||
|
||||
var _user_volume_linear: float = DEFAULT_VOLUME
|
||||
var _is_muted: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
_load_settings()
|
||||
_apply_volume()
|
||||
|
||||
func play_hover() -> void:
|
||||
if stream == null or _is_muted or _user_volume_linear <= 0.0:
|
||||
return
|
||||
play(0.0)
|
||||
|
||||
func set_user_volume(value: float) -> void:
|
||||
var clamped_value: float = clamp(value, 0.0, 1.0)
|
||||
if is_equal_approx(_user_volume_linear, clamped_value):
|
||||
return
|
||||
_user_volume_linear = clamped_value
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func get_user_volume() -> float:
|
||||
return _user_volume_linear
|
||||
|
||||
func set_user_muted(muted: bool) -> void:
|
||||
if _is_muted == muted:
|
||||
return
|
||||
_is_muted = muted
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
if _is_muted:
|
||||
stop()
|
||||
|
||||
func is_user_muted() -> bool:
|
||||
return _is_muted
|
||||
|
||||
func _apply_volume() -> void:
|
||||
if _is_muted or _user_volume_linear <= 0.0:
|
||||
volume_db = -80.0
|
||||
else:
|
||||
volume_db = linear_to_db(_user_volume_linear)
|
||||
|
||||
func _load_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err == OK:
|
||||
_user_volume_linear = clamp(float(config.get_value(CONFIG_SECTION, CONFIG_KEY_VOLUME, DEFAULT_VOLUME)), 0.0, 1.0)
|
||||
_is_muted = bool(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUTED, false))
|
||||
elif err == ERR_DOES_NOT_EXIST:
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
else:
|
||||
push_warning("Failed to load settings.cfg: %s" % err)
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
|
||||
func _save_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err != OK and err != ERR_DOES_NOT_EXIST:
|
||||
push_warning("Failed to load settings.cfg before saving: %s" % err)
|
||||
config = ConfigFile.new()
|
||||
elif err != OK:
|
||||
config = ConfigFile.new()
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_VOLUME, _user_volume_linear)
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUTED, _is_muted)
|
||||
var save_err: int = config.save(CONFIG_PATH)
|
||||
if save_err != OK:
|
||||
push_warning("Failed to save settings.cfg: %s" % save_err)
|
||||
extends AudioStreamPlayer
|
||||
|
||||
const CONFIG_PATH := "user://settings.cfg"
|
||||
const CONFIG_SECTION := "audio"
|
||||
const CONFIG_KEY_VOLUME := "menu_sfx_volume"
|
||||
const CONFIG_KEY_MUTED := "menu_sfx_muted"
|
||||
const DEFAULT_VOLUME := 0.7
|
||||
|
||||
var _user_volume_linear: float = DEFAULT_VOLUME
|
||||
var _is_muted: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
_load_settings()
|
||||
_apply_volume()
|
||||
|
||||
func play_hover() -> void:
|
||||
if stream == null or _is_muted or _user_volume_linear <= 0.0:
|
||||
return
|
||||
play(0.0)
|
||||
|
||||
func set_user_volume(value: float) -> void:
|
||||
var clamped_value: float = clamp(value, 0.0, 1.0)
|
||||
if is_equal_approx(_user_volume_linear, clamped_value):
|
||||
return
|
||||
_user_volume_linear = clamped_value
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
|
||||
func get_user_volume() -> float:
|
||||
return _user_volume_linear
|
||||
|
||||
func set_user_muted(muted: bool) -> void:
|
||||
if _is_muted == muted:
|
||||
return
|
||||
_is_muted = muted
|
||||
_apply_volume()
|
||||
_save_settings()
|
||||
if _is_muted:
|
||||
stop()
|
||||
|
||||
func is_user_muted() -> bool:
|
||||
return _is_muted
|
||||
|
||||
func _apply_volume() -> void:
|
||||
if _is_muted or _user_volume_linear <= 0.0:
|
||||
volume_db = -80.0
|
||||
else:
|
||||
volume_db = linear_to_db(_user_volume_linear)
|
||||
|
||||
func _load_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err == OK:
|
||||
_user_volume_linear = clamp(float(config.get_value(CONFIG_SECTION, CONFIG_KEY_VOLUME, DEFAULT_VOLUME)), 0.0, 1.0)
|
||||
_is_muted = bool(config.get_value(CONFIG_SECTION, CONFIG_KEY_MUTED, false))
|
||||
elif err == ERR_DOES_NOT_EXIST:
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
else:
|
||||
push_warning("Failed to load settings.cfg: %s" % err)
|
||||
_user_volume_linear = DEFAULT_VOLUME
|
||||
_is_muted = false
|
||||
|
||||
func _save_settings() -> void:
|
||||
var config: ConfigFile = ConfigFile.new()
|
||||
var err: int = config.load(CONFIG_PATH)
|
||||
if err != OK and err != ERR_DOES_NOT_EXIST:
|
||||
push_warning("Failed to load settings.cfg before saving: %s" % err)
|
||||
config = ConfigFile.new()
|
||||
elif err != OK:
|
||||
config = ConfigFile.new()
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_VOLUME, _user_volume_linear)
|
||||
config.set_value(CONFIG_SECTION, CONFIG_KEY_MUTED, _is_muted)
|
||||
var save_err: int = config.save(CONFIG_PATH)
|
||||
if save_err != OK:
|
||||
push_warning("Failed to save settings.cfg: %s" % save_err)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dt785sv7ie7uj"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://64dplcgx2icb" path="res://assets/audio/silly-menu-hover-test.ogg" id="1_a5j5k"]
|
||||
[ext_resource type="Script" path="res://scenes/UI/menu_sfx.gd" id="1_ijvfa"]
|
||||
|
||||
[node name="MenuSfx" type="AudioStreamPlayer"]
|
||||
bus = &"SFX"
|
||||
stream = ExtResource("1_a5j5k")
|
||||
volume_db = -6.0
|
||||
autoplay = false
|
||||
priority = 0.5
|
||||
max_polyphony = 4
|
||||
script = ExtResource("1_ijvfa")
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dt785sv7ie7uj"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://64dplcgx2icb" path="res://assets/audio/silly-menu-hover-test.ogg" id="1_a5j5k"]
|
||||
[ext_resource type="Script" path="res://scenes/UI/menu_sfx.gd" id="1_ijvfa"]
|
||||
|
||||
[node name="MenuSfx" type="AudioStreamPlayer"]
|
||||
bus = &"SFX"
|
||||
stream = ExtResource("1_a5j5k")
|
||||
volume_db = -6.0
|
||||
autoplay = false
|
||||
priority = 0.5
|
||||
max_polyphony = 4
|
||||
script = ExtResource("1_ijvfa")
|
||||
|
||||
Reference in New Issue
Block a user