👽 interstellar delivery

This commit is contained in:
anyreso 2024-10-16 21:43:01 +00:00
parent 547c97bfba
commit 97c8292858
257 changed files with 7309 additions and 4637 deletions

View file

@ -0,0 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://bec7g0fax3c8o"]
[ext_resource type="FontFile" uid="uid://hbggv2tf174i" path="res://assets/fonts/Exo2/Exo2.ttf" id="1_u2ykv"]
[resource]
default_font = ExtResource("1_u2ykv")

32
interfaces/hud/hud.gd Normal file
View file

@ -0,0 +1,32 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name HUD extends CanvasLayer
@export var health_bar:ProgressBar
@export var energy_bar:ProgressBar
@export var timer_label:Label
@export var objective_label:Label
@export var debug_label:Label
@export var ammo_label:Label
@export var throw_progress:TextureProgressBar
@onready var player:Player = owner
func _ready() -> void:
health_bar.set_value(player.health.max_value)
energy_bar.set_value(player.energy_max)
func _on_ammo_changed(new_ammo: int) -> void:
ammo_label.text = str(new_ammo)

View file

@ -1,52 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://bcv81ku26xo"]
[gd_scene load_steps=13 format=3 uid="uid://bcv81ku26xo"]
[ext_resource type="Script" path="res://interfaces/hud/timer_label.gd" id="1_6qrx6"]
[ext_resource type="StyleBox" uid="uid://dcn1ll2ra4lwn" path="res://interfaces/hud/vitals/background.tres" id="1_gmv44"]
[ext_resource type="Script" path="res://interfaces/hud/hud.gd" id="1_yev76"]
[ext_resource type="StyleBox" uid="uid://bq7rjpm38pao7" path="res://interfaces/hud/vitals/health_foreground.tres" id="2_6ejsl"]
[sub_resource type="GDScript" id="GDScript_2vxif"]
script/source = "# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends CanvasLayer
@export var health_bar : ProgressBar
@export var energy_bar : ProgressBar
@export var debug_label : Label
"
[sub_resource type="GDScript" id="GDScript_w8l21"]
script/source = "extends Label
@onready var player : Player = get_parent().owner
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
if not OS.is_debug_build():
queue_free()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta : float) -> void:
text = \"\"
text += \"fps: %d (%.2f mspf)\\n\" % [Engine.get_frames_per_second(), 1000.0 / Engine.get_frames_per_second()]
text += \"position: %d, %d, %d\\n\" % [player.position.x, player.position.y, player.position.z]
text += \"speed: %d km/h\\n\" % (player.linear_velocity.length() * 3.6)
var velocity_xz := Vector3(player.linear_velocity.x, 0., player.linear_velocity.z)
text += \"speed_xz: %d km/h\\n\" % (velocity_xz.length() * 3.6)
var viewport_render_size : Vector2i = get_viewport().size * get_viewport().scaling_3d_scale
text += \"3D viewport resolution: %d × %d (%d%%)\\n\" \\
% [viewport_render_size.x, viewport_render_size.y, round(get_viewport().scaling_3d_scale * 100)]
"
[ext_resource type="Theme" uid="uid://bec7g0fax3c8o" path="res://interfaces/global_theme.tres" id="2_gbqw5"]
[ext_resource type="Texture2D" uid="uid://1mwcg0cd0msw" path="res://interfaces/hud/throw_force_texture.svg" id="6_rrus8"]
[sub_resource type="Shader" id="Shader_gaah5"]
code = "shader_type canvas_item;
@ -67,6 +26,33 @@ void fragment() {
shader = SubResource("Shader_gaah5")
shader_parameter/color = Color(1, 1, 1, 1)
[sub_resource type="SystemFont" id="SystemFont_oo638"]
subpixel_positioning = 0
[sub_resource type="GDScript" id="GDScript_w8l21"]
script/source = "extends Label
@onready var player : Player = owner.get_parent()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
if not OS.is_debug_build():
queue_free()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta : float) -> void:
text = \"\"
text += \"fps: %d (%.2f mspf)\\n\" % [Engine.get_frames_per_second(), 1000.0 / Engine.get_frames_per_second()]
text += \"position: %d, %d, %d\\n\" % [player.position.x, player.position.y, player.position.z]
text += \"speed: %d km/h\\n\" % (player.linear_velocity.length() * 3.6)
var velocity_xz := Vector3(player.linear_velocity.x, 0., player.linear_velocity.z)
text += \"speed_xz: %d km/h\\n\" % (velocity_xz.length() * 3.6)
var viewport_render_size : Vector2i = get_viewport().size * get_viewport().scaling_3d_scale
text += \"3D viewport resolution: %d × %d (%d%%)\\n\" \\
% [viewport_render_size.x, viewport_render_size.y, round(get_viewport().scaling_3d_scale * 100)]
text += \"health: %d\" % player.health.value
"
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_f23s3"]
bg_color = Color(0.0901961, 0.87451, 0.760784, 0.65098)
corner_radius_top_left = 3
@ -75,17 +61,23 @@ corner_radius_bottom_right = 3
corner_radius_bottom_left = 3
anti_aliasing = false
[node name="HUD" type="CanvasLayer" node_paths=PackedStringArray("health_bar", "energy_bar")]
script = SubResource("GDScript_2vxif")
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_2pxd4"]
properties/0/path = NodePath("MarginContainer/Multiplayer/TimerLabel:text")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath("MarginContainer/Multiplayer/ObjectiveLabel:visible")
properties/1/spawn = true
properties/1/replication_mode = 2
[node name="HUD" type="CanvasLayer" node_paths=PackedStringArray("health_bar", "energy_bar", "timer_label", "objective_label", "debug_label", "ammo_label", "throw_progress")]
script = ExtResource("1_yev76")
health_bar = NodePath("MarginContainer/HBoxContainer/VBoxContainer/HealthBar")
energy_bar = NodePath("MarginContainer/HBoxContainer/VBoxContainer/EnergyBar")
[node name="DebugLabel" type="Label" parent="."]
offset_left = 20.0
offset_top = 20.0
offset_right = 21.0
offset_bottom = 43.0
script = SubResource("GDScript_w8l21")
timer_label = NodePath("MarginContainer/Multiplayer/TimerLabel")
objective_label = NodePath("MarginContainer/Multiplayer/ObjectiveLabel")
debug_label = NodePath("MarginContainer/DebugLabel")
ammo_label = NodePath("MarginContainer/HBoxContainer/HBoxContainer/AmmoLabel")
throw_progress = NodePath("MarginContainer/CenterContainer/TextureProgressBar")
[node name="Reticle" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_7blp5")
@ -103,24 +95,53 @@ grow_vertical = 2
mouse_filter = 2
[node name="MarginContainer" type="MarginContainer" parent="."]
anchors_preset = 12
anchor_top = 1.0
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = -42.0
grow_horizontal = 2
grow_vertical = 0
theme_override_constants/margin_left = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
grow_vertical = 2
theme = ExtResource("2_gbqw5")
theme_override_constants/margin_left = 24
theme_override_constants/margin_top = 24
theme_override_constants/margin_right = 24
theme_override_constants/margin_bottom = 24
[node name="Multiplayer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="TimerLabel" type="Label" parent="MarginContainer/Multiplayer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 22
text = "Warmup"
horizontal_alignment = 1
script = ExtResource("1_6qrx6")
[node name="ObjectiveLabel" type="Label" parent="MarginContainer/Multiplayer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.75, 0, 1)
theme_override_colors/font_shadow_color = Color(0, 0, 0, 0.5)
theme_override_font_sizes/font_size = 24
text = "YOU ARE THE RABBIT"
horizontal_alignment = 1
uppercase = true
[node name="DebugLabel" type="Label" parent="MarginContainer"]
layout_mode = 2
size_flags_vertical = 0
theme_override_fonts/font = SubResource("SystemFont_oo638")
script = SubResource("GDScript_w8l21")
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 10
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 8
size_flags_stretch_ratio = 0.2
theme_override_constants/separation = 6
@ -132,7 +153,7 @@ theme_override_styles/background = ExtResource("1_gmv44")
theme_override_styles/fill = ExtResource("2_6ejsl")
max_value = 255.0
step = 1.0
value = 1.0
value = 255.0
show_percentage = false
[node name="EnergyBar" type="ProgressBar" parent="MarginContainer/HBoxContainer/VBoxContainer"]
@ -141,10 +162,42 @@ layout_mode = 2
mouse_filter = 2
theme_override_styles/background = ExtResource("1_gmv44")
theme_override_styles/fill = SubResource("StyleBoxFlat_f23s3")
value = 60.0
value = 100.0
show_percentage = false
[node name="Spacer" type="Control" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.8
size_flags_stretch_ratio = 0.6
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.2
[node name="AmmoLabel" type="Label" parent="MarginContainer/HBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 20
text = "24
"
horizontal_alignment = 2
vertical_alignment = 1
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer"]
layout_mode = 2
[node name="TextureProgressBar" type="TextureProgressBar" parent="MarginContainer/CenterContainer"]
visible = false
layout_mode = 2
value = 100.0
fill_mode = 4
texture_progress = ExtResource("6_rrus8")
radial_initial_angle = 293.0
radial_fill_degrees = 135.0
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_interval = 0.1
replication_config = SubResource("SceneReplicationConfig_2pxd4")
[node name="CenterContainer" type="CenterContainer" parent="."]

View file

@ -51,8 +51,10 @@ signal border_changed(new_border : float)
## The username to display on top of this indicator.
@export var username : String = "Username":
set(value):
username = value
set = set_username
func set_username(new_name : String) -> void:
username = new_name
username_changed.emit(username)
## The foreground color to use for this indicator.

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="26.53857mm"
height="26.538568mm"
viewBox="0 0 26.53857 26.538568"
version="1.1"
id="svg1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="linearGradient1">
<stop
style="stop-color:#ffff00;stop-opacity:1;"
offset="0"
id="stop1" />
<stop
style="stop-color:#ff0000;stop-opacity:1;"
offset="1"
id="stop2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient1"
id="linearGradient2"
x1="60.761497"
y1="51.722984"
x2="92.511497"
y2="51.722984"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.86468252,0,0,0.86468252,10.370258,6.999024)" />
</defs>
<g
id="layer1"
transform="translate(-63.367213,-38.4537)">
<circle
style="fill:none;stroke:url(#linearGradient2);stroke-width:3.66051;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:markers stroke fill"
id="path1"
cx="76.636497"
cy="51.722984"
r="11.43903" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://1mwcg0cd0msw"
path="res://.godot/imported/throw_force_texture.svg-c8f74c490a74ad039fa1bdb24add5fd6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://interfaces/hud/throw_force_texture.svg"
dest_files=["res://.godot/imported/throw_force_texture.svg-c8f74c490a74ad039fa1bdb24add5fd6.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=false
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
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,32 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends Label
var timer: Timer = null
func _ready() -> void:
if Game.type is Multiplayer:
timer = Game.type.timer
else:
visible = false
set_process(false)
func _process(_delta: float) -> void:
if timer and not timer.is_stopped() \
and !(multiplayer.multiplayer_peer is OfflineMultiplayerPeer) \
and multiplayer.is_server():
var minutes: int = int(timer.time_left / 60)
var seconds : int = int(fmod(timer.time_left, 60))
text = "%d:%02d" % [minutes, seconds]

View file

@ -16,30 +16,37 @@ class_name BootMenu extends CanvasLayer
signal start_demo
@export var multiplayer_panel : MultiplayerPanelContainer
@export var settings_panel : SettingsPanelContainer
func _ready() -> void:
multiplayer_panel.menu_pressed.connect(_on_main_menu_pressed)
settings_panel.closed.connect(_on_main_menu_pressed)
func _on_demo_pressed() -> void:
start_demo.emit()
func _on_multiplayer_pressed() -> void:
$MultiplayerPanelContainer.hide()
$MultiplayerPanelContainer.tab_container.current_tab = 0
$SettingsPanelContainer.hide()
multiplayer_panel.hide()
multiplayer_panel.tab_container.current_tab = 0
settings_panel.hide()
$MainPanelContainer.hide()
$MultiplayerPanelContainer.show()
multiplayer_panel.show()
show()
func _on_settings_pressed() -> void:
$MultiplayerPanelContainer.hide()
$MultiplayerPanelContainer.tab_container.current_tab = 0
$SettingsPanelContainer.show()
multiplayer_panel.hide()
multiplayer_panel.tab_container.current_tab = 0
settings_panel.show()
$MainPanelContainer.hide()
show()
func _on_quit_pressed() -> void:
get_tree().quit()
Game.quit()
func _on_main_menu_pressed() -> void:
$MultiplayerPanelContainer.hide()
$MultiplayerPanelContainer.tab_container.current_tab = 0
$SettingsPanelContainer.hide()
multiplayer_panel.hide()
settings_panel.hide()
multiplayer_panel.tab_container.current_tab = 0
$MainPanelContainer.show()
show()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,22 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name HostPanel extends MarginContainer
@export var host_button : Button
@export var menu_button : Button
@export var quit_button : Button
@export var server_port : LineEdit
@export var map_selector : MapSelector
@export var mode_selector : ModeSelector

View file

@ -0,0 +1,97 @@
[gd_scene load_steps=4 format=3 uid="uid://dv0lqek8bqyv"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/host_panel/host_panel.gd" id="1_wnvng"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/host_panel/map_selector.gd" id="2_kwlr3"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/host_panel/mode_selector.gd" id="3_o6ecq"]
[node name="HostPanel" type="MarginContainer" node_paths=PackedStringArray("host_button", "menu_button", "quit_button", "server_port", "map_selector", "mode_selector")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("1_wnvng")
host_button = NodePath("HBoxContainer/LeftBox/Top/Host")
menu_button = NodePath("HBoxContainer/LeftBox/Bottom/Menu")
quit_button = NodePath("HBoxContainer/LeftBox/Bottom/Quit")
server_port = NodePath("HBoxContainer/RightBox/GridContainer/ServerPort")
map_selector = NodePath("HBoxContainer/RightBox/GridContainer/MapSelector")
mode_selector = NodePath("HBoxContainer/RightBox/GridContainer/ModeSelector")
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 2
theme_override_constants/separation = 20
[node name="LeftBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Top" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Host" type="Button" parent="HBoxContainer/LeftBox/Top"]
layout_mode = 2
text = "Host"
[node name="Bottom" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_vertical = 10
[node name="Menu" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Main Menu
"
[node name="Quit" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Quit"
[node name="RightBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="MapPreview" type="ColorRect" parent="HBoxContainer/RightBox"]
layout_mode = 2
[node name="GridContainer" type="GridContainer" parent="HBoxContainer/RightBox"]
layout_mode = 2
theme_override_constants/h_separation = 120
columns = 2
[node name="PortLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
text = "Port"
[node name="ServerPort" type="LineEdit" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
placeholder_text = "9000"
alignment = 2
[node name="MapLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
text = "Map"
[node name="MapSelector" type="OptionButton" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
clip_text = true
allow_reselect = true
script = ExtResource("2_kwlr3")
[node name="ModeLabel" type="Label" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
text = "Mode"
[node name="ModeSelector" type="OptionButton" parent="HBoxContainer/RightBox/GridContainer"]
layout_mode = 2
script = ExtResource("3_o6ecq")

View file

@ -0,0 +1,21 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name MapSelector extends OptionButton
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
for map : PackedScene in MapsManager.maps:
var map_name : String = map._bundled.names[0]
add_item(map_name)

View file

@ -0,0 +1,33 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name ModeSelector extends OptionButton
func format(enum_key: String) -> String:
# split enum value by underscores
var words : PackedStringArray = enum_key.split("_")
# capitalize first letter of each word
for i in range(words.size()):
words[i] = words[i].capitalize()
# join words with spaces
return " ".join(words)
func _ready() -> void:
for mode:String in Multiplayer.Mode.keys():
add_item(format(mode))
# @NOTE: ctf, arena and ball are not implemented yet
set_item_disabled(2, true)
set_item_disabled(3, true)
set_item_disabled(4, true)

View file

@ -0,0 +1,20 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name JoinPanel extends MarginContainer
@export var join_button : Button
@export var menu_button : Button
@export var quit_button : Button
@export var join_address : LineEdit

View file

@ -0,0 +1,62 @@
[gd_scene load_steps=2 format=3 uid="uid://cfegls11p6wav"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/join_panel/join_panel.gd" id="1_svm4h"]
[node name="JoinPanel" type="MarginContainer" node_paths=PackedStringArray("join_button", "menu_button", "quit_button", "join_address")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("1_svm4h")
join_button = NodePath("HBoxContainer/LeftBox/Top/Join")
menu_button = NodePath("HBoxContainer/LeftBox/Bottom/Menu")
quit_button = NodePath("HBoxContainer/LeftBox/Bottom/Quit")
join_address = NodePath("HBoxContainer/RightBox/JoinAddress")
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 2
theme_override_constants/separation = 20
[node name="LeftBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Top" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Join" type="Button" parent="HBoxContainer/LeftBox/Top"]
layout_mode = 2
text = "Join"
[node name="Bottom" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_vertical = 10
[node name="Menu" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Main Menu
"
[node name="Quit" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Quit"
[node name="RightBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="JoinAddress" type="LineEdit" parent="HBoxContainer/RightBox"]
layout_mode = 2
placeholder_text = "localhost"

View file

@ -0,0 +1,98 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name MultiplayerPanelContainer extends PanelContainer
const DEFAULT_HOST : String = "localhost"
const DEFAULT_PORT : int = 9000
const CONFIG_FILE_PATH : String = "user://profile.cfg"
var _join_address : RegEx = RegEx.new()
var _registered_ports : RegEx = RegEx.new()
var _config_file : ConfigFile = ConfigFile.new()
signal menu_pressed # reuse signal for all tabs
signal start_server(port : int, map : PackedScene, mode: Multiplayer.Mode, username: String)
signal join_server(host : String, port : int)
@export var tab_container : TabContainer
@export var profile_panel : ProfilePanel
@export var join_panel : JoinPanel
@export var host_panel : HostPanel
@onready var modal : Control = $Modal
func _ready() -> void:
# see https://datatracker.ietf.org/doc/html/rfc1700
_registered_ports.compile(r'^(?:102[4-9]|10[3-9]\d|1[1-9]\d{2}|[2-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$')
_join_address.compile(r'^(?<host>[a-zA-Z0-9.-]+)(:(?<port>:102[4-9]|10[3-9]\d|1[1-9]\d{2}|[2-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5]))?$')
# connect signals
join_panel.join_button.pressed.connect(_on_join_pressed)
host_panel.host_button.pressed.connect(_on_host_pressed)
for panel:Control in [profile_panel, host_panel, join_panel]:
panel.menu_button.pressed.connect(_on_menu_pressed)
panel.quit_button.pressed.connect(_on_quit_pressed)
# load configuration file
_load_config()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("exit"):
modal.hide()
func _load_config() -> void:
var error : Error = _config_file.load(CONFIG_FILE_PATH)
if error != OK:
return
profile_panel.profile_name.text = _config_file.get_value("profile", "name", "Newblood")
func _on_save_pressed() -> void:
_config_file.set_value("profile", "name", profile_panel.profile_name.text)
_config_file.save(CONFIG_FILE_PATH)
func _on_menu_pressed() -> void:
menu_pressed.emit()
func _on_quit_pressed() -> void:
get_tree().quit()
func _on_host_pressed() -> void:
var port : int = DEFAULT_PORT
# check for registered ports number matches
if host_panel.server_port.text:
var result : RegExMatch = _registered_ports.search(host_panel.server_port.text)
if result: # port is valid
port = int(result.get_string())
else: # port is not valid
push_warning("A valid port number in the range 1024-65535 is required.")
return
start_server.emit(
port,
MapsManager.maps[host_panel.map_selector.selected],
host_panel.mode_selector.selected,
profile_panel.profile_name.text
)
func _on_join_pressed() -> void:
var addr : Array = [DEFAULT_HOST, DEFAULT_PORT]
# validate join address input
var result : RegExMatch = _join_address.search(join_panel.join_address.text)
if result: # address is valid
addr[0] = result.get_string("host")
var rport : String = result.get_string("port")
if rport: addr[1] = int(rport)
modal.show()
join_server.emit(addr[0], addr[1], profile_panel.profile_name.text)

View file

@ -0,0 +1,79 @@
[gd_scene load_steps=6 format=3 uid="uid://7chfb47enqwm"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/multiplayer_panel_container.gd" id="1_yyvwh"]
[ext_resource type="PackedScene" uid="uid://cfegls11p6wav" path="res://interfaces/menus/boot/multiplayer/join_panel/join_panel.tscn" id="2_4vm27"]
[ext_resource type="PackedScene" uid="uid://moey0w3677td" path="res://interfaces/menus/boot/multiplayer/profile_panel/profile_panel.tscn" id="2_aidbu"]
[ext_resource type="PackedScene" uid="uid://dv0lqek8bqyv" path="res://interfaces/menus/boot/multiplayer/host_panel/host_panel.tscn" id="2_ameih"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_krqeq"]
bg_color = Color(0.501961, 0.501961, 0.501961, 0.25098)
[node name="MultiplayerPanelContainer" type="PanelContainer" node_paths=PackedStringArray("tab_container", "profile_panel", "join_panel", "host_panel")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_krqeq")
script = ExtResource("1_yyvwh")
tab_container = NodePath("MarginContainer/VBoxContainer/TabContainer")
profile_panel = NodePath("MarginContainer/VBoxContainer/TabContainer/Profile/ProfilePanel")
join_panel = NodePath("MarginContainer/VBoxContainer/TabContainer/Join/JoinPanel")
host_panel = NodePath("MarginContainer/VBoxContainer/TabContainer/Host/HostPanel")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/side_margin = 0
[node name="Profile" type="TabBar" parent="MarginContainer/VBoxContainer/TabContainer"]
layout_mode = 2
theme_override_constants/h_separation = 0
[node name="ProfilePanel" parent="MarginContainer/VBoxContainer/TabContainer/Profile" instance=ExtResource("2_aidbu")]
layout_mode = 1
[node name="Join" type="TabBar" parent="MarginContainer/VBoxContainer/TabContainer"]
visible = false
layout_mode = 2
select_with_rmb = true
[node name="JoinPanel" parent="MarginContainer/VBoxContainer/TabContainer/Join" instance=ExtResource("2_4vm27")]
layout_mode = 1
[node name="Host" type="TabBar" parent="MarginContainer/VBoxContainer/TabContainer"]
visible = false
layout_mode = 2
select_with_rmb = true
[node name="HostPanel" parent="MarginContainer/VBoxContainer/TabContainer/Host" instance=ExtResource("2_ameih")]
layout_mode = 1
[node name="Modal" type="Panel" parent="."]
visible = false
layout_mode = 2
[node name="Label" type="Label" parent="Modal"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -59.5
offset_top = -11.5
offset_right = 59.5
offset_bottom = 11.5
grow_horizontal = 2
grow_vertical = 2
text = "CONNECTING..."

View file

@ -0,0 +1,22 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name ProfilePanel extends MarginContainer
@export var create_button : Button
@export var delete_button : Button
@export var save_button : Button
@export var menu_button : Button
@export var quit_button : Button
@export var profile_name : LineEdit

View file

@ -0,0 +1,79 @@
[gd_scene load_steps=2 format=3 uid="uid://moey0w3677td"]
[ext_resource type="Script" path="res://interfaces/menus/boot/multiplayer/profile_panel/profile_panel.gd" id="1_e3jmb"]
[node name="ProfilePanel" type="MarginContainer" node_paths=PackedStringArray("create_button", "delete_button", "save_button", "menu_button", "quit_button", "profile_name")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
script = ExtResource("1_e3jmb")
create_button = NodePath("HBoxContainer/LeftBox/Top/Create")
delete_button = NodePath("HBoxContainer/LeftBox/Top/Delete")
save_button = NodePath("HBoxContainer/LeftBox/Top/Save")
menu_button = NodePath("HBoxContainer/LeftBox/Bottom/Menu")
quit_button = NodePath("HBoxContainer/LeftBox/Bottom/Quit")
profile_name = NodePath("HBoxContainer/RightBox/ProfileName")
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 2
theme_override_constants/separation = 20
[node name="LeftBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Top" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.25
[node name="Create" type="Button" parent="HBoxContainer/LeftBox/Top"]
layout_mode = 2
disabled = true
text = "Create"
[node name="Delete" type="Button" parent="HBoxContainer/LeftBox/Top"]
layout_mode = 2
disabled = true
text = "Delete"
[node name="Save" type="Button" parent="HBoxContainer/LeftBox/Top"]
layout_mode = 2
text = "Save"
[node name="Bottom" type="VBoxContainer" parent="HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_vertical = 10
[node name="Menu" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Main Menu
"
[node name="Quit" type="Button" parent="HBoxContainer/LeftBox/Bottom"]
layout_mode = 2
size_flags_horizontal = 3
text = "Quit"
[node name="RightBox" type="VBoxContainer" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Label" type="Label" parent="HBoxContainer/RightBox"]
layout_mode = 2
text = "Current Profile:"
[node name="ProfileName" type="LineEdit" parent="HBoxContainer/RightBox"]
layout_mode = 2
size_flags_horizontal = 3
text = "Newblood"

View file

@ -0,0 +1,32 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("video", "filter"))
func _on_item_selected(index: int) -> void:
Settings.set_value("video", "filter", index)
# Viewport scale mode setting.
if index == 0: # Bilinear (Fastest)
get_viewport().scaling_3d_mode = Viewport.SCALING_3D_MODE_BILINEAR
# FSR Sharpness is only effective when the scaling mode is FSR 1.0.
%FSRSharpnessLabel.visible = false
%FSRSharpnessSlider.visible = false
elif index == 1: # FSR 1.0 (Fast)
get_viewport().scaling_3d_mode = Viewport.SCALING_3D_MODE_FSR
# FSR Sharpness is only effective when the scaling mode is FSR 1.0.
%FSRSharpnessLabel.visible = true
%FSRSharpnessSlider.visible = true

View file

@ -0,0 +1,39 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends HBoxContainer
@export var min_value : int = 70
@export var max_value : int = 150
@export var step : int = 1
func _ready() -> void:
var value : int = Settings.get_value("video", "fov")
for control : Range in [$SpinBox, $Slider]:
control.min_value = min_value
control.max_value = max_value
control.step = step
control.value = value
_on_value_changed(value)
func _on_value_changed(new_value : int) -> void:
Settings.set_value("video", "fov", new_value)
#
func _on_spin_box_value_changed(new_value : int) -> void:
_on_value_changed(new_value)
$Slider.value = new_value
#
func _on_slider_value_changed(new_value : int) -> void:
_on_value_changed(new_value)
$SpinBox.value = new_value

View file

@ -0,0 +1,26 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends HSlider
func _ready() -> void:
self.value = Settings.get_value("video", "fsr_sharpness")
self.value_changed.emit(self.value)
func _on_value_changed(new_value : float) -> void:
Settings.set_value("video", "fsr_sharpness", new_value)
# Lower FSR sharpness values result in a sharper image.
# Invert the slider so that higher values result in a sharper image,
# which is generally expected from users.
get_viewport().fsr_sharpness = 2.0 - new_value

View file

@ -0,0 +1,24 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("video", "fxaa"))
func _on_item_selected(index: int) -> void:
Settings.set_value("video", "fxaa", index)
# Fast approximate anti-aliasing. Much faster than MSAA (and works on alpha scissor edges),
# but blurs the whole scene rendering slightly.
get_viewport().screen_space_aa = int(index == 1) as Viewport.ScreenSpaceAA

View file

@ -0,0 +1,30 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("environment", "glow"))
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "glow", index)
## This is a setting that is attached to the environment.
## If your game requires you to change the environment,
## then be sure to run this function again to make the setting effective.
if index == 0: # Disabled (default)
Game.environment.glow_enabled = false
elif index == 1: # Low
Game.environment.glow_enabled = true
elif index == 2: # High
Game.environment.glow_enabled = true

View file

@ -0,0 +1,32 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("quality", "mesh_lod"))
func _on_item_selected(index : int) -> void:
Settings.set_value("quality", "mesh_lod", index)
if index == 0: # Very Low
get_viewport().mesh_lod_threshold = 8.0
if index == 0: # Low
get_viewport().mesh_lod_threshold = 4.0
if index == 1: # Medium
get_viewport().mesh_lod_threshold = 2.0
if index == 2: # High (default)
get_viewport().mesh_lod_threshold = 1.0
if index == 3: # Ultra
# Always use highest LODs to avoid any form of pop-in.
get_viewport().mesh_lod_threshold = 0.0

View file

@ -0,0 +1,39 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends HBoxContainer
@export var min_value : float = .01
@export var max_value : float = 1.
@export var step : float = .01
func _ready() -> void:
var value : float = Settings.get_value("controls", "mouse_sensitivity")
for control : Range in [$SpinBox, $Slider]:
control.min_value = min_value
control.max_value = max_value
control.step = step
control.value = value
_on_value_changed(value)
func _on_value_changed(new_value : float) -> void:
Settings.set_value("controls", "mouse_sensitivity", new_value)
func _on_spin_box_value_changed(new_value : float) -> void:
_on_value_changed(new_value)
$Slider.value = new_value
func _on_slider_value_changed(new_value : float) -> void:
_on_value_changed(new_value)
$SpinBox.value = new_value

View file

@ -0,0 +1,31 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("video", "msaa"))
func _on_item_selected(index: int) -> void:
Settings.set_value("video", "msaa", index)
# Multi-sample anti-aliasing. High quality, but slow. It also does not smooth out the edges of
# transparent (alpha scissor) textures.
if index == 0: # Disabled (default)
get_viewport().msaa_3d = Viewport.MSAA_DISABLED
elif index == 1: # 2×
get_viewport().msaa_3d = Viewport.MSAA_2X
elif index == 2: # 4×
get_viewport().msaa_3d = Viewport.MSAA_4X
elif index == 3: # 8×
get_viewport().msaa_3d = Viewport.MSAA_8X

View file

@ -0,0 +1,40 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends HBoxContainer
@export var min_value : float = 0.25
@export var max_value : float = 2
@export var step : float = .05
func _ready() -> void:
var value : float = Settings.get_value("video", "quality")
for control : Range in [$SpinBox, $Slider]:
control.min_value = min_value
control.max_value = max_value
control.step = step
control.value = value
get_viewport().scaling_3d_scale = value
func _on_value_changed(new_value : float) -> void:
Settings.set_value("video", "quality", new_value)
get_viewport().scaling_3d_scale = new_value
func _on_spin_box_value_changed(new_value : float) -> void:
_on_value_changed(new_value)
$Slider.value = new_value
#
func _on_slider_value_changed(new_value : float) -> void:
_on_value_changed(new_value)
$SpinBox.value = new_value

View file

@ -0,0 +1,32 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("environment", "sdfgi"))
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "sdfgi", index)
# This is a setting that is attached to the environment.
# If your game requires you to change the environment,
# then be sure to run this function again to make the setting effective.
if index == 0: # Disabled (default)
Game.environment.sdfgi_enabled = false
elif index == 1: # Low
Game.environment.sdfgi_enabled = true
RenderingServer.gi_set_use_half_resolution(true)
elif index == 2: # High
Game.environment.sdfgi_enabled = true
RenderingServer.gi_set_use_half_resolution(false)

View file

@ -0,0 +1,39 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("quality", "shadow_filter"))
func _on_item_selected(index : int) -> void:
Settings.set_value("quality", "shadow_filter", index)
if index == 0: # Very Low
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_HARD)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_HARD)
if index == 1: # Low
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_VERY_LOW)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_VERY_LOW)
if index == 2: # Medium (default)
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_LOW)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_LOW)
if index == 3: # High
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_MEDIUM)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_MEDIUM)
if index == 4: # Very High
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_HIGH)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_HIGH)
if index == 5: # Ultra
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_ULTRA)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_ULTRA)

View file

@ -0,0 +1,56 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("quality", "shadow_size"))
func _on_item_selected(index : int) -> void:
Settings.set_value("quality", "shadow_size", index)
if index == 0: # Minimum
RenderingServer.directional_shadow_atlas_set_size(512, true)
# Adjust shadow bias according to shadow resolution.
# Higher resultions can use a lower bias without suffering from shadow acne.
#Settings.set_value("quality", "shadow_bias", 0.06)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
# Disable positional (omni/spot) light shadows entirely to further improve performance.
# These often don't contribute as much to a scene compared to directional light shadows.
get_viewport().positional_shadow_atlas_size = 0
if index == 1: # Very Low
RenderingServer.directional_shadow_atlas_set_size(1024, true)
#Settings.set_value("quality", "shadow_bias", 0.04)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
get_viewport().positional_shadow_atlas_size = 1024
if index == 2: # Low
RenderingServer.directional_shadow_atlas_set_size(2048, true)
#Settings.set_value("quality", "shadow_bias", 0.03)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
get_viewport().positional_shadow_atlas_size = 2048
if index == 3: # Medium (default)
RenderingServer.directional_shadow_atlas_set_size(4096, true)
#Settings.set_value("quality", "shadow_bias", 0.02)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
get_viewport().positional_shadow_atlas_size = 4096
if index == 4: # High
RenderingServer.directional_shadow_atlas_set_size(8192, true)
#Settings.set_value("quality", "shadow_bias", 0.01)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
get_viewport().positional_shadow_atlas_size = 8192
if index == 5: # Ultra
RenderingServer.directional_shadow_atlas_set_size(16384, true)
#Settings.set_value("quality", "shadow_bias", 0.005)
#directional_light.shadow_bias = Settings.get_value("quality", "shadow_bias")
get_viewport().positional_shadow_atlas_size = 16384

View file

@ -0,0 +1,38 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("environment", "ssao"))
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "ssao", index)
# This is a setting that is attached to the environment.
# If your game requires you to change the environment,
# then be sure to run this function again to make the setting effective.
if index == 0: # Disabled (default)
Game.environment.ssao_enabled = false
elif index == 1: # Very Low
Game.environment.ssao_enabled = true
RenderingServer.environment_set_ssao_quality(RenderingServer.ENV_SSAO_QUALITY_VERY_LOW, true, 0.5, 2, 50, 300)
elif index == 2: # Low
Game.environment.ssao_enabled = true
RenderingServer.environment_set_ssao_quality(RenderingServer.ENV_SSAO_QUALITY_VERY_LOW, true, 0.5, 2, 50, 300)
elif index == 3: # Medium
Game.environment.ssao_enabled = true
RenderingServer.environment_set_ssao_quality(RenderingServer.ENV_SSAO_QUALITY_MEDIUM, true, 0.5, 2, 50, 300)
elif index == 4: # High
Game.environment.ssao_enabled = true
RenderingServer.environment_set_ssao_quality(RenderingServer.ENV_SSAO_QUALITY_HIGH, true, 0.5, 2, 50, 300)

View file

@ -0,0 +1,38 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("environment", "ssil"))
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "ssil", index)
# This is a setting that is attached to the environment.
# If your game requires you to change the environment,
# then be sure to run this function again to make the setting effective.
if index == 0: # Disabled (default)
Game.environment.ssil_enabled = false
if index == 1: # Very Low
Game.environment.ssil_enabled = true
RenderingServer.environment_set_ssil_quality(RenderingServer.ENV_SSIL_QUALITY_VERY_LOW, true, 0.5, 4, 50, 300)
if index == 2: # Low
Game.environment.ssil_enabled = true
RenderingServer.environment_set_ssil_quality(RenderingServer.ENV_SSIL_QUALITY_LOW, true, 0.5, 4, 50, 300)
if index == 3: # Medium
Game.environment.ssil_enabled = true
RenderingServer.environment_set_ssil_quality(RenderingServer.ENV_SSIL_QUALITY_MEDIUM, true, 0.5, 4, 50, 300)
if index == 4: # High
Game.environment.ssil_enabled = true
RenderingServer.environment_set_ssil_quality(RenderingServer.ENV_SSIL_QUALITY_HIGH, true, 0.5, 4, 50, 300)

View file

@ -0,0 +1,35 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("environment", "ssr"))
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "ssr", index)
# This is a setting that is attached to the environment.
# If your game requires you to change the environment,
# then be sure to run this function again to make the setting effective.
if index == 0: # Disabled (default)
Game.environment.ssr_enabled = false
elif index == 1: # Low
Game.environment.ssr_enabled = true
Game.environment.ssr_max_steps = 8
elif index == 2: # Medium
Game.environment.ssr_enabled = true
Game.environment.ssr_max_steps = 32
elif index == 3: # High
Game.environment.ssr_enabled = true
Game.environment.ssr_max_steps = 56

View file

@ -0,0 +1,26 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("video", "taa"))
func _on_item_selected(index: int) -> void:
Settings.set_value("video", "taa", index)
# Temporal antialiasing. Smooths out everything including specular aliasing,
# but can introduce ghosting artifacts and blurring in motion.
# Moderate performance cost.
# @WARNING: https://github.com/TokisanGames/Terrain3D/issues/302
# get_viewport().use_taa = index == 1

View file

@ -0,0 +1,42 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
self.selected = Settings.get_value("ui", "scale")
self.item_selected.emit(self.selected)
func _on_item_selected(index: int) -> void:
Settings.set_value("ui", "scale", clamp(index, 0, 2))
# When the screen changes size, we need to update the 3D
# viewport quality setting. If we don't do this, the viewport will take
# the size from the main viewport.
var new_size := Vector2(
ProjectSettings.get_setting(&"display/window/size/viewport_width"),
ProjectSettings.get_setting(&"display/window/size/viewport_height")
)
# compute new size
if index == 0: # Smaller (66%)
new_size *= 1.5
elif index == 1: # Small (80%)
new_size *= 1.25
elif index == 2: # Medium (100%) (default)
new_size *= 1.
elif index == 3: # Large (133%)
new_size *= .75
elif index == 4: # Larger (200%)
new_size *= .5
# update scale
get_tree().root.set_content_scale_size(new_size)

View file

@ -0,0 +1,30 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
self.selected = Settings.get_value("environment", "volumetric_fog")
self.item_selected.emit(self.selected)
func _on_item_selected(index: int) -> void:
Settings.set_value("environment", "volumetric_fog", index)
if index == 0: # Disabled (default)
Game.environment.volumetric_fog_enabled = false
if index == 1: # Low
Game.environment.volumetric_fog_enabled = true
RenderingServer.environment_set_volumetric_fog_filter_active(false)
if index == 2: # High
Game.environment.volumetric_fog_enabled = true
RenderingServer.environment_set_volumetric_fog_filter_active(true)

View file

@ -0,0 +1,33 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
select(Settings.get_value("video", "vsync"))
func _on_item_selected(index : int) -> void:
Settings.set_value("video", "vsync", index)
# Vsync is enabled by default.
# Vertical synchronization locks framerate and makes screen tearing not visible at the cost of
# higher input latency and stuttering when the framerate target is not met.
# Adaptive V-Sync automatically disables V-Sync when the framerate target is not met, and enables
# V-Sync otherwise. This prevents suttering and reduces input latency when the framerate target
# is not met, at the cost of visible tearing.
if index == 0: # Disabled (default)
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
elif index == 1: # Adaptive
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ADAPTIVE)
elif index == 2: # Enabled
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)

View file

@ -0,0 +1,28 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
extends OptionButton
func _ready() -> void:
var window_mode : DisplayServer.WindowMode = Settings.get_value("video", "window_mode")
select(DisplayServer.WINDOW_MODE_WINDOWED if OS.is_debug_build() else window_mode)
func _on_item_selected(index : int) -> void:
Settings.set_value("video", "window_mode", clampi(index, 0, 2))
if index == 0: # Windowed (default)
get_tree().root.set_mode(Window.MODE_WINDOWED)
elif index == 1: # Fullscreen
get_tree().root.set_mode(Window.MODE_FULLSCREEN)
elif index == 2: # Exclusive Fullscreen
get_tree().root.set_mode(Window.MODE_EXCLUSIVE_FULLSCREEN)

View file

@ -0,0 +1,114 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name SettingsPanelContainer extends PanelContainer
signal closed
# Quality presets.
func _on_very_low_preset_pressed() -> void:
%TAAOptionButton.select(0)
%MSAAOptionButton.select(0)
%FXAAOptionButton.select(0)
%ShadowSizeOptionButton.select(0)
%ShadowFilterOptionButton.select(0)
%MeshLODOptionButton.select(0)
%SDFGIOptionButton.select(0)
%GlowOptionButton.select(0)
%SSAOOptionButton.select(0)
%SSReflectionsOptionButton.select(0)
%SSILOptionButton.select(0)
%VolumetricFogOptionButton.select(0)
func _on_low_preset_pressed() -> void:
%TAAOptionButton.select(0)
%MSAAOptionButton.select(0)
%FXAAOptionButton.select(1)
%ShadowSizeOptionButton.select(1)
%ShadowFilterOptionButton.select(1)
%MeshLODOptionButton.select(1)
%SDFGIOptionButton.select(0)
%GlowOptionButton.select(0)
%SSAOOptionButton.select(0)
%SSReflectionsOptionButton.select(0)
%SSILOptionButton.select(0)
%VolumetricFogOptionButton.select(0)
func _on_medium_preset_pressed() -> void:
%TAAOptionButton.select(1)
%MSAAOptionButton.select(0)
%FXAAOptionButton.select(0)
%ShadowSizeOptionButton.select(2)
%ShadowFilterOptionButton.select(2)
%MeshLODOptionButton.select(1)
%SDFGIOptionButton.select(1)
%GlowOptionButton.select(1)
%SSAOOptionButton.select(1)
%SSReflectionsOptionButton.select(1)
%SSILOptionButton.select(0)
%VolumetricFogOptionButton.select(1)
func _on_high_preset_pressed() -> void:
%TAAOptionButton.select(1)
%MSAAOptionButton.select(0)
%FXAAOptionButton.select(0)
%ShadowSizeOptionButton.select(3)
%ShadowFilterOptionButton.select(3)
%MeshLODOptionButton.select(2)
%SDFGIOptionButton.select(1)
%GlowOptionButton.select(2)
%SSAOOptionButton.select(2)
%SSReflectionsOptionButton.select(2)
%SSILOptionButton.select(2)
%VolumetricFogOptionButton.select(2)
func _on_ultra_preset_pressed() -> void:
%TAAOptionButton.select(1)
%MSAAOptionButton.select(1)
%FXAAOptionButton.select(0)
%ShadowSizeOptionButton.select(4)
%ShadowFilterOptionButton.select(4)
%MeshLODOptionButton.select(3)
%SDFGIOptionButton.select(2)
%GlowOptionButton.select(2)
%SSAOOptionButton.select(3)
%SSReflectionsOptionButton.select(3)
%SSILOptionButton.select(3)
%VolumetricFogOptionButton.select(2)
func _on_apply_pressed() -> void:
Settings.save()
func _on_reset_pressed() -> void:
Settings.reset()
# @TODO: reset also settings user interface to render actual state
func _on_close_pressed() -> void:
hide()
closed.emit()
# Adjustment settings.
#func _on_brightness_slider_value_changed(value: float) -> void:
# The slider value is clamped between 0.5 and 4.
#world_environment.environment.set_adjustment_brightness(value)
#func _on_contrast_slider_value_changed(value: float) -> void:
# The slider value is clamped between 0.5 and 4.
#world_environment.environment.set_adjustment_contrast(value)
#func _on_saturation_slider_value_changed(value: float) -> void:
# The slider value is clamped between 0.5 and 10.
#world_environment.environment.set_adjustment_saturation(value)

View file

@ -0,0 +1,704 @@
[gd_scene load_steps=22 format=3 uid="uid://cvu66n4bm10w3"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/ui_scale.gd" id="1_b2atp"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/settings_panel_container.gd" id="1_c6l0i"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/mouse_sensitivity.gd" id="2_xrhb7"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/fov.gd" id="3_eemxr"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/quality.gd" id="4_n2pno"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/filters.gd" id="5_v6h66"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/fsr_sharpness.gd" id="6_ahtl5"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/window_mode.gd" id="7_rfyne"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/vsync.gd" id="8_tdbn8"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/taa.gd" id="9_ogr52"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/msaa.gd" id="10_hsx6v"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/fxaa.gd" id="11_qd7o2"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/shadow_size.gd" id="12_53fxd"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/shadow_filter.gd" id="13_tast2"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/mesh_lod.gd" id="14_gekxq"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/sdfgi.gd" id="15_yf3v0"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/glow.gd" id="16_pq7lj"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/ssao.gd" id="17_xi4oy"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/ssr.gd" id="18_dprjc"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/ssil.gd" id="19_myuy8"]
[ext_resource type="Script" path="res://interfaces/menus/boot/settings/scripts/volumetric_fog.gd" id="20_wf7u8"]
[node name="SettingsPanelContainer" type="PanelContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
script = ExtResource("1_c6l0i")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer"]
custom_minimum_size = Vector2(480, 0)
layout_mode = 2
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/margin_left = 15
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 15
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/MarginContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/separation = 10
[node name="PresetSection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.682353, 0.917647, 1, 1)
text = "Presets"
horizontal_alignment = 1
[node name="Presets" type="HBoxContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="VeryLowPreset" type="Button" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets"]
layout_mode = 2
size_flags_horizontal = 3
text = "Very Low"
[node name="LowPreset" type="Button" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets"]
layout_mode = 2
size_flags_horizontal = 3
text = "Low"
[node name="MediumPreset" type="Button" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets"]
layout_mode = 2
size_flags_horizontal = 3
text = "Medium"
[node name="HighPreset" type="Button" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets"]
layout_mode = 2
size_flags_horizontal = 3
text = "High"
[node name="UltraPreset" type="Button" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets"]
layout_mode = 2
size_flags_horizontal = 3
text = "Ultra"
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="UISection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "User Interface Settings"
horizontal_alignment = 1
[node name="UIGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
columns = 2
[node name="UIScaleLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/UIGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "UI Scale:"
[node name="UIScaleOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/UIGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 5
selected = 2
popup/item_0/text = "Smaller (66%)"
popup/item_0/id = 0
popup/item_1/text = "Small (80%)"
popup/item_1/id = 1
popup/item_2/text = "Medium (100%)"
popup/item_2/id = 2
popup/item_3/text = "Large (133%)"
popup/item_3/id = 3
popup/item_4/text = "Larger (200%)"
popup/item_4/id = 4
script = ExtResource("1_b2atp")
[node name="ControlsSection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "Controls Settings"
horizontal_alignment = 1
[node name="ControlsGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
columns = 2
[node name="SensitivityLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Mouse sensitivity"
[node name="SensitivityControls" type="HBoxContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
script = ExtResource("2_xrhb7")
[node name="SpinBox" type="SpinBox" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls"]
layout_mode = 2
[node name="Slider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
[node name="InvertedYLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Inverted Y"
[node name="InvertedYCheckbox" type="CheckBox" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
[node name="ViewportSection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "Video Settings"
horizontal_alignment = 1
[node name="ViewportGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
columns = 2
[node name="FOVLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Field of View:"
[node name="FOVControls" type="HBoxContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
script = ExtResource("3_eemxr")
[node name="SpinBox" type="SpinBox" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls"]
layout_mode = 2
min_value = 70.0
max_value = 150.0
value = 90.0
[node name="Slider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
min_value = 70.0
max_value = 150.0
value = 90.0
[node name="QualityLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Resolution Scale:"
[node name="QualityControls" type="HBoxContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
script = ExtResource("4_n2pno")
[node name="SpinBox" type="SpinBox" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls"]
layout_mode = 2
[node name="Slider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
[node name="FilterLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Display Filter:"
[node name="FilterOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 2
selected = 0
popup/item_0/text = "Bilinear (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "FSR 1.0 (Fast)"
popup/item_1/id = 1
script = ExtResource("5_v6h66")
[node name="FSRSharpnessLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "FSR Sharpness:"
[node name="FSRSharpnessSlider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
max_value = 2.0
step = 0.2
script = ExtResource("6_ahtl5")
[node name="WindowModeLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Window Mode:"
[node name="WindowModeOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 3
selected = 2
popup/item_0/text = "Windowed"
popup/item_0/id = 0
popup/item_1/text = "Fullscreen"
popup/item_1/id = 1
popup/item_2/text = "Exclusive Fullscreen"
popup/item_2/id = 2
script = ExtResource("7_rfyne")
[node name="VsyncLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "V-Sync:"
[node name="VsyncOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 3
selected = 0
popup/item_0/text = "Disabled"
popup/item_0/id = 0
popup/item_1/text = "Adaptive"
popup/item_1/id = 1
popup/item_2/text = "Enabled"
popup/item_2/id = 2
script = ExtResource("8_tdbn8")
[node name="TAALabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
visible = false
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Anti-Aliasing (TAA):"
[node name="TAAOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 2
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Enabled (Average)"
popup/item_1/id = 1
script = ExtResource("9_ogr52")
[node name="MSAALabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Anti-Aliasing (MSAA):"
[node name="MSAAOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 4
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "2× (Average)"
popup/item_1/id = 1
popup/item_2/text = "4× (Slow)"
popup/item_2/id = 2
popup/item_3/text = "8× (Slower)"
popup/item_3/id = 3
script = ExtResource("10_hsx6v")
[node name="FXAALabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Anti-Aliasing (FXAA):"
[node name="FXAAOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 2
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Enabled (Fast)"
popup/item_1/id = 1
script = ExtResource("11_qd7o2")
[node name="QualitySection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "Quality Settings"
horizontal_alignment = 1
[node name="QualityGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
columns = 2
[node name="ShadowSizeLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Shadow Resolution:"
[node name="ShadowSizeOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 6
selected = 3
popup/item_0/text = "Minimum (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Very Low (Faster)"
popup/item_1/id = 1
popup/item_2/text = "Low (Fast)"
popup/item_2/id = 2
popup/item_3/text = "Medium (Average)"
popup/item_3/id = 3
popup/item_4/text = "High (Slow)"
popup/item_4/id = 4
popup/item_5/text = "Ultra (Slowest)"
popup/item_5/id = 5
script = ExtResource("12_53fxd")
[node name="ShadowFilterLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Shadow Filtering:"
[node name="ShadowFilterOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 6
selected = 2
popup/item_0/text = "Very Low (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Low (Faster)"
popup/item_1/id = 1
popup/item_2/text = "Medium (Fast)"
popup/item_2/id = 2
popup/item_3/text = "High (Average)"
popup/item_3/id = 3
popup/item_4/text = "Very High (Slow)"
popup/item_4/id = 4
popup/item_5/text = "Ultra (Slower)"
popup/item_5/id = 5
script = ExtResource("13_tast2")
[node name="MeshLODLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Model Quality:"
[node name="MeshLODOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 4
selected = 2
popup/item_0/text = "Low (Faster)"
popup/item_0/id = 0
popup/item_1/text = "Medium (Fast)"
popup/item_1/id = 1
popup/item_2/text = "High (Average)"
popup/item_2/id = 2
popup/item_3/text = "Ultra (Slow)"
popup/item_3/id = 3
script = ExtResource("14_gekxq")
[node name="EnvironmentSection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "Effect Settings"
horizontal_alignment = 1
[node name="EnvironmentGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
columns = 2
[node name="SDFGILabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Global Illumination:"
[node name="SDFGIOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 3
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Low (Average)"
popup/item_1/id = 1
popup/item_2/text = "High (Slow)"
popup/item_2/id = 2
script = ExtResource("15_yf3v0")
[node name="GlowLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Bloom:"
[node name="GlowOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 3
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Low (Fast)"
popup/item_1/id = 1
popup/item_2/text = "High (Average)"
popup/item_2/id = 2
script = ExtResource("16_pq7lj")
[node name="SSAOLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Ambient Occlusion:"
[node name="SSAOOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 5
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Very Low (Fast)"
popup/item_1/id = 1
popup/item_2/text = "Low (Fast)"
popup/item_2/id = 2
popup/item_3/text = "Medium (Average)"
popup/item_3/id = 3
popup/item_4/text = "High (Slow)"
popup/item_4/id = 4
script = ExtResource("17_xi4oy")
[node name="SSReflectionsLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 14
text = "Screen-Space Reflections:"
[node name="SSReflectionsOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 4
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Low (Average)"
popup/item_1/id = 1
popup/item_2/text = "Medium (Slow)"
popup/item_2/id = 2
popup/item_3/text = "High (Slower)"
popup/item_3/id = 3
script = ExtResource("18_dprjc")
[node name="SSILLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Screen-Space Lighting:"
[node name="SSILOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 5
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Very Low (Fast)"
popup/item_1/id = 1
popup/item_2/text = "Low (Average)"
popup/item_2/id = 2
popup/item_3/text = "Medium (Slow)"
popup/item_3/id = 3
popup/item_4/text = "High (Slower)"
popup/item_4/id = 4
script = ExtResource("19_myuy8")
[node name="VolumetricFogLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Volumetric Fog:"
[node name="VolumetricFogOptionButton" type="OptionButton" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
item_count = 3
selected = 0
popup/item_0/text = "Disabled (Fastest)"
popup/item_0/id = 0
popup/item_1/text = "Low (Fast)"
popup/item_1/id = 1
popup/item_2/text = "High (Average)"
popup/item_2/id = 2
script = ExtResource("20_wf7u8")
[node name="AdjustmentSection" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(0.683425, 0.916893, 1, 1)
text = "Adjustments"
horizontal_alignment = 1
[node name="AdjustmentsGridContainer" type="GridContainer" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
visible = false
layout_mode = 2
columns = 2
[node name="BrightnessLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Brightness:"
[node name="BrightnessSlider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
min_value = 0.5
max_value = 2.0
step = 0.01
value = 1.0
[node name="ContrastLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Contrast:"
[node name="ContrastSlider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
min_value = 0.5
max_value = 2.0
step = 0.01
value = 1.0
[node name="SaturationLabel" type="Label" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 16
text = "Saturation:"
[node name="SaturationSlider" type="HSlider" parent="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/AdjustmentsGridContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
min_value = 0.01
max_value = 2.0
step = 0.01
value = 1.0
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/margin_left = 15
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 23
theme_override_constants/margin_bottom = 15
[node name="Buttons" type="HBoxContainer" parent="VBoxContainer/MarginContainer"]
layout_mode = 2
[node name="Save" type="Button" parent="VBoxContainer/MarginContainer/Buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Save"
[node name="Reset" type="Button" parent="VBoxContainer/MarginContainer/Buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Reset"
[node name="Close" type="Button" parent="VBoxContainer/MarginContainer/Buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Close"
[connection signal="pressed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets/VeryLowPreset" to="." method="_on_very_low_preset_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets/LowPreset" to="." method="_on_low_preset_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets/MediumPreset" to="." method="_on_medium_preset_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets/HighPreset" to="." method="_on_high_preset_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/Presets/UltraPreset" to="." method="_on_ultra_preset_pressed"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/UIGridContainer/UIScaleOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/UIGridContainer/UIScaleOptionButton" method="_on_item_selected"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls/SpinBox" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls" method="_on_spin_box_value_changed"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls/Slider" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ControlsGridContainer/SensitivityControls" method="_on_slider_value_changed"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls/SpinBox" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls" method="_on_spin_box_value_changed"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls/Slider" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FOVControls" method="_on_slider_value_changed"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls/SpinBox" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls" method="_on_spin_box_value_changed"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls/Slider" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/QualityControls" method="_on_slider_value_changed"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FilterOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FilterOptionButton" method="_on_item_selected"]
[connection signal="value_changed" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FSRSharpnessSlider" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FSRSharpnessSlider" method="_on_value_changed"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/WindowModeOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/WindowModeOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/VsyncOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/VsyncOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/TAAOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/TAAOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/MSAAOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/MSAAOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FXAAOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/ViewportGridContainer/FXAAOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/ShadowSizeOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/ShadowSizeOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/ShadowFilterOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/ShadowFilterOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/MeshLODOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/QualityGridContainer/MeshLODOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SDFGIOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SDFGIOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/GlowOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/GlowOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSAOOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSAOOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSReflectionsOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSReflectionsOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSILOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/SSILOptionButton" method="_on_item_selected"]
[connection signal="item_selected" from="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/VolumetricFogOptionButton" to="VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/EnvironmentGridContainer/VolumetricFogOptionButton" method="_on_item_selected"]
[connection signal="pressed" from="VBoxContainer/MarginContainer/Buttons/Save" to="." method="_on_apply_pressed"]
[connection signal="pressed" from="VBoxContainer/MarginContainer/Buttons/Reset" to="." method="_on_reset_pressed"]
[connection signal="pressed" from="VBoxContainer/MarginContainer/Buttons/Close" to="." method="_on_close_pressed"]

View file

@ -0,0 +1,35 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name DeathmatchScoringComponent extends Node
@export var ON_KILL_SCORE := Vector3i(1,0,0)
signal add_score(peer_id:int, score:Vector3i)
## This method returns a new bound deathmatch scoring component to be added in tree.
func _init(scoreboard:Scoreboard, players: Node) -> void:
add_score.connect(scoreboard.add_score)
players.child_entered_tree.connect(register)
players.child_exiting_tree.connect(unregister)
func register(player: Player) -> void:
player.killed.connect(_on_player_killed)
func unregister(player: Player) -> void:
player.killed.disconnect(_on_player_killed)
func _on_player_killed(victim: Player, killer:int) -> void:
if victim.peer_id != killer:
add_score.emit(killer, ON_KILL_SCORE)

View file

@ -0,0 +1,56 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
## This defines a rabbit scoring component.
class_name RabbitScoringComponent extends Node
const ON_GRAB_SCORE := Vector3i(1,0,0)
const ON_HOLD_SCORE := Vector3i(1,0,0)
const HOLD_SCORING_TIMER:float = 10.0 # seconds
var timer:= Timer.new()
signal add_score(peer_id:int, score:Vector3i)
# @TODO: remove this variable by passing flag to signals `grabbed` and `dropped`
# this if fine for rabbit but will be required for CTF
var _flag: Flag
# This method initializes a new rabbit scoring component.
func _init(scoreboard:Scoreboard, flag:Flag) -> void:
timer.timeout.connect(_on_timer_timeout.bind(flag))
add_score.connect(scoreboard.add_score)
flag.grabbed.connect(_on_flag_grabbed)
flag.dropped.connect(_on_flag_dropped)
_flag = flag
func _ready() -> void:
add_child(timer)
func _on_flag_grabbed(carry: FlagCarryComponent) -> void:
assert(_flag)
# prevent chained grab scoring abuse
if _flag and (not _flag.last_carrier or _flag.last_carrier.owner.peer_id != carry.owner.peer_id):
# set new carrier for `_on_timer_timeout`
_flag.last_carrier = carry
add_score.emit(carry.owner.peer_id, ON_GRAB_SCORE)
timer.start(HOLD_SCORING_TIMER)
func _on_flag_dropped(_carry: FlagCarryComponent) -> void:
assert(_flag)
timer.stop()
func _on_timer_timeout(flag:Flag) -> void:
assert(_flag)
add_score.emit(flag.last_carrier.owner.peer_id, ON_HOLD_SCORE)

View file

@ -0,0 +1,21 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name PingLabel extends Label
@export var entry : ScorePanelEntry
func _on_sync(state: Dictionary) -> void:
if entry.peer_id in state: # update clients only
text = str(state[entry.peer_id])

View file

@ -0,0 +1,80 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
## This defines a score panel to hold [ScorePanelEntry] instances.
class_name ScorePanel extends Panel
# The ScorePanelEntry packed scene to instantiate
@export var _SCORE_PANEL_ENTRY:PackedScene
## This is the panel title.
@export var title:Label
## This is the container for [ScorePanelEntry] child nodes.
@export var entries:VBoxContainer
# This is the iterator index cursor.
var _iter_cursor:int = 0
# This method is an iterator initializer.
func _iter_init(_arg:Variant) -> bool:
_iter_cursor = 0 # reset
return _iter_cursor < entries.get_child_count()
# This method checks if the iterator has a next value.
func _iter_next(_arg:Variant) -> bool:
_iter_cursor += 1
return _iter_cursor < entries.get_child_count()
# This method gets the next iterator value.
func _iter_get(_arg:Variant) -> ScorePanelEntry:
return entries.get_child(_iter_cursor)
func _to_string() -> String:
return "<ScorePanel#%s>" % get_instance_id()
## This method adds an entry to the panel.
func add_entry(peer_id:int, username:String, score:Vector3i = Vector3i.ZERO) -> ScorePanelEntry:
var entry:ScorePanelEntry = _SCORE_PANEL_ENTRY.instantiate()
entry.name = str(peer_id)
entry.peer_id = peer_id
entries.add_child(entry)
entry.ping.text = "" # @TODO: get player ping
entry._username = username
entry._score = score
return entry
## This method removes a [ScorePanelEntry] from the [ScorePanel].
func remove_entry(entry:ScorePanelEntry) -> void:
entries.remove_child(entry)
entry.free()
## This method returns a [ScorePanelEntry] from the [ScorePanel].
func get_entry(index:int) -> ScorePanelEntry:
return entries.get_child(index)
## This method removes a [ScorePanelEntry] from the [ScorePanel] by [param name]
## and returns a boolean to indicate removal state.
func remove_entry_by_name(entry_name:String) -> bool:
var path := NodePath(entry_name)
if entries.has_node(path):
var entry:ScorePanelEntry = entries.get_node(path)
remove_entry(entry)
return true
else:
return false
func remove_entry_by_peer_id(peer_id:int) -> bool:
return remove_entry_by_name(str(peer_id))
func size() -> int:
return entries.get_child_count()

View file

@ -0,0 +1,66 @@
[gd_scene load_steps=4 format=3 uid="uid://p1q2lu7mtte1"]
[ext_resource type="Script" path="res://interfaces/scoreboard/score_panel.gd" id="1_diy54"]
[ext_resource type="PackedScene" uid="uid://bu186wanwk1kh" path="res://interfaces/scoreboard/score_panel_entry.tscn" id="2_54ms2"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_bhp7i"]
properties/0/path = NodePath("MarginContainer/VBoxContainer/Title:text")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath("MarginContainer/VBoxContainer/Title:visible")
properties/1/spawn = true
properties/1/replication_mode = 2
[node name="ScorePanel" type="Panel" node_paths=PackedStringArray("title", "entries")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 2
script = ExtResource("1_diy54")
_SCORE_PANEL_ENTRY = ExtResource("2_54ms2")
title = NodePath("MarginContainer/VBoxContainer/Title")
entries = NodePath("MarginContainer/VBoxContainer/Entries")
[node name="ScorePanelSync" type="MultiplayerSynchronizer" parent="."]
replication_interval = 1.0
delta_interval = 1.0
replication_config = SubResource("SceneReplicationConfig_bhp7i")
[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 = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Title" type="Label" parent="MarginContainer/VBoxContainer"]
visible = false
layout_mode = 2
theme_type_variation = &"HeaderSmall"
text = "PANEL TITLE"
horizontal_alignment = 1
vertical_alignment = 1
uppercase = true
[node name="Headers" parent="MarginContainer/VBoxContainer" instance=ExtResource("2_54ms2")]
layout_mode = 2
[node name="Entries" type="VBoxContainer" parent="MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="EntrySpawner" type="MultiplayerSpawner" parent="MarginContainer/VBoxContainer"]
_spawnable_scenes = PackedStringArray("res://interfaces/scoreboard/score_panel_entry.tscn")
spawn_path = NodePath("../Entries")

View file

@ -0,0 +1,61 @@
# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name ScorePanelEntry extends HBoxContainer
@export var scoring: bool = true
@export var _ping : int:
set = set_ping
@export var _username : String:
set = set_username
@export var _score : Vector3i = Vector3i.ZERO:
set = set_score
@export var ping : PingLabel
@export var username : Label
@export var offense : Label
@export var defense : Label
@export var style : Label
@export var score : Label
var peer_id : int
func get_total() -> int:
return _score.x + _score.y + _score.z
func _to_string() -> String:
return "<ScorePanelEntry(%s)#%s>" % [name, get_instance_id()]
# setters
func set_username(new_username : String) -> void:
_username = new_username
username.text = new_username
func set_ping(new_ping : int) -> void:
_ping = new_ping
ping.text = str(_ping)
func set_score(new_score : Vector3i) -> void:
if scoring:
_score = new_score
offense.text = str(_score.x)
defense.text = str(_score.y)
style.text = str(_score.z)
score.text = str(get_total())
# This is called when the Scoreboard.scoring_state_changed signal is emmitted
func _on_scoring_state_changed(new_scoring: bool) -> void:
scoring = new_scoring

View file

@ -0,0 +1,92 @@
[gd_scene load_steps=4 format=3 uid="uid://bu186wanwk1kh"]
[ext_resource type="Script" path="res://interfaces/scoreboard/score_panel_entry.gd" id="1_ohfvg"]
[ext_resource type="Script" path="res://interfaces/scoreboard/ping_label.gd" id="2_rlg8k"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_hpwcf"]
properties/0/path = NodePath("Ping:text")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath("Username:text")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath("Offense:text")
properties/2/spawn = true
properties/2/replication_mode = 2
properties/3/path = NodePath("Defense:text")
properties/3/spawn = true
properties/3/replication_mode = 2
properties/4/path = NodePath("Style:text")
properties/4/spawn = true
properties/4/replication_mode = 2
properties/5/path = NodePath("Score:text")
properties/5/spawn = true
properties/5/replication_mode = 2
[node name="Entry" type="HBoxContainer" node_paths=PackedStringArray("ping", "username", "offense", "defense", "style", "score")]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 17.0
grow_horizontal = 2
script = ExtResource("1_ohfvg")
ping = NodePath("Ping")
username = NodePath("Username")
offense = NodePath("Offense")
defense = NodePath("Defense")
style = NodePath("Style")
score = NodePath("Score")
[node name="EntrySync" type="MultiplayerSynchronizer" parent="."]
replication_interval = 0.5
delta_interval = 0.5
replication_config = SubResource("SceneReplicationConfig_hpwcf")
[node name="Ping" type="Label" parent="." node_paths=PackedStringArray("entry")]
custom_minimum_size = Vector2(64, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 12
text = "PING"
horizontal_alignment = 1
vertical_alignment = 1
script = ExtResource("2_rlg8k")
entry = NodePath("..")
[node name="Username" type="Label" parent="."]
custom_minimum_size = Vector2(128, 0)
layout_mode = 2
size_flags_horizontal = 3
theme_override_font_sizes/font_size = 12
text = "USERNAME"
vertical_alignment = 1
[node name="Offense" type="Label" parent="."]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 12
text = "O"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Defense" type="Label" parent="."]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 12
text = "D"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Style" type="Label" parent="."]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 12
text = "S"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Score" type="Label" parent="."]
custom_minimum_size = Vector2(96, 0)
layout_mode = 2
theme_override_font_sizes/font_size = 12
text = "SCORE"
horizontal_alignment = 1
vertical_alignment = 1

View file

@ -12,73 +12,118 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
## This defines a scoreboard to track players, scores and teams.
## It is a container for [ScorePanel] instances.
class_name Scoreboard extends Control
@export var _entries : Dictionary = {}
signal scoring_state_changed(new_scoring: bool)
class ScoreboardEntry:
var username : String
var kills : int
var score : int
var username_label : Label = Label.new()
var kills_label : Label = Label.new()
var score_label : Label = Label.new()
# The score panel scene to spawn.
@export var _SCORE_PANEL: PackedScene
## This is the container for [ScorePanel] child nodes.
@export var panels: GridContainer
## This controls whether [Entry] scores can be updated or not.
@export var scoring: bool:
set = set_scoring
func set_scoring(new_scoring: bool) -> void:
scoring = new_scoring
scoring_state_changed.emit(scoring)
func _unhandled_input(event : InputEvent) -> void:
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("scoreboard"):
show()
elif event.is_action_released("scoreboard"):
hide()
func _ready() -> void:
panels.child_entered_tree.connect(_on_score_panel_added)
panels.child_exiting_tree.connect(_on_score_panel_removed)
func add_participant(participant : MatchParticipant) -> void:
_add_scoreboard_entry.rpc(participant.player_id, participant.username)
func _on_score_panel_added(panel: ScorePanel) -> void:
if not panel.entries.child_entered_tree.is_connected(_on_entry_added):
panel.entries.child_entered_tree.connect(_on_entry_added)
func remove_participant(participant : MatchParticipant) -> void:
_remove_scoreboard_entry.rpc(participant.player_id)
func _on_score_panel_removed(panel: ScorePanel) -> void:
if panel.entries.child_entered_tree.is_connected(_on_entry_added):
panel.entries.child_entered_tree.disconnect(_on_entry_added)
func _on_entry_added(entry: ScorePanelEntry) -> void:
if not scoring_state_changed.is_connected(entry._on_scoring_state_changed):
scoring_state_changed.connect(entry._on_scoring_state_changed)
func _on_entry_removed(entry: ScorePanelEntry) -> void:
if scoring_state_changed.is_connected(entry._on_scoring_state_changed):
scoring_state_changed.disconnect(entry._on_scoring_state_changed)
func increment_kill_count(participant : MatchParticipant) -> void:
_entries[participant.player_id].kills += 1
func _on_ping_sync(state: Dictionary) -> void:
for panel: ScorePanel in panels.get_children():
for entry in panel:
entry.ping._on_sync(state)
func add_score_to_player(participant : MatchParticipant, amount : int) -> void:
var player_id : int = participant.player_id
var entry : ScoreboardEntry = _entries[player_id]
_update_scoreboard_entry.rpc(player_id, entry.username, entry.kills, entry.score + amount)
func _to_string() -> String:
return "<Scoreboard#%s>" % get_instance_id()
@rpc("any_peer", "call_remote", "reliable")
func request_scoreboard_from_authority() -> void:
if is_multiplayer_authority():
var recipient_id : int = multiplayer.get_remote_sender_id()
for entry_player_id : int in _entries:
var entry : ScoreboardEntry = _entries[entry_player_id]
_add_scoreboard_entry.rpc_id(recipient_id, entry_player_id, entry.username, entry.kills, entry.score)
## This method adds a [ScorePanel] to the [Scoreboard] and returns a reference to the added [ScorePanel].
func add_panel(panel_name : String = "") -> ScorePanel:
var score_panel: ScorePanel = _SCORE_PANEL.instantiate()
var score_panel_name := str(panel_name)
if score_panel_name.is_valid_identifier():
score_panel.name = score_panel_name
panels.add_child(score_panel)
panels.columns = 2 if panels.get_child_count() > 2 else panels.get_child_count()
return score_panel
@rpc("authority", "call_local", "reliable")
func _add_scoreboard_entry(player_id : int, username : String, kills : int = 0, score : int = 0) -> void:
var new_entry : ScoreboardEntry = ScoreboardEntry.new()
_entries[player_id] = new_entry
%Scores.add_child(new_entry.username_label)
%Scores.add_child(new_entry.kills_label)
%Scores.add_child(new_entry.score_label)
_update_scoreboard_entry(player_id, username, kills, score)
## This method removes a [ScorePanel] from the [Scoreboard].
func remove_panel(panel: ScorePanel) -> void:
panels.remove_child(panel)
panel.free()
@rpc("authority", "call_local", "reliable")
func _update_scoreboard_entry(player_id : int, username : String, kills : int, score : int) -> void:
var entry : ScoreboardEntry = _entries[player_id]
entry.username = username
entry.kills = kills
entry.score = score
_update_scoreboard_entry_ui(player_id)
## This method returns a [ScorePanel] from the [Scoreboard].
func get_panel(index: int) -> ScorePanel:
return panels.get_child(index)
@rpc("authority", "call_local", "reliable")
func _remove_scoreboard_entry(player_id : int) -> void:
var entry : ScoreboardEntry = _entries[player_id]
entry.username_label.queue_free()
entry.kills_label.queue_free()
entry.score_label.queue_free()
_entries.erase(player_id)
## This method removes an entry by its node name in the tree.
func remove_entry_by_name(entry_name: String) -> bool:
for panel : ScorePanel in panels.get_children():
if panel.remove_entry_by_name(entry_name):
return true
return false
func _update_scoreboard_entry_ui(player_id : int) -> void:
var entry : ScoreboardEntry = _entries[player_id]
entry.username_label.text = entry.username
entry.kills_label.text = str(entry.kills)
entry.score_label.text = str(entry.score)
func get_entry(peer_id: int) -> ScorePanelEntry:
for panel : ScorePanel in panels.get_children():
for entry in panel:
if entry.peer_id == peer_id:
return entry
return null
## This method returns the score of the given [param peer_id].
func get_score(peer_id: int) -> Vector3i:
var entry : ScorePanelEntry = get_entry(peer_id)
return entry._score if entry else Vector3i.ZERO
## This method sets the score of the given [param peer_id].
func set_score(peer_id:int, score:Vector3i) -> bool:
var entry : ScorePanelEntry = get_entry(peer_id)
if entry:
entry._score = score
return true
return false
## This method adds to the score of the given [param peer_id].
func add_score(peer_id:int, score:Vector3i) -> bool:
var entry : ScorePanelEntry = get_entry(peer_id)
if entry:
entry._score += score
return true
return false
## This method resets the scores of all [Entry] nodes.
func reset_scores() -> void:
for panel : ScorePanel in panels.get_children():
for entry in panel:
entry._score = Vector3.ZERO
## This method returns the number of [ScorePanel] children.
func size() -> int:
return panels.get_child_count()

View file

@ -1,8 +1,16 @@
[gd_scene load_steps=2 format=3 uid="uid://b8bosdd0o1lu7"]
[gd_scene load_steps=5 format=3 uid="uid://b8bosdd0o1lu7"]
[ext_resource type="Script" path="res://interfaces/scoreboard/scoreboard.gd" id="1_k2wav"]
[ext_resource type="Theme" uid="uid://bec7g0fax3c8o" path="res://interfaces/global_theme.tres" id="1_p81gx"]
[ext_resource type="PackedScene" uid="uid://p1q2lu7mtte1" path="res://interfaces/scoreboard/score_panel.tscn" id="2_oa7t6"]
[node name="Scoreboard" type="Control"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_jx1ww"]
properties/0/path = NodePath(".:columns")
properties/0/spawn = true
properties/0/replication_mode = 2
[node name="Scoreboard" type="Control" node_paths=PackedStringArray("panels")]
visible = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@ -10,9 +18,12 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme = ExtResource("1_p81gx")
script = ExtResource("1_k2wav")
_SCORE_PANEL = ExtResource("2_oa7t6")
panels = NodePath("MarginContainer/VBoxContainer/ScorePanels")
[node name="Panel" type="Panel" parent="."]
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@ -20,45 +31,51 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_constants/margin_left = 12
theme_override_constants/margin_top = 12
theme_override_constants/margin_right = 12
theme_override_constants/margin_bottom = 12
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
mouse_filter = 2
[node name="Header" type="Panel" parent="MarginContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 48)
layout_mode = 2
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -76.5
offset_top = -19.5
offset_right = 76.5
offset_bottom = 19.5
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_constants/margin_left = 64
theme_override_constants/margin_top = 64
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
layout_mode = 2
mouse_filter = 2
[node name="Label" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
theme_type_variation = &"HeaderLarge"
text = "Scoreboard"
horizontal_alignment = 1
vertical_alignment = 1
uppercase = true
[node name="Scores" type="GridContainer" parent="Panel/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
[node name="ScorePanels" type="GridContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 3
mouse_filter = 2
theme_override_constants/h_separation = 32
theme_override_constants/v_separation = 16
columns = 3
[node name="PlayerLabel" type="Label" parent="Panel/MarginContainer/VBoxContainer/Scores"]
layout_mode = 2
text = "Player"
[node name="PanelSpawner" type="MultiplayerSpawner" parent="MarginContainer/VBoxContainer"]
_spawnable_scenes = PackedStringArray("res://interfaces/scoreboard/score_panel.tscn")
spawn_path = NodePath("../ScorePanels")
spawn_limit = 4
[node name="KillsLabel" type="Label" parent="Panel/MarginContainer/VBoxContainer/Scores"]
layout_mode = 2
text = "Kills"
[node name="ScoreLabel" type="Label" parent="Panel/MarginContainer/VBoxContainer/Scores"]
layout_mode = 2
text = "Score"
[node name="ScoreboardSync" type="MultiplayerSynchronizer" parent="MarginContainer/VBoxContainer"]
root_path = NodePath("../ScorePanels")
replication_interval = 1.0
delta_interval = 1.0
replication_config = SubResource("SceneReplicationConfig_jx1ww")

View file

@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://cpb6vpa0c74rl"
path.s3tc="res://.godot/imported/waypoint.svg-e7e029f470e2f863636e9426f3893ced.s3tc.ctex"
path.etc2="res://.godot/imported/waypoint.svg-e7e029f470e2f863636e9426f3893ced.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://interfaces/waypoint/assets/waypoint.svg"
dest_files=["res://.godot/imported/waypoint.svg-e7e029f470e2f863636e9426f3893ced.s3tc.ctex"]
dest_files=["res://.godot/imported/waypoint.svg-e7e029f470e2f863636e9426f3893ced.s3tc.ctex", "res://.godot/imported/waypoint.svg-e7e029f470e2f863636e9426f3893ced.etc2.ctex"]
[params]

View file

@ -17,7 +17,7 @@ line_spacing = 32.025
[node name="Sprite3D" type="Sprite3D" parent="."]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 0, 0, 0)
offset = Vector2(0, 64)
billboard = 2
billboard = 1
no_depth_test = true
fixed_size = true
texture = ExtResource("1_502g6")