diff options
author | metamuffin <metamuffin@disroot.org> | 2025-09-04 23:47:24 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-09-05 23:07:07 +0200 |
commit | 81deaf81c800900e30046cb927be1c9d91ae61b8 (patch) | |
tree | 20ce9898465e8d4c49eeff12a9ea55572517ea7b /client/gui | |
parent | fd80142282fcef628466a18e3ea62f0d1372d807 (diff) | |
download | hurrycurry-81deaf81c800900e30046cb927be1c9d91ae61b8.tar hurrycurry-81deaf81c800900e30046cb927be1c9d91ae61b8.tar.bz2 hurrycurry-81deaf81c800900e30046cb927be1c9d91ae61b8.tar.zst |
reorganize client gui files
Diffstat (limited to 'client/gui')
212 files changed, 7813 insertions, 0 deletions
diff --git a/client/gui/components/blur_setup.gd b/client/gui/components/blur_setup.gd new file mode 100644 index 00000000..567ac891 --- /dev/null +++ b/client/gui/components/blur_setup.gd @@ -0,0 +1,24 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name BlurSetup + +func _ready(): + update(Global.get_setting("graphics.ui_blur")) + Settings.hook_changed("graphics.ui_blur", false, update) + +func update(state): + material.set_shader_parameter("enable_blur", state) diff --git a/client/gui/components/blur_setup.gd.uid b/client/gui/components/blur_setup.gd.uid new file mode 100644 index 00000000..68ba7335 --- /dev/null +++ b/client/gui/components/blur_setup.gd.uid @@ -0,0 +1 @@ +uid://cmncjc06kadpe diff --git a/client/gui/components/controller_button.gd b/client/gui/components/controller_button.gd new file mode 100644 index 00000000..71f1332f --- /dev/null +++ b/client/gui/components/controller_button.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# + +extends Button +class_name ControllerButton + +@export var controller_texture: Texture2D +@export var press_action: String + +func _ready(): + set_texture_enabled(Global.using_joypad) + Global.using_joypad_change.connect(set_texture_enabled) + +func _input(_event): + if press_action == null: + return + if not is_visible_in_tree(): + return + if disabled: + return + if Input.is_action_just_pressed(press_action): + pressed.emit() + +func set_texture_enabled(b: bool): + if b: + icon = controller_texture + else: + icon = null diff --git a/client/gui/components/controller_button.gd.uid b/client/gui/components/controller_button.gd.uid new file mode 100644 index 00000000..c8f5a86c --- /dev/null +++ b/client/gui/components/controller_button.gd.uid @@ -0,0 +1 @@ +uid://b1eomxildrq30 diff --git a/client/gui/components/message/chat_message.gd b/client/gui/components/message/chat_message.gd new file mode 100644 index 00000000..ce3dd0ca --- /dev/null +++ b/client/gui/components/message/chat_message.gd @@ -0,0 +1,32 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends VBoxContainer +class_name ChatMessage + +@onready var fade_away_timer: Timer = $FadeAway +@onready var sender_label: Label = $Sender +@onready var message_label: Label = $MarginContainer/Message + +func set_message(username: String, message: String, username_color: Color, fade_away: bool = false, fade_time: float = 5.): + sender_label.text = "<%s>" % username + message_label.text = message + sender_label.add_theme_color_override("font_color", username_color.lightened(.5)) + + if fade_away: + fade_away_timer.start(fade_time) + +func _on_fade_away_timeout() -> void: + queue_free() diff --git a/client/gui/components/message/chat_message.gd.uid b/client/gui/components/message/chat_message.gd.uid new file mode 100644 index 00000000..f1c4ff05 --- /dev/null +++ b/client/gui/components/message/chat_message.gd.uid @@ -0,0 +1 @@ +uid://6rprqelfdp3 diff --git a/client/gui/components/message/chat_message.tscn b/client/gui/components/message/chat_message.tscn new file mode 100644 index 00000000..1478c738 --- /dev/null +++ b/client/gui/components/message/chat_message.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=4 format=3 uid="uid://bpc2qgsvcafhe"] + +[ext_resource type="Script" uid="uid://6rprqelfdp3" path="res://gui/components/message/chat_message.gd" id="1_ey0qp"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_rx6vg"] + +[sub_resource type="FontVariation" id="FontVariation_jfhbh"] +variation_embolden = 1.3 + +[node name="ChatMessage" type="VBoxContainer"] +offset_right = 72.0 +offset_bottom = 192.0 +theme = ExtResource("1_rx6vg") +script = ExtResource("1_ey0qp") + +[node name="Sender" type="Label" parent="."] +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_jfhbh") +text = "<Name>" + +[node name="FadeAway" type="Timer" parent="."] +one_shot = true + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 0 +theme_override_constants/margin_right = 0 +theme_override_constants/margin_bottom = 5 + +[node name="Message" type="Label" parent="MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Message" +vertical_alignment = 1 +autowrap_mode = 3 + +[connection signal="timeout" from="FadeAway" to="." method="_on_fade_away_timeout"] diff --git a/client/gui/components/message/item/item_message.gd b/client/gui/components/message/item/item_message.gd new file mode 100644 index 00000000..e643c291 --- /dev/null +++ b/client/gui/components/message/item/item_message.gd @@ -0,0 +1,71 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name ItemMessage +extends Control + +const PRINTED_MAT := preload("res://gui/resources/materials/printed_material.tres") + +@export var enable_rotation := true +@export var enable_grayscale := false + +var timeout_remaining := 0. +var timeout_initial := 0. + +@onready var item_render: ItemRender = $VBoxContainer/SubViewportContainer/SubViewport/ItemRender +@onready var progress: ProgressBar = $VBoxContainer/ProgressBar +@onready var sub_viewport: SubViewport = $VBoxContainer/SubViewportContainer/SubViewport +@onready var sub_viewport_container: SubViewportContainer = $VBoxContainer/SubViewportContainer +@onready var v_box_container: VBoxContainer = $VBoxContainer + +func _ready() -> void: + Global.configure_viewport_aa(sub_viewport, Global.get_setting("graphics.aa")) + + if enable_grayscale: + sub_viewport_container.material = PRINTED_MAT + +func set_subviewport_size(sub_viewport_size: Vector2): + sub_viewport.size = sub_viewport_size + progress.custom_minimum_size.y = sub_viewport_size.x - sub_viewport_size.y + v_box_container.size.y = 0 + +func set_round_corner_radius_progress(radius: int): + var style_bg: StyleBoxFlat = progress.get_theme_stylebox("background") + var style_fill: StyleBoxFlat = progress.get_theme_stylebox("fill") + + style_bg.corner_radius_bottom_left = radius + style_bg.corner_radius_bottom_right = radius + style_fill.corner_radius_bottom_left = radius + style_fill.corner_radius_bottom_right = radius + +func set_item(item_name: String, timeout_initial_: float, timeout_remaining_: float): + item_render.set_item(item_name, enable_rotation) + + timeout_remaining = timeout_remaining_ + timeout_initial = timeout_initial_ + progress.max_value = timeout_initial + progress.value = timeout_remaining + +func remove_item(): + item_render.remove_item() + +func _process(delta): + if item_render.item != null and !Global.game_paused: + timeout_remaining -= delta + progress.value = timeout_remaining + var x: float = timeout_remaining / timeout_initial + var progress_style: StyleBoxFlat = progress.get_theme_stylebox("fill") + progress_style.bg_color = Color(min((1-x) * 2, 1), min(x * 2, 1), 0.) + progress.add_theme_stylebox_override("fill", progress_style) diff --git a/client/gui/components/message/item/item_message.gd.uid b/client/gui/components/message/item/item_message.gd.uid new file mode 100644 index 00000000..d2600c43 --- /dev/null +++ b/client/gui/components/message/item/item_message.gd.uid @@ -0,0 +1 @@ +uid://boheclidwdafn diff --git a/client/gui/components/message/item/item_message.tscn b/client/gui/components/message/item/item_message.tscn new file mode 100644 index 00000000..59e0ebf9 --- /dev/null +++ b/client/gui/components/message/item/item_message.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=6 format=3 uid="uid://fkqh36s4vl3p"] + +[ext_resource type="Script" uid="uid://boheclidwdafn" path="res://gui/components/message/item/item_message.gd" id="1_76lg0"] +[ext_resource type="PackedScene" uid="uid://cem5xcld6vn51" path="res://gui/components/message/item/item_render.tscn" id="1_sju7l"] +[ext_resource type="StyleBox" uid="uid://brw8uogdgx2gf" path="res://gui/resources/style/item_bubble_progress_style.tres" id="3_ipe76"] +[ext_resource type="StyleBox" uid="uid://cu0his4018e7h" path="res://gui/resources/style/item_bubble_progress_style_background.tres" id="3_t61n3"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dpele"] +bg_color = Color(1, 1, 1, 1) +corner_radius_top_left = 30 +corner_radius_top_right = 30 +corner_radius_bottom_right = 30 +corner_radius_bottom_left = 30 + +[node name="ItemMessage" type="PanelContainer"] +auto_translate_mode = 2 +clip_children = 2 +offset_right = 256.0 +offset_bottom = 256.0 +size_flags_vertical = 0 +theme_override_styles/panel = SubResource("StyleBoxFlat_dpele") +script = ExtResource("1_76lg0") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +size_flags_vertical = 0 +theme_override_constants/separation = 0 + +[node name="SubViewportContainer" type="SubViewportContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="SubViewport" type="SubViewport" parent="VBoxContainer/SubViewportContainer"] +own_world_3d = true +transparent_bg = true +handle_input_locally = false +size = Vector2i(256, 224) +render_target_update_mode = 4 + +[node name="ItemRender" parent="VBoxContainer/SubViewportContainer/SubViewport" instance=ExtResource("1_sju7l")] + +[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 32) +layout_mode = 2 +theme_override_styles/background = ExtResource("3_t61n3") +theme_override_styles/fill = ExtResource("3_ipe76") +step = 0.0 +value = 100.0 +show_percentage = false diff --git a/client/gui/components/message/item/item_render.gd b/client/gui/components/message/item/item_render.gd new file mode 100644 index 00000000..71a5eb7c --- /dev/null +++ b/client/gui/components/message/item/item_render.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Node3D +class_name ItemRender + +var item: Item +var do_rotate: bool + +var base := Node3D.new() + +func _ready() -> void: + add_child(base) + +func set_item(item_name: String, enable_rotation := true): + if item != null: + remove_item() + + item = ItemFactory.produce(item_name, base) + do_rotate = enable_rotation + base.add_child(item) + +func remove_item(): + if item != null: + item.queue_free() + +func _process(delta: float): + if do_rotate: + base.rotation.y += delta * TAU * .025 diff --git a/client/gui/components/message/item/item_render.gd.uid b/client/gui/components/message/item/item_render.gd.uid new file mode 100644 index 00000000..745b21ce --- /dev/null +++ b/client/gui/components/message/item/item_render.gd.uid @@ -0,0 +1 @@ +uid://bt7773og3p557 diff --git a/client/gui/components/message/item/item_render.tscn b/client/gui/components/message/item/item_render.tscn new file mode 100644 index 00000000..3d993b7a --- /dev/null +++ b/client/gui/components/message/item/item_render.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=3 format=3 uid="uid://cem5xcld6vn51"] + +[ext_resource type="Script" uid="uid://bt7773og3p557" path="res://gui/components/message/item/item_render.gd" id="1_jfi7o"] + +[sub_resource type="Environment" id="Environment_iyxrx"] +ambient_light_source = 2 +ambient_light_color = Color(1, 1, 1, 1) +ambient_light_energy = 0.5 + +[node name="ItemRender" type="Node3D"] +script = ExtResource("1_jfi7o") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0.5, 1) +projection = 1 +size = 0.6 + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.173648, 0.984808, 0, -0.984808, 0.173648, 0, 0, 0) +light_energy = 0.5 + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_iyxrx") diff --git a/client/gui/components/message/popup_message/pinned_item_messages.gd b/client/gui/components/message/popup_message/pinned_item_messages.gd new file mode 100644 index 00000000..fe82f904 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.gd @@ -0,0 +1,55 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name PinnedItemMessages + +const ITEM_MESSAGE_SCENE := preload("res://gui/components/message/item/item_message.tscn") +const PAPER_PANEL_STYLE := preload("res://gui/resources/style/paper_panel_style.tres") + +var pinned_items := {} + +@onready var pinned_items_container: HBoxContainer = $HBoxContainer + +func pin_item(item_name: String, timeout_initial_: float, timeout_remaining_: float, player_id: float): + var item_message: ItemMessage = ITEM_MESSAGE_SCENE.instantiate() + item_message.remove_theme_stylebox_override("panel") + item_message.enable_rotation = false + item_message.enable_grayscale = true + item_message.add_theme_stylebox_override("panel", PAPER_PANEL_STYLE) + pinned_items_container.add_child(item_message) + item_message.set_subviewport_size(Vector2(96, 84)) + item_message.set_round_corner_radius_progress(0) + item_message.set_item(item_name, timeout_initial_, timeout_remaining_) + pinned_items[player_id] = item_message + sort_pins() + +func clear_item(player_id: float): + if player_id in pinned_items: + if is_instance_valid(pinned_items[player_id]): + pinned_items[player_id].queue_free() + +func sort_pins(): + var sorted_nodes := pinned_items_container.get_children() + + sorted_nodes.sort_custom( + func(a: Node, b: Node): return a.timeout_remaining < b.timeout_remaining + ) + + for node in pinned_items_container.get_children(): + pinned_items_container.remove_child(node) + + for node in sorted_nodes: + pinned_items_container.add_child(node) diff --git a/client/gui/components/message/popup_message/pinned_item_messages.gd.uid b/client/gui/components/message/popup_message/pinned_item_messages.gd.uid new file mode 100644 index 00000000..2325c656 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.gd.uid @@ -0,0 +1 @@ +uid://c0k6f1wkynbkd diff --git a/client/gui/components/message/popup_message/pinned_item_messages.tscn b/client/gui/components/message/popup_message/pinned_item_messages.tscn new file mode 100644 index 00000000..30f27809 --- /dev/null +++ b/client/gui/components/message/popup_message/pinned_item_messages.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=2 format=3 uid="uid://dcrr1rwdwbkq8"] + +[ext_resource type="Script" uid="uid://c0k6f1wkynbkd" path="res://gui/components/message/popup_message/pinned_item_messages.gd" id="1_q0jkk"] + +[node name="PinnedItemMessages" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_q0jkk") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_direction = 2 +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 256.0 +grow_horizontal = 2 +mouse_filter = 2 diff --git a/client/gui/components/message/popup_message/popup_message.gd b/client/gui/components/message/popup_message/popup_message.gd new file mode 100644 index 00000000..ae474914 --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.gd @@ -0,0 +1,230 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name PopupMessage + +const SERVER_MESSAGE_SCENE = preload("res://gui/components/message/popup_message/server_message.tscn") + +var is_ingame := false +var is_joined := false + +var positional_messages = {} + +@onready var positional_messages_node: Control = $Positional +@onready var server_msg = $Static/VBox/ServerMessage +@onready var hint_msg = $Static/VBox/HintMessage + +@onready var server_msg_label: Label = $Static/VBox/ServerMessage/CenterContainer/Label +@onready var hint_msg_label: Label = $Static/VBox/HintMessage/CenterContainer/Label + +@onready var auto_hint_timers: Node = $Timers/AutoHints +@onready var server_msg_timer: Timer = $Timers/Server +@onready var hint_msg_timer: Timer = $Timers/Hint +@onready var reset_timer = $Timers/Reset +@onready var join_while_running_timer = $Timers/JoinWhileRunning + +@onready var game: Game = $"../Game" + +func _ready(): + game.join_state_updated.connect(func(state: Game.JoinState): + is_joined = state == Game.JoinState.JOINED + ) + game.update_tutorial_running.connect( + func a(running: bool): + if running: + stop_game_hints() + else: + update_state() + ) + game.in_lobby_updated.connect( + func a(in_lobby): + is_ingame = not in_lobby + update_state() + ) + +func _process(_delta: float): + for pos: Vector2 in positional_messages.keys(): + var msg: PositionalMessage = positional_messages[pos] + var pos_3d = Vector3(pos.x + 0.5, 1.5, pos.y + 0.5) + var pos_2d = get_viewport().get_camera_3d().unproject_position(pos_3d) + + msg.node_2d.position = pos_2d.clamp( + Vector2.ZERO + 0.5 * msg.node.size, + Vector2(get_viewport_rect().size) - 0.5 * msg.node.size + ) + + if msg.node.size != msg.last_size: + msg.last_size = msg.node.size + msg.node.position = -0.5 * msg.last_size + +func update_state(): + if is_ingame and is_joined: + start_game_hints() + elif is_ingame: + stop_game_hints() + join_while_running_timer.start() + else: + stop_game_hints() + +func display_server_msg(msg: String, auto_remove := true): + server_msg.show() + server_msg_label.text = msg + + if auto_remove: + server_msg_timer.start() + +func _on_server_timeout() -> void: + clear_server_msg() + +func display_server_msg_positional(text: String, pos: Vector2, use_monospace: bool): + var msg := PositionalMessage.new() + msg.node = SERVER_MESSAGE_SCENE.instantiate() + msg.node_2d = Node2D.new() + positional_messages_node.add_child(msg.node_2d) + msg.node_2d.add_child(msg.node) + msg.node.set_text(text, use_monospace) + msg.node.size = Vector2.ZERO + msg.position = pos + positional_messages[pos] = msg + +func clear_server_msg(position_ = null): + if position_ == null: + server_msg_timer.stop() + server_msg.hide() + else: + if position_ in positional_messages: + var msg: PositionalMessage = positional_messages[position_] + msg.node_2d.queue_free() + positional_messages.erase(position_) + +func display_hint_msg(msg: String): + hint_msg.show() + hint_msg_label.text = msg + hint_msg_timer.start() + +func _on_hint_timer_timeout(): + hint_msg.hide() + +func start_game_hints(): + for c: Timer in auto_hint_timers.get_children(): + c.start() + +func stop_game_hints(): + _on_hint_timer_timeout() + for c: Timer in auto_hint_timers.get_children(): + c.stop() + reset_timer.stop() + join_while_running_timer.stop() + +func _input(_event): + if Input.is_action_just_pressed("boost"): + Global.set_hint("has_boosted", true) + if any_action_just_pressed(["forwards", "backwards", "left", "right"]): + Global.set_hint("has_moved", true) + if any_action_just_pressed(["rotate_left", "rotate_right", "rotate_up", "rotate_down"]): + if not Global.get_hint("has_reset"): + reset_timer.start() + Global.set_hint("has_rotated", true) + if any_action_just_pressed(["zoom_in", "zoom_out"]): + Global.set_hint("has_zoomed", true) + if Input.is_action_just_pressed("interact_left") or Input.is_action_just_pressed("interact_right"): + Global.set_hint("has_interacted", true) + if Input.is_action_just_pressed("reset"): + Global.set_hint("has_reset", true) + +func _on_boost_timeout(): + if not Global.get_hint("has_boosted") and not Global.using_touch: + display_hint_msg(tr("c.hint.boost").format([display_keybind("boost")])) + +func _on_move_timeout(): + if not Global.get_hint("has_moved") and not Global.using_touch: + display_hint_msg(tr("c.hint.movement").format([", ".join( + [ + display_keybind("forwards"), + display_keybind("left"), + display_keybind("backwards"), + display_keybind("right") + ] + )])) + +func _on_interact_timeout(): + if not Global.get_hint("has_interacted") and not Global.using_touch: + display_hint_msg(tr("c.hint.interact").format([display_keybind("interact")])) + +func _on_reset_timeout(): + if not Global.get_hint("has_reset") and not Global.using_touch: + display_hint_msg(tr("c.hint.reset_camera").format([display_keybind("reset")])) + +func _on_zoom_timeout(): + if not Global.get_hint("has_zoomed") and not Global.using_touch: + display_hint_msg(tr("c.hint.zoom_camera").format([", ".join( + [ + display_keybind("zoom_in"), + display_keybind("zoom_out") + ] + )])) + +func display_keybind(action_name: String) -> String: + var events := InputManager.get_events(action_name) + + if events.size() == 0: + # There are no events which match the action + return tr("c.settings.input.unknown_event") + + for event: InputEvent in events: + # Try to find event which matches input method + var type := InputManager.get_event_type(event) + if Global.using_joypad and type != InputManager.EventType.JOYPAD: + continue + if Global.using_touch and type != InputManager.EventType.TOUCH: + continue + return InputManager.display_input_event(event) + + # No matching event found. Just show any event. + return InputManager.display_input_event(events[0]) + +func any_action_just_pressed(actions: Array) -> bool: + for a: String in actions: + if Input.is_action_just_pressed(a): + return true + return false + +func _on_rotate_camera_timeout(): + if not Global.get_hint("has_rotated") and not Global.using_touch: + display_hint_msg(tr("c.hint.rotate").format([", ".join( + [ + display_keybind("rotate_up"), + display_keybind("rotate_left"), + display_keybind("rotate_down"), + display_keybind("rotate_right") + ] + )])) + +func _on_join_while_running_timeout(): + if not game.join_state == Game.JoinState.JOINED and not Global.get_hint("has_seen_join_while_running"): + Global.set_hint("has_seen_join_while_running", true) + display_hint_msg(tr("c.hint.join_while_running").format([display_keybind("menu")])) + +func _on_performance_timeout() -> void: + if not Global.get_hint("has_seen_performance") and Engine.get_frames_per_second() < DisplayServer.screen_get_refresh_rate() * 0.75: + Global.set_hint("has_seen_performance", true) + display_hint_msg(tr("c.hint.framerate_low")) + +class PositionalMessage: + var node: ServerMessage + var node_2d: Node2D + var position: Vector2 + var last_size: Vector2 diff --git a/client/gui/components/message/popup_message/popup_message.gd.uid b/client/gui/components/message/popup_message/popup_message.gd.uid new file mode 100644 index 00000000..d9aa95c5 --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.gd.uid @@ -0,0 +1 @@ +uid://c2cx41lrgf5b0 diff --git a/client/gui/components/message/popup_message/popup_message.tscn b/client/gui/components/message/popup_message/popup_message.tscn new file mode 100644 index 00000000..0f1bfcec --- /dev/null +++ b/client/gui/components/message/popup_message/popup_message.tscn @@ -0,0 +1,164 @@ +[gd_scene load_steps=12 format=3 uid="uid://b21nrnkygiyjt"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_a1566"] +[ext_resource type="Script" uid="uid://c2cx41lrgf5b0" path="res://gui/components/message/popup_message/popup_message.gd" id="2_sbew6"] +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="3_2vnom"] +[ext_resource type="PackedScene" uid="uid://dq61p3a8og2b6" path="res://gui/components/message/popup_message/server_message.tscn" id="3_m3rok"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_pvwmw"] +[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="4_wsrnf"] +[ext_resource type="Texture2D" uid="uid://b2uv5rf0enikf" path="res://gui/resources/icons/hint.svg" id="5_2dxsd"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_k0m35"] +shader = ExtResource("3_2vnom") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.85 +shader_parameter/mix_amount_no_blur = 1.0 +shader_parameter/color_over = Color(0, 0, 0, 1) +shader_parameter/enable_blur = false + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vq4dg"] +bg_color = Color(1, 1, 1, 0.878431) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="FontVariation" id="FontVariation_qfltj"] +base_font = ExtResource("4_wsrnf") +variation_embolden = 0.75 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3rgop"] +content_margin_left = 32.0 +content_margin_top = 8.0 +content_margin_right = 32.0 +content_margin_bottom = 8.0 + +[node name="PopupMessage" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("2_sbew6") + +[node name="Static" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_a1566") + +[node name="VBox" type="VBoxContainer" parent="Static"] +layout_mode = 2 +mouse_filter = 2 + +[node name="ServerMessage" parent="Static/VBox" instance=ExtResource("3_m3rok")] +visible = false +layout_mode = 2 + +[node name="HintMessage" type="PanelContainer" parent="Static/VBox"] +visible = false +material = SubResource("ShaderMaterial_k0m35") +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_vq4dg") +script = ExtResource("4_pvwmw") + +[node name="CenterContainer" type="HBoxContainer" parent="Static/VBox/HintMessage"] +layout_mode = 2 +mouse_filter = 2 +alignment = 1 + +[node name="MarginContainer" type="MarginContainer" parent="Static/VBox/HintMessage/CenterContainer"] +layout_mode = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="TextureRect" type="TextureRect" parent="Static/VBox/HintMessage/CenterContainer/MarginContainer"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +mouse_filter = 2 +texture = ExtResource("5_2dxsd") +expand_mode = 1 +stretch_mode = 4 + +[node name="Label" type="Label" parent="Static/VBox/HintMessage/CenterContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_fonts/font = SubResource("FontVariation_qfltj") +theme_override_styles/normal = SubResource("StyleBoxEmpty_3rgop") +text = "A hint is worth more than a thousand manuals" +autowrap_mode = 3 + +[node name="Positional" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="Timers" type="Node" parent="."] + +[node name="Server" type="Timer" parent="Timers"] +wait_time = 5.0 +one_shot = true + +[node name="Hint" type="Timer" parent="Timers"] +wait_time = 10.0 +one_shot = true + +[node name="AutoHints" type="Node" parent="Timers"] + +[node name="Move" type="Timer" parent="Timers/AutoHints"] +wait_time = 2.0 +one_shot = true + +[node name="Performance" type="Timer" parent="Timers/AutoHints"] +wait_time = 20.0 +one_shot = true + +[node name="Boost" type="Timer" parent="Timers/AutoHints"] +wait_time = 90.0 +one_shot = true + +[node name="Interact" type="Timer" parent="Timers/AutoHints"] +wait_time = 15.0 +one_shot = true + +[node name="RotateCamera" type="Timer" parent="Timers/AutoHints"] +wait_time = 120.0 +one_shot = true + +[node name="Zoom" type="Timer" parent="Timers/AutoHints"] +wait_time = 135.0 +one_shot = true + +[node name="Reset" type="Timer" parent="Timers"] +wait_time = 10.0 +one_shot = true + +[node name="JoinWhileRunning" type="Timer" parent="Timers"] +wait_time = 5.0 +one_shot = true + +[connection signal="timeout" from="Timers/Server" to="." method="_on_server_timeout"] +[connection signal="timeout" from="Timers/Hint" to="Static" method="_on_hint_timer_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Move" to="Static" method="_on_move_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Performance" to="Static" method="_on_performance_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Boost" to="Static" method="_on_boost_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Interact" to="Static" method="_on_interact_timeout"] +[connection signal="timeout" from="Timers/AutoHints/RotateCamera" to="Static" method="_on_rotate_camera_timeout"] +[connection signal="timeout" from="Timers/AutoHints/Zoom" to="Static" method="_on_zoom_timeout"] +[connection signal="timeout" from="Timers/Reset" to="Static" method="_on_reset_timeout"] +[connection signal="timeout" from="Timers/JoinWhileRunning" to="Static" method="_on_join_while_running_timeout"] diff --git a/client/gui/components/message/popup_message/server_message.gd b/client/gui/components/message/popup_message/server_message.gd new file mode 100644 index 00000000..a0688dc5 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.gd @@ -0,0 +1,13 @@ +extends BlurSetup +class_name ServerMessage + +const DEFAULT_FONT = preload("res://gui/resources/fonts/font-josefin-sans.woff2") +const MONOSPACE_FONT = preload("res://gui/resources/fonts/font-azaret-mono.woff2") + +@onready var label: Label = $CenterContainer/Label + +func set_text(text: String, use_monospace := true): + label.text = text + var font: FontVariation = label.get_theme_font("font") + font.base_font = MONOSPACE_FONT if use_monospace else DEFAULT_FONT + label.add_theme_font_size_override("font_size", 16 if use_monospace else 20) diff --git a/client/gui/components/message/popup_message/server_message.gd.uid b/client/gui/components/message/popup_message/server_message.gd.uid new file mode 100644 index 00000000..775979e0 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.gd.uid @@ -0,0 +1 @@ +uid://dfgwh7x7sqc21 diff --git a/client/gui/components/message/popup_message/server_message.tscn b/client/gui/components/message/popup_message/server_message.tscn new file mode 100644 index 00000000..fd128666 --- /dev/null +++ b/client/gui/components/message/popup_message/server_message.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=8 format=3 uid="uid://dq61p3a8og2b6"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_qv8ew"] +[ext_resource type="Script" uid="uid://dfgwh7x7sqc21" path="res://gui/components/message/popup_message/server_message.gd" id="2_csqo8"] +[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="3_dw20j"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_q3bbd"] +shader = ExtResource("1_qv8ew") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.85 +shader_parameter/mix_amount_no_blur = 0.85 +shader_parameter/color_over = Color(1, 1, 1, 1) +shader_parameter/enable_blur = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_vq4dg"] +bg_color = Color(1, 1, 1, 0.878431) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="FontVariation" id="FontVariation_qfltj"] +resource_local_to_scene = true +base_font = ExtResource("3_dw20j") +variation_embolden = 0.75 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3rgop"] +content_margin_left = 32.0 +content_margin_top = 8.0 +content_margin_right = 32.0 +content_margin_bottom = 8.0 + +[node name="ServerMessage" type="PanelContainer"] +material = SubResource("ShaderMaterial_q3bbd") +size_flags_horizontal = 4 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_vq4dg") +script = ExtResource("2_csqo8") + +[node name="CenterContainer" type="CenterContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 + +[node name="Label" type="Label" parent="CenterContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = SubResource("FontVariation_qfltj") +theme_override_font_sizes/font_size = 16 +theme_override_styles/normal = SubResource("StyleBoxEmpty_3rgop") +text = "Server message" diff --git a/client/gui/components/smart_margin_container.gd b/client/gui/components/smart_margin_container.gd new file mode 100644 index 00000000..046dc6f3 --- /dev/null +++ b/client/gui/components/smart_margin_container.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends MarginContainer +class_name SmartMarginContainer +# A smart margin container which automatically adjusts the margin such that it doesn't cover notch on phones + +func _ready() -> void: + var os := OS.get_name() + if os == "iOS" or os == "Android": + update_margins() + +func update_margins() -> void: + var screen_safe_rect := Rect2(DisplayServer.get_display_safe_area()) + var viewport_transform := get_viewport().get_final_transform() + var viewport_safe_rect := screen_safe_rect * viewport_transform.affine_inverse() + var viewport_full_rect := get_viewport().get_visible_rect() + var left := viewport_safe_rect.position.x - viewport_full_rect.position.x + var top := viewport_safe_rect.position.y - viewport_full_rect.position.y + var right := viewport_full_rect.end.x - viewport_safe_rect.end.x + var bottom := viewport_full_rect.end.y - viewport_safe_rect.end.y + # print("OLD: ", get_theme_constant("margin_left")) + begin_bulk_theme_override() + add_theme_constant_override('margin_left', roundi(left) + get_theme_constant("margin_left")) + add_theme_constant_override('margin_top', roundi(top) + get_theme_constant("margin_top")) + add_theme_constant_override('margin_right', roundi(right) + get_theme_constant("margin_right")) + add_theme_constant_override('margin_bottom', roundi(bottom) + get_theme_constant("margin_bottom")) + end_bulk_theme_override() + # print("NEW: ", get_theme_constant("margin_left")) diff --git a/client/gui/components/smart_margin_container.gd.uid b/client/gui/components/smart_margin_container.gd.uid new file mode 100644 index 00000000..c5246aed --- /dev/null +++ b/client/gui/components/smart_margin_container.gd.uid @@ -0,0 +1 @@ +uid://byshs20og68tn diff --git a/client/gui/components/touch_scroll_container.gd b/client/gui/components/touch_scroll_container.gd new file mode 100644 index 00000000..41aa34c0 --- /dev/null +++ b/client/gui/components/touch_scroll_container.gd @@ -0,0 +1,45 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends ScrollContainer +class_name ScrollContainerCustom + +# Adds support for scrolling with joypad and touch + +const SCROLL_SPEED := 1000. +var velocity := 0. + +@export var auto_scroll_to_bottom := false + +func _init(): + follow_focus = true + +func _ready(): + if auto_scroll_to_bottom: + call_deferred("scroll_to_bottom") + +func scroll_to_bottom(): + set_deferred("scroll_vertical", get_v_scroll_bar().max_value) + +func _process(delta): + velocity = G.interpolate(velocity, 0., delta * 5.) + velocity = 0. if abs(velocity) < .001 else velocity + if Input.get_axis("scroll_up", "scroll_down") != 0.: + velocity = Input.get_axis("scroll_up", "scroll_down") + set_deferred("scroll_vertical", scroll_vertical + velocity * delta * SCROLL_SPEED) + +func _input(event): + if event is InputEventScreenDrag: + velocity = -(scroll_vertical - (scroll_vertical - event.relative.y)) * .1 diff --git a/client/gui/components/touch_scroll_container.gd.uid b/client/gui/components/touch_scroll_container.gd.uid new file mode 100644 index 00000000..56b74a3d --- /dev/null +++ b/client/gui/components/touch_scroll_container.gd.uid @@ -0,0 +1 @@ +uid://bd7bylb2t2m0 diff --git a/client/gui/menus/character.gd b/client/gui/menus/character.gd new file mode 100644 index 00000000..3c1230ae --- /dev/null +++ b/client/gui/menus/character.gd @@ -0,0 +1,96 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +@onready var character: Character = $Node3D/Character +@onready var back_button := $VBoxContainer/bottom_panel/back +@onready var map: Map = $Node3D/Map +@onready var username_edit = $VBoxContainer/top_panel/a/username + +func _ready(): + super() + $VBoxContainer/top_panel/a/username.text = Global.get_profile("username") + character.set_style(Global.get_profile("character_style"), "chef") + init_map() + +func init_map(): + var map_tile = func (t): match t: + ".": return "floor" + "=": return "counter" + "s": return "stove" + "c": return "chair" + "t": return "table" + "o": return "oven" + "#": return "wall" + _: push_error("unknown tile: ", t) + var tiles = [ + "...............", + "###############", + "=oo==ss===.ctc#", + "..............#", + ".............=#", + ".............=#", + ".............=#" + ].map(func (l): return Array(l.split("")).map(map_tile)) + var gt = func (e): return null if e[1] >= tiles.size() else null if e[0] >= tiles[e[1]].size() else tiles[e[1]][e[0]] + var co = Vector2i(floor(tiles[0].size() / 2), floor(tiles.size() - 2)) + for y in tiles.size(): + for x in tiles[y].size(): + map.set_tile(Vector2i(x,y) - co, gt.call([x,y]), [[x,y-1],[x-1,y],[x,y+1],[x+1,y]].map(gt)) + map.flush() + +func exit(): + if username_edit.text == "": + var popup_data := MenuPopup.Data.new() + popup_data.text = tr("c.error.empty_username") + var accept_button := Button.new() + accept_button.text = tr("c.menu.accept") + popup_data.buttons = [accept_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + return + Global.set_profile("username", username_edit.text) + Global.save_profile() + super() + +func _on_character_back_pressed(): + modify_style(func m(current_style: Dictionary): + current_style.color = G.rem_euclid(current_style.color - 1, character.COLORS.size())) + +func _on_character_forward_pressed(): + modify_style(func m(current_style: Dictionary): + current_style.color = G.rem_euclid(current_style.color + 1, character.COLORS.size())) + +func _on_headwear_back_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.headwear = G.rem_euclid(current_style.headwear - 1, character.headwears.size())) + +func _on_headwear_forward_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.headwear = G.rem_euclid(current_style.headwear + 1, character.headwears.size())) + +func _on_hairstyle_back_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.hairstyle = G.rem_euclid(current_style.hairstyle - 1, character.hairstyles.size())) + +func _on_hairstyle_forward_pressed() -> void: + modify_style(func m(current_style: Dictionary): + current_style.hairstyle = G.rem_euclid(current_style.hairstyle + 1, character.hairstyles.size())) + +func modify_style(modifier: Callable): + var current_style: Dictionary = Global.get_profile("character_style") + modifier.call(current_style) + Global.set_profile("character_style", current_style) + character.set_style(Global.get_profile("character_style"), "chef") diff --git a/client/gui/menus/character.gd.uid b/client/gui/menus/character.gd.uid new file mode 100644 index 00000000..d0df5488 --- /dev/null +++ b/client/gui/menus/character.gd.uid @@ -0,0 +1 @@ +uid://bglusga8l5c27 diff --git a/client/gui/menus/character.tscn b/client/gui/menus/character.tscn new file mode 100644 index 00000000..7bdf03e6 --- /dev/null +++ b/client/gui/menus/character.tscn @@ -0,0 +1,230 @@ +[gd_scene load_steps=11 format=3 uid="uid://1f7xpirm5d28"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_ak2pw"] +[ext_resource type="Script" uid="uid://bglusga8l5c27" path="res://gui/menus/character.gd" id="1_brhd1"] +[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="3_6mc88"] +[ext_resource type="PackedScene" uid="uid://b3hhir2fvnunu" path="res://player/character/character.tscn" id="3_odq7n"] +[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://gui/menus/transition/scene_transition.tscn" id="4_c0ocf"] +[ext_resource type="Texture2D" uid="uid://35rd5gamtyqm" path="res://gui/resources/icons/arrow.svg" id="5_kvd7k"] +[ext_resource type="Texture2D" uid="uid://j75dbytlbju" path="res://gui/resources/icons/arrow_pressed.svg" id="5_xpff8"] +[ext_resource type="Texture2D" uid="uid://b33qmctbpf48g" path="res://gui/resources/icons/arrow_hover.svg" id="6_soj8g"] +[ext_resource type="Texture2D" uid="uid://by3qsrpxnfq4w" path="res://gui/resources/icons/arrow_focus.svg" id="6_u31hl"] + +[sub_resource type="Environment" id="Environment_ex25y"] +background_mode = 1 +background_color = Color(0.145548, 0.151043, 0.207031, 1) + +[node name="CharacterMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_ak2pw") +script = ExtResource("1_brhd1") + +[node name="Node3D" type="Node3D" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="Node3D"] +environment = SubResource("Environment_ex25y") + +[node name="Camera3D" type="Camera3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 0.977046, 0.21303, 0, -0.21303, 0.977046, 0, 1.137, 2.703) +current = true +fov = 41.8 + +[node name="Map" parent="Node3D" instance=ExtResource("3_6mc88")] +transform = Transform3D(0.866025, 0, 0.5, 0, 1, 0, -0.5, 0, 0.866025, 0, 0, 0) + +[node name="Character" parent="Node3D" instance=ExtResource("3_odq7n")] + +[node name="SpotLight3D" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.631535, -0.571246, 0.524254, 0.0428654, 0.700843, 0.712026, -0.774162, -0.427197, 0.467093, 1.79161, 3.07541, 1.58055) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="SpotLight3D2" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.32457, 0.109091, -0.93955, 0.0604837, 0.9889, 0.135716, 0.943926, -0.100877, 0.314369, -5.22608, 2.10824, 2.35824) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="SpotLight3D3" type="SpotLight3D" parent="Node3D"] +transform = Transform3D(0.114088, -0.0173997, 0.993318, 0.0610452, 0.99808, 0.0104718, -0.991594, 0.0594426, 0.114931, 8.10732, 0.437069, 2.35824) +light_energy = 2.689 +spot_range = 20.159 +spot_angle = 17.9256 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="top_panel" type="Panel" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 100) +layout_mode = 2 + +[node name="a" type="VBoxContainer" parent="VBoxContainer/top_panel"] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -213.0 +offset_top = 13.0 +offset_right = 216.0 +offset_bottom = 110.0 +grow_horizontal = 2 + +[node name="Label" type="Label" parent="VBoxContainer/top_panel/a"] +layout_mode = 2 +text = "c.settings.username" +horizontal_alignment = 1 + +[node name="username" type="LineEdit" parent="VBoxContainer/top_panel/a"] +layout_mode = 2 +max_length = 32 + +[node name="Spacer" type="MarginContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_constants/margin_left = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/Spacer"] +layout_mode = 2 +alignment = 1 + +[node name="Headware" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="Hairstyle" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="Character" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 1 + +[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_right = NodePath("../Forward") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 +flip_h = true + +[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_neighbor_left = NodePath("../Back") +texture_normal = ExtResource("5_kvd7k") +texture_pressed = ExtResource("5_xpff8") +texture_hover = ExtResource("6_soj8g") +texture_focused = ExtResource("6_u31hl") +ignore_texture_size = true +stretch_mode = 5 + +[node name="bottom_panel" type="Panel" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 75) +layout_mode = 2 + +[node name="back" type="Button" parent="VBoxContainer/bottom_panel"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -39.5 +offset_top = -22.0 +offset_right = 39.5 +offset_bottom = 22.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 8 +text = "c.menu.back" + +[node name="SceneTransition" parent="." instance=ExtResource("4_c0ocf")] +visible = false +layout_mode = 1 + +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Back" to="." method="_on_headwear_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Forward" to="." method="_on_headwear_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Back" to="." method="_on_hairstyle_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Forward" to="." method="_on_hairstyle_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Back" to="." method="_on_character_back_pressed"] +[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Forward" to="." method="_on_character_forward_pressed"] +[connection signal="pressed" from="VBoxContainer/bottom_panel/back" to="." method="exit"] diff --git a/client/gui/menus/chat.gd b/client/gui/menus/chat.gd new file mode 100644 index 00000000..150b0e7e --- /dev/null +++ b/client/gui/menus/chat.gd @@ -0,0 +1,48 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu +class_name ChatOpen + +const CHAT_MESSAGE_SCENE = preload("res://menu/communicate/chat/chat_message.tscn") + +@onready var messages_container: VBoxContainer = $PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom/Messages +@onready var scroll_container: ScrollContainerCustom = $PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom +@onready var line: LineEdit = $PanelContainer/MarginContainer/VBoxContainer/LineEdit +@onready var game_menu: GameMenu = get_parent() +@onready var game: Game = game_menu.game + +func _ready() -> void: + super() + for i in game.text_message_history: + add_message(i) + + game.text_message.connect( + func message(m: Game.TextMessage): + add_message(m) + ) + +func _input(event: InputEvent) -> void: + if Input.is_action_just_pressed("chat"): + if line.text != "": + game.mp.send_chat(game.my_player_id, line.text) + exit() + super(event) + +func add_message(message: Game.TextMessage): + var chat_message: ChatMessage = CHAT_MESSAGE_SCENE.instantiate() + messages_container.add_child(chat_message) + chat_message.set_message(message.username, message.text, message.color) + scroll_container.call_deferred("scroll_to_bottom") diff --git a/client/gui/menus/chat.gd.uid b/client/gui/menus/chat.gd.uid new file mode 100644 index 00000000..672792c0 --- /dev/null +++ b/client/gui/menus/chat.gd.uid @@ -0,0 +1 @@ +uid://cfweimyoq5vv0 diff --git a/client/gui/menus/chat.tscn b/client/gui/menus/chat.tscn new file mode 100644 index 00000000..626038f4 --- /dev/null +++ b/client/gui/menus/chat.tscn @@ -0,0 +1,56 @@ +[gd_scene load_steps=7 format=3 uid="uid://dbd6k56l4p0ls"] + +[ext_resource type="Script" uid="uid://cfweimyoq5vv0" path="res://gui/menus/chat.gd" id="1_gntkb"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="2_1au48"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="3_lrbjr"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="4_d4nta"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_l1coj"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_ff15x"] + +[node name="ChatOpen" type="Control"] +layout_mode = 3 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +script = ExtResource("1_gntkb") +support_anim = false +auto_anim = null + +[node name="PanelContainer" type="PanelContainer" parent="."] +material = ExtResource("2_1au48") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +theme = ExtResource("3_lrbjr") +theme_override_styles/panel = ExtResource("4_d4nta") +script = ExtResource("5_l1coj") + +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/separation = 0 + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] +material = ExtResource("2_1au48") +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("6_ff15x") +auto_scroll_to_bottom = true + +[node name="Messages" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="LineEdit" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer" groups=["autoselect"]] +layout_mode = 2 +placeholder_text = "c.chat.write_message" +keep_editing_on_text_submit = true diff --git a/client/gui/menus/document/document.gd b/client/gui/menus/document/document.gd new file mode 100644 index 00000000..c7042852 --- /dev/null +++ b/client/gui/menus/document/document.gd @@ -0,0 +1,152 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +const MARGIN: int = 75 + +var labels := {} + +func _ready(): + super() + $ScrollContainer/VBoxContainer.add_child(build_document(data)) + +func build_document(element: Dictionary, bullet: bool = false) -> Control: + var node: Control + match element["t"]: + "document": + node = VBoxContainer.new() + node.name = "Document" + for e in element["es"]: + node.add_child(build_document(e)) + "page": + node = PanelContainer.new() + node.name = "Page" + node.add_theme_stylebox_override("panel", preload("res://menu/theme/style/paper_panel_style.tres")) + node.set_custom_minimum_size(Vector2(800, 1131.371)) + var margin := MarginContainer.new() + margin.add_theme_constant_override("margin_bottom", MARGIN) + margin.add_theme_constant_override("margin_top", MARGIN) + margin.add_theme_constant_override("margin_left", MARGIN) + margin.add_theme_constant_override("margin_right", MARGIN) + var vbox := VBoxContainer.new() + if element["background"]: + margin.add_child(background(element["background"])) + margin.add_child(vbox) + for e in element["es"]: + vbox.add_child(build_document(e, bullet)) + node.add_child(margin) + "label": + var label_id = element["id"] + node = build_document(element["e"], bullet) + labels[label_id] = node + "list": + node = VBoxContainer.new() + node.name = "List" + for e in element["es"]: + node.add_child(build_document(e, true)) + "table": + node = VBoxContainer.new() + node.name = "Rows" + node.size_flags_horizontal = Control.SIZE_EXPAND_FILL + for r in range(element["es"].size()): + var row = HBoxContainer.new() + node.add_child(row) + row.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.name = "Row%d" % r + for c in element["es"][r]: + var e = build_document(c, bullet) + e.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.add_child(e) + "par": + node = VBoxContainer.new() + node.name = "Paragraph" + for e in element["es"]: + node.add_child(build_document(e, bullet)) + "ref": + # TODO: Support clicking + node = build_document(element["e"], bullet) + "conditional": + # Ignore all conditionals for now, since they are only revelant for typst version + node = Control.new() + "text": + node = text_node(element, bullet) + _: + node = Control.new() + push_error("Error building document: Unknown type \"%s\"" % element["t"]) + return node + +func text_node(element: Dictionary, bullet: bool) -> Control: + var node: Control + var label := Label.new() + # we need a hbox container for rtl + if bullet: + node = HBoxContainer.new() + var bullet_label := Label.new() + bullet_label.text = "•" + if element.get("size"): + bullet_label.add_theme_font_size_override("font_size", element["size"]) + # TODO: Ignore font color for now. Will be removed in the future. + # if element.get("color"): + # bullet_label.add_theme_color_override("font_color", Color(element["color"])) + bullet_label.add_theme_color_override("font_color", Color.BLACK) + label.add_theme_color_override("font_color", Color.BLACK) + node.add_child(bullet_label) + label.size_flags_horizontal = Control.SIZE_EXPAND_FILL + node.add_child(label) + else: + node = label + label.name = "Text" + label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + label.text = Global.get_message_str(element["s"]) + if element.get("font"): + match element["font"]: + "Great Vibes": + node.add_theme_font_override("font", preload("res://menu/theme/fonts/font-sansita-swashed.woff2")) + if element.get("size"): + node.add_theme_font_size_override("font_size", element["size"]) + # TODO: Ignore font color for now. Will be removed in the future. + # if element.get("color"): + # label.add_theme_color_override("font_color", Color(element["color"])) + label.add_theme_color_override("font_color", Color.BLACK) + return node + +func background(background_name: String) -> SubViewportContainer: + var item_name: String + match background_name: + "cover": item_name = "plate:plate,plate,plate,dirt" + "toc": item_name = "tomato" + "tomato_soup": item_name = "plate:tomato-soup" + "burger": item_name = "plate:sliced-bun,sliced-tomato,sliced-lettuce" + "mochi": item_name = "plate:strawberry-mochi" + "curry": item_name = "plate:curry,cooked-rice" + "icecream": item_name = "plate:strawberry-icecream" + "drinks": item_name = "glass:strawberry-shake" + var n: item_name = n + var scene: ItemRender = preload("res://menu/communicate/item/item_render.tscn").instantiate() + scene.set_item(item_name, false) + var vc := SubViewportContainer.new() + var viewport := SubViewport.new() + viewport.add_child(scene) + viewport.own_world_3d = true + viewport.transparent_bg = true + vc.size_flags_horizontal = Control.SIZE_SHRINK_CENTER + vc.size_flags_vertical = Control.SIZE_SHRINK_END + #vc.material = preload("res://menu/theme/materials/printed_material.tres") + vc.add_child(viewport) + return vc + +func _menu_open(): pass +func _menu_exit(): pass diff --git a/client/gui/menus/document/document.gd.uid b/client/gui/menus/document/document.gd.uid new file mode 100644 index 00000000..c84b53b1 --- /dev/null +++ b/client/gui/menus/document/document.gd.uid @@ -0,0 +1 @@ +uid://c83p4k0nredmd diff --git a/client/gui/menus/document/document.tscn b/client/gui/menus/document/document.tscn new file mode 100644 index 00000000..537ac8b8 --- /dev/null +++ b/client/gui/menus/document/document.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=3 format=3 uid="uid://bdggwo8un3mys"] + +[ext_resource type="Script" uid="uid://c83p4k0nredmd" path="res://gui/menus/document/document.gd" id="1_gyisx"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="2_0d0p0"] + +[node name="Document" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_gyisx") +support_anim = false +auto_anim = null + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("2_0d0p0") + +[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 6 +size_flags_vertical = 4 diff --git a/client/gui/menus/entry.gd b/client/gui/menus/entry.gd new file mode 100644 index 00000000..91bec795 --- /dev/null +++ b/client/gui/menus/entry.gd @@ -0,0 +1,35 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name Entry +extends Menu + +func _ready(): + super() + get_window().title = "Hurry Curry!" + + var args = OS.get_cmdline_user_args() + if args.size() == 1: + await submenu("res://gui/menus/game.tscn", args[0]) + elif not Global.get_setting("gameplay.setup_completed"): + await submenu("res://gui/menus/setup/setup.tscn") + else: + await submenu("res://gui/menus/main/main.tscn") + + print("Menu stack empty, quitting game.") + get_tree().quit() + +func quit(): + pass diff --git a/client/gui/menus/entry.gd.uid b/client/gui/menus/entry.gd.uid new file mode 100644 index 00000000..4bd126a6 --- /dev/null +++ b/client/gui/menus/entry.gd.uid @@ -0,0 +1 @@ +uid://yxaynnimyxgr diff --git a/client/gui/menus/entry.tscn b/client/gui/menus/entry.tscn new file mode 100644 index 00000000..f4eced3e --- /dev/null +++ b/client/gui/menus/entry.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://cd52sr1cmo8oj"] + +[ext_resource type="Script" uid="uid://yxaynnimyxgr" path="res://gui/menus/entry.gd" id="1_kibw2"] + +[node name="Entry" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_kibw2") diff --git a/client/gui/menus/error.gd b/client/gui/menus/error.gd new file mode 100644 index 00000000..e11812d5 --- /dev/null +++ b/client/gui/menus/error.gd @@ -0,0 +1,23 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +func _ready(): + super() + $Panel/SmartMarginContainer/contents/mesage.text = Global.error_message + +func _on_return_pressed(): + replace_menu("res://gui/menus/main/main.tscn") diff --git a/client/gui/menus/error.gd.uid b/client/gui/menus/error.gd.uid new file mode 100644 index 00000000..20a67804 --- /dev/null +++ b/client/gui/menus/error.gd.uid @@ -0,0 +1 @@ +uid://bl0n4atrdcogm diff --git a/client/gui/menus/error.tscn b/client/gui/menus/error.tscn new file mode 100644 index 00000000..dcebf322 --- /dev/null +++ b/client/gui/menus/error.tscn @@ -0,0 +1,70 @@ +[gd_scene load_steps=7 format=3 uid="uid://cimgn07lbcs4v"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_cabdu"] +[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://gui/menus/main/background.tscn" id="2_5fxol"] +[ext_resource type="Script" uid="uid://bl0n4atrdcogm" path="res://gui/menus/error.gd" id="2_dbe41"] +[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://gui/menus/transition/scene_transition.tscn" id="4_1nbt3"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_hxkkd"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="5_rfcg2"] + +[node name="ErrorMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_cabdu") +script = ExtResource("2_dbe41") + +[node name="MenuBackground" parent="." instance=ExtResource("2_5fxol")] + +[node name="Panel" type="Panel" parent="."] +material = ExtResource("4_hxkkd") +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="SmartMarginContainer" type="MarginContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("5_rfcg2") +metadata/_custom_type_script = "uid://byshs20og68tn" + +[node name="contents" type="VBoxContainer" parent="Panel/SmartMarginContainer"] +layout_mode = 2 +alignment = 1 + +[node name="title" type="Label" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 61 +text = "Error" +horizontal_alignment = 1 + +[node name="mesage" type="Label" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "This should be the error message." +horizontal_alignment = 1 + +[node name="Control" type="Control" parent="Panel/SmartMarginContainer/contents"] +custom_minimum_size = Vector2(0, 15.805) +layout_mode = 2 + +[node name="return" type="Button" parent="Panel/SmartMarginContainer/contents"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "Return to Main Menu" + +[node name="SceneTransition" parent="." instance=ExtResource("4_1nbt3")] +visible = false +layout_mode = 1 + +[connection signal="pressed" from="Panel/SmartMarginContainer/contents/return" to="." method="_on_return_pressed"] diff --git a/client/gui/menus/game.gd b/client/gui/menus/game.gd new file mode 100644 index 00000000..a4916b92 --- /dev/null +++ b/client/gui/menus/game.gd @@ -0,0 +1,64 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu +class_name GameMenu + +@onready var game: Game = $Game +@onready var debug_label: RichTextLabel = $Debug +@onready var overlay: Overlay = $Overlay +@onready var popup_message: PopupMessage = $PopupMessage +@onready var chat_preview: ChatPreview = $ChatPreview +@onready var pinned_items: PinnedItemMessages = $PinnedItemMessages + +func _ready(): + get_tree().get_root().go_back_requested.connect(open_ingame_menu) + super() + transition.set_loading_text(tr("c.menu.game.connecting")) + Settings.hook_changed_init("ui.hide_overlays", false, apply_hide_overlays) + +func _input(_event): + if Input.is_action_just_pressed("ui_menu"): + open_ingame_menu() + + if Input.is_action_just_pressed("chat"): + Sound.play_click() + chat_preview.visible = false + await submenu("res://gui/menus/chat.tscn") + chat_preview.visible = true + + if Input.is_action_just_pressed("toggle_overlay"): + Global.set_setting("ui.hide_overlays", not Global.get_setting("ui.hide_overlays")) + +func _menu_cover(state): + game.follow_camera.disable_input_menu = state + game.follow_camera.update_disable_input() + +func _process(_delta): + if Global.get_setting("graphics.debug_info"): + debug_label.show() + debug_label.text = "%d FPS\nDriver: %s" % [Engine.get_frames_per_second(), ProjectSettings.get_setting("rendering/rendering_device/driver")] + else: debug_label.hide() + +func open_ingame_menu(): + if popup != null: return + Sound.play_click() + submenu("res://gui/menus/ingame.tscn") + +func apply_hide_overlays(v: bool): + overlay.visible = v + pinned_items.visible = v + chat_preview.visible = v + popup_message.visible = false diff --git a/client/gui/menus/game.gd.uid b/client/gui/menus/game.gd.uid new file mode 100644 index 00000000..992bc7f3 --- /dev/null +++ b/client/gui/menus/game.gd.uid @@ -0,0 +1 @@ +uid://bmno0s2du3ie6 diff --git a/client/gui/menus/game.tscn b/client/gui/menus/game.tscn new file mode 100644 index 00000000..56df81d6 --- /dev/null +++ b/client/gui/menus/game.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=8 format=3 uid="uid://bbjwoxs71fnsk"] + +[ext_resource type="Script" uid="uid://bmno0s2du3ie6" path="res://gui/menus/game.gd" id="1_cdpsh"] +[ext_resource type="PackedScene" uid="uid://c6krh36hoqfg8" path="res://game.tscn" id="2_uojcy"] +[ext_resource type="PackedScene" uid="uid://bpikve6wlsjfl" path="res://gui/overlays/ingame/score.tscn" id="3_i0ytb"] +[ext_resource type="PackedScene" uid="uid://bc50la65ntifb" path="res://gui/overlays/lobby/lobby.tscn" id="3_udxby"] +[ext_resource type="PackedScene" uid="uid://b21nrnkygiyjt" path="res://gui/components/message/popup_message/popup_message.tscn" id="5_n1wy0"] +[ext_resource type="PackedScene" uid="uid://xcxbmynn8mhi" path="res://gui/overlays/ingame/chat.tscn" id="6_dh5lr"] +[ext_resource type="PackedScene" uid="uid://dcrr1rwdwbkq8" path="res://gui/components/message/popup_message/pinned_item_messages.tscn" id="7_lf2li"] + +[node name="GameMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_cdpsh") +auto_anim = false + +[node name="Game" parent="." instance=ExtResource("2_uojcy")] + +[node name="Overlay" parent="." instance=ExtResource("3_i0ytb")] +layout_mode = 1 + +[node name="Lobby" parent="." instance=ExtResource("3_udxby")] +layout_mode = 1 + +[node name="PinnedItemMessages" parent="." instance=ExtResource("7_lf2li")] +layout_mode = 1 + +[node name="ChatPreview" parent="." instance=ExtResource("6_dh5lr")] +layout_mode = 1 + +[node name="PopupMessage" parent="." instance=ExtResource("5_n1wy0")] +layout_mode = 1 + +[node name="Debug" type="RichTextLabel" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 diff --git a/client/gui/menus/ingame.gd b/client/gui/menus/ingame.gd new file mode 100644 index 00000000..4809b2ee --- /dev/null +++ b/client/gui/menus/ingame.gd @@ -0,0 +1,82 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +@onready var anim = $AnimationPlayer +@onready var options = $Side/Margin/Options +@onready var game: Game = $"../Game" +@onready var lobby_button: Button = $Side/Margin/Options/Lobby +@onready var leave_button: Button = $Side/Margin/Options/Leave + +var opened +func _ready(): + opened = Time.get_ticks_msec() + game.join_state_updated.connect(_on_game_join_state_changed) + _on_game_join_state_changed(game.join_state) + update_lobby_button() + super() + +func update_lobby_button(): + lobby_button.disabled = game.in_lobby or game.join_state == Game.JoinState.SPECTATING + if game.in_lobby: + lobby_button.tooltip_text = "Cannot cancel game since no game is running." + elif not game.join_state == Game.JoinState.JOINED: + lobby_button.tooltip_text = "You must join in order to be able to cancel the current game." + else: + lobby_button.tooltip_text = "" + +func anim_setup(): pass +func _menu_open(): + anim.play("activate") + await anim.animation_finished + game.mp.send_idle(true) +func _menu_exit(): + game.mp.send_idle(false) + anim.play_backwards("activate") + await anim.animation_finished + +func _on_resume_pressed(): + exit() + +func _on_main_menu_pressed(): + parent_menu.replace_menu("res://gui/menus/main/main.tscn") + +func _on_settings_pressed(): + submenu("res://gui/menus/settings/settings.tscn") + +func _on_reconnect_pressed(): + parent_menu.replace_menu("res://gui/menus/game.tscn", parent_menu.data) + +func _on_quit_pressed(): + quit() + +func _on_lobby_pressed(): + game.mp.send_chat(game.my_player_id, "/end") + exit() + +func _on_leave_pressed(): + game.toggle_join() + +func _on_game_join_state_changed(state: Game.JoinState): + match state: + Game.JoinState.JOINED: + leave_button.disabled = false + leave_button.text = tr("c.menu.ingame.leave") + Game.JoinState.SPECTATING: + leave_button.disabled = false + leave_button.text = tr("c.menu.ingame.join") + Game.JoinState.WAITING: + leave_button.disabled = true diff --git a/client/gui/menus/ingame.gd.uid b/client/gui/menus/ingame.gd.uid new file mode 100644 index 00000000..496c313c --- /dev/null +++ b/client/gui/menus/ingame.gd.uid @@ -0,0 +1 @@ +uid://dyi2xohgxeybb diff --git a/client/gui/menus/ingame.tscn b/client/gui/menus/ingame.tscn new file mode 100644 index 00000000..0a77af14 --- /dev/null +++ b/client/gui/menus/ingame.tscn @@ -0,0 +1,142 @@ +[gd_scene load_steps=12 format=3 uid="uid://lxlgtjm8hw7v"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_2vmyh"] +[ext_resource type="Script" uid="uid://dyi2xohgxeybb" path="res://gui/menus/ingame.gd" id="2_0h3no"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_vvvlt"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_b6bm7"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="4_scupw"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="4_vr8y1"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="6_poj4k"] + +[sub_resource type="Animation" id="Animation_8sedy"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Side:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.0005, 0, 0.0005, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_660jl"] +resource_name = "activate" +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Side:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(-400, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_u0kyp"] +_data = { +&"RESET": SubResource("Animation_8sedy"), +&"activate": SubResource("Animation_660jl") +} + +[sub_resource type="FontVariation" id="FontVariation_ud3l8"] +base_font = ExtResource("4_scupw") +variation_embolden = 0.5 + +[node name="IngameMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_2vmyh") +script = ExtResource("2_0h3no") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_u0kyp") +} +speed_scale = 8.0 + +[node name="Side" type="PanelContainer" parent="."] +material = ExtResource("3_vvvlt") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("4_vr8y1") +script = ExtResource("4_b6bm7") + +[node name="Margin" type="MarginContainer" parent="Side"] +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 +script = ExtResource("6_poj4k") + +[node name="Options" type="VBoxContainer" parent="Side/Margin"] +layout_mode = 2 + +[node name="Title" type="Label" parent="Side/Margin/Options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_ud3l8") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="Spacer" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="Resume" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.resume" +alignment = 0 + +[node name="Leave" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.join" +alignment = 0 + +[node name="Lobby" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.cancel" +alignment = 0 + +[node name="Reconnect" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.reconnect" +alignment = 0 + +[node name="Spacer2" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="Settings" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.settings" +alignment = 0 + +[node name="Spacer3" type="Control" parent="Side/Margin/Options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="MainMenu" type="Button" parent="Side/Margin/Options"] +layout_mode = 2 +text = "c.menu.ingame.main_menu" +alignment = 0 + +[connection signal="pressed" from="Side/Margin/Options/Resume" to="." method="_on_resume_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Leave" to="." method="_on_leave_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Lobby" to="." method="_on_lobby_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Reconnect" to="." method="_on_reconnect_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Settings" to="." method="_on_settings_pressed"] +[connection signal="pressed" from="Side/Margin/Options/MainMenu" to="." method="_on_main_menu_pressed"] diff --git a/client/gui/menus/main/about.gd b/client/gui/menus/main/about.gd new file mode 100644 index 00000000..b56d3941 --- /dev/null +++ b/client/gui/menus/main/about.gd @@ -0,0 +1,169 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# + +extends Menu + +var authors := ["metamuffin", "nokoe", "tpart"] +var contributors := ["sofviic", "BigBrotherNii", "Miner34"] +const cc_by_4 := "CC-BY 4.0" +const cc_by_3 := "CC-BY 3.0" +const cc0 := "CC0" + +const AGPL_NOTICE := """This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, version 3 of the License only. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>.""" + +const SOURCE_CODE := "https://codeberg.org/hurrycurry/hurrycurry" + +func _ready() -> void: + super() + $side/margin/options/first/source.tooltip_text = SOURCE_CODE + +var credits := [ + [tr("c.credits.models"), [ + ["kenney.nl", "Various Models", cc0], + ["Kay Lousberg", "Kitchen tiles", cc0], + ["Poly by Google", "Strawberry", cc_by_3], + ["Poly by Google", "Fish", cc_by_3], + ["jeremy", "Propeller hat", cc_by_3] + ]], + [tr("c.credits.sounds"), [ + ["Dryoma", "Footstep sounds", cc_by_4], + ["Koops", "Page_Turn_24.wav", cc_by_4], + ["InspectorJ", "Pencil, Writing, Close, A.wav", cc_by_4], + ["Dillon Becker", "Super Dialogue Audio Pack", cc_by_4], + ["Ellr", "Universal UI/Menu Soundpack", cc_by_4], + ["toyoto", "Woosh Fleuret Escrime B.wav", cc_by_4], + ["deleted_user_877451", "Game_over.wav", cc_by_3], + ["Quaternius", "Someting, dont remember...", cc0], + ["Dillon Becker", "Super Dialogue Audio Pack V1", cc_by_4] + ]], + [tr("c.credits.translations"), { + tr("c.settings.ui.language.zh_Hans"): ["Outbreak2096"], + tr("c.settings.ui.language.zh_Hant"): ["hugoalh"], + tr("c.settings.ui.language.nl"): ["Vistaus"], + tr("c.settings.ui.language.it"): ["Miner34", "solemden"], + tr("c.settings.ui.language.eu"): ["josuigoa"], + tr("c.settings.ui.language.fr"): ["fnetX", "lejun"], + tr("c.settings.ui.language.pl"): ["tranzystorekk"], + tr("c.settings.ui.language.he"): ["RustyStriker"], + tr("c.settings.ui.language.el"): ["n0toose"], + tr("c.settings.ui.language.ja"): ["BigBrotherNii"], + tr("c.settings.ui.language.ar"): ["sofviic"], + tr("c.settings.ui.language.tr"): ["furkanunsalan", "tekrei"], + tr("c.settings.ui.language.ru"): ["0ko"], + }] +] + +func _menu_cover(state): + $side.visible = not state + +func credits_text() -> String: + var text = "[center]" + authors.shuffle() + contributors.shuffle() + + text += "\n\n\n[b]%s[/b]\n\n%s\n\n[b]%s[/b]\n\n%s\n\n[b]%s[/b]\n\n\n" % [ + tr("c.credits.title"), + tr("c.credits.developed_by"), + "\n".join(authors), + tr("c.credits.contributors"), + ", ".join(contributors), + ] + + for section in credits: + text += "[b]%s[/b]\n\n" % section[0] + if typeof(section[1]) == TYPE_DICTIONARY: + text += "[table=2]" + for key in section[1]: + text += "[cell][right]%s[/right][/cell]" % key + text += "[cell][left]%s[/left][/cell]" % ", ".join(section[1][key]) + text += "[/table]" + else: + text += "[table=3]" + for entry in section[1]: + text += "[cell][right]%s[/right][/cell]" % entry[0] + text += "[cell][left]%s[/left][/cell]" % entry[1] + text += "[cell][left]%s[/left][/cell]" % entry[2] + text += "[/table]" + text += "\n\n\n" + + text += "\n[b]%s[/b]\n\n\n[/center]" % tr("c.credits.thanks") + return text + +func legal_text() -> String: + var all: Array[String] = [] + var translators: Array[String] = [] + for c in credits[2][1].values(): + translators.append_array(c) + translators.shuffle() + authors.shuffle() + contributors.shuffle() + all.append_array(authors) + all.append_array(contributors) + all.append_array(translators) + + var text := "Hurry Curry! - a game about cooking\n" + text += "[code]Copyright 2024, 2025 %s\n\n" % ", ".join(dedup_array(all)) + text += "%s[/code]\n\n" % AGPL_NOTICE + text += tr("c.legal.using_godot") + text += "\n\n[code]%s[/code]" % Engine.get_license_text() + return text + +func version_text() -> String: + var text := "[center][b]Hurry Curry![/b]\n\n" + OS.get_version() + text += "[table=2]" + var row = "[cell][right]%s[/right][/cell][cell][left]%s[/left][/cell]" + text += row % [tr("c.version.game"), Global.VERSION] + text += row % [tr("c.version.protocol"), "%s.%s" % [Multiplayer.VERSION_MAJOR, Multiplayer.VERSION_MINOR]] + text += row % [tr("c.version.godot"), Engine.get_version_info().string] + text += row % [tr("c.version.os"), OS.get_name()] + text += row % [tr("c.version.arch"), Engine.get_architecture_name()] + text += row % [tr("c.version.distribution"), Global.DISTRIBUTION] + + text += "[/table]" + text += "[/center]" + return text + +func _on_credits_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", credits_text()) + +func _on_legal_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", legal_text()) + +func _on_version_pressed() -> void: + submenu("res://gui/menus/popup_large.tscn", version_text()) + +func _on_back_pressed() -> void: + exit() + + +func _on_source_pressed() -> void: + OS.shell_open(SOURCE_CODE) + +func dedup_array(a: Array) -> Array: + var b = [] + for x in a: if not b.has(x): b.append(x) + return b diff --git a/client/gui/menus/main/about.gd.uid b/client/gui/menus/main/about.gd.uid new file mode 100644 index 00000000..3929f2c3 --- /dev/null +++ b/client/gui/menus/main/about.gd.uid @@ -0,0 +1 @@ +uid://pcu87stpkgd8 diff --git a/client/gui/menus/main/about.tscn b/client/gui/menus/main/about.tscn new file mode 100644 index 00000000..006b61fe --- /dev/null +++ b/client/gui/menus/main/about.tscn @@ -0,0 +1,93 @@ +[gd_scene load_steps=7 format=3 uid="uid://bpaenm8c6nmo8"] + +[ext_resource type="Script" uid="uid://pcu87stpkgd8" path="res://gui/menus/main/about.gd" id="1_0acu0"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="1_ai5pk"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="2_pya1x"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="4_kx3j7"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="4_t51wf"] + +[sub_resource type="FontVariation" id="FontVariation_o2r3e"] +base_font = ExtResource("4_kx3j7") +variation_embolden = 0.5 + +[node name="AboutMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_0acu0") +support_anim = false + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("1_ai5pk") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("2_pya1x") + +[node name="margin" type="MarginContainer" parent="side"] +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 +script = ExtResource("4_t51wf") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_o2r3e") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="first" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 + +[node name="credits" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.credits" +alignment = 0 + +[node name="version" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.version" +alignment = 0 + +[node name="legal" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.legal" +alignment = 0 + +[node name="source" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about.source" +alignment = 0 + +[node name="first2" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 +size_flags_vertical = 3 +alignment = 2 + +[node name="back" type="Button" parent="side/margin/options/first2"] +layout_mode = 2 +text = "c.menu.back" +alignment = 0 + +[connection signal="pressed" from="side/margin/options/first/credits" to="." method="_on_credits_pressed"] +[connection signal="pressed" from="side/margin/options/first/version" to="." method="_on_version_pressed"] +[connection signal="pressed" from="side/margin/options/first/legal" to="." method="_on_legal_pressed"] +[connection signal="pressed" from="side/margin/options/first/source" to="." method="_on_source_pressed"] +[connection signal="pressed" from="side/margin/options/first2/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/main/background.gd b/client/gui/menus/main/background.gd new file mode 100644 index 00000000..4abb84b4 --- /dev/null +++ b/client/gui/menus/main/background.gd @@ -0,0 +1,50 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Node3D + +const CRATES = ["tomato-crate", "steak-crate", "cheese-crate", "lettuce-crate", "flour-crate", "coconut-crate"] +const TOOLS = ["stove", "stove", "stove", "sink", "cuttingboard", "sink", "cuttingboard", "oven", "freezer"] + +@onready var environment: WorldEnvironment = $Environment +@onready var map: Map = $Map + +func _ready(): + if !Global.on_vulkan(): + environment.environment.tonemap_exposure = 0.25 + + var tiles = {} + for x in range(-10, 11): + for y in range(-10, 11): + var w = exp(-sqrt(x * x + y * y) * 0.15) + var k = randf() * w + var tn = null + if k > 0.25: tn = "floor" + if k > 0.4: tn = choose(CRATES) if randf() > 0.3 else "counter" + if k > 0.6: tn = choose(TOOLS) + if tn != null: tiles[str(Vector2i(x,y))] = [tn,[x,y]] + + var gt = func (cs): + var t = tiles.get(str(Vector2i(cs[0],cs[1]))) + return null if t == null else t[0] + for pk in tiles.keys(): + var x = tiles[pk][1][0] + var y = tiles[pk][1][1] + var t = gt.call([x,y]) + if t != null: map.set_tile(Vector2i(x,y), t, [[x,y-1],[x-1,y],[x,y+1],[x+1,y]].map(gt)) + + map.flush() + +func choose(a): return a[floor(a.size() * randf())] diff --git a/client/gui/menus/main/background.gd.uid b/client/gui/menus/main/background.gd.uid new file mode 100644 index 00000000..7d61d488 --- /dev/null +++ b/client/gui/menus/main/background.gd.uid @@ -0,0 +1 @@ +uid://b2tq5rcjjcxdg diff --git a/client/gui/menus/main/background.tscn b/client/gui/menus/main/background.tscn new file mode 100644 index 00000000..2bd4ee04 --- /dev/null +++ b/client/gui/menus/main/background.tscn @@ -0,0 +1,71 @@ +[gd_scene load_steps=12 format=3 uid="uid://l4vm07dtda4j"] + +[ext_resource type="Script" uid="uid://b2tq5rcjjcxdg" path="res://gui/menus/main/background.gd" id="1_pgu7b"] +[ext_resource type="Script" uid="uid://cwg7wympevxs4" path="res://map/auto_setup/environment_setup.gd" id="2_7dwbj"] +[ext_resource type="Shader" uid="uid://b1k6ipo0sagli" path="res://gui/menus/main/clouds.gdshader" id="3_lapmn"] +[ext_resource type="PackedScene" uid="uid://b4gone8fu53r7" path="res://map/map.tscn" id="4_nslxb"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_uw50b"] +sky_top_color = Color(0.55, 0.55, 0.55, 1) + +[sub_resource type="Sky" id="Sky_utrtx"] +sky_material = SubResource("ProceduralSkyMaterial_uw50b") + +[sub_resource type="Environment" id="Environment_slkjl"] +background_mode = 1 +background_color = Color(0.517035, 0.49506, 0.878906, 1) +sky = SubResource("Sky_utrtx") +tonemap_mode = 2 +tonemap_exposure = 0.6 +tonemap_white = 0.9 +ssao_enabled = true + +[sub_resource type="QuadMesh" id="QuadMesh_fvp2p"] +size = Vector2(100, 100) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_e3eby"] +noise_type = 2 +frequency = 0.008 +fractal_octaves = 7 +fractal_gain = 0.72 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_s4fnp"] +width = 1024 +height = 1024 +generate_mipmaps = false +seamless = true +noise = SubResource("FastNoiseLite_e3eby") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_gd87g"] +render_priority = 0 +shader = ExtResource("3_lapmn") +shader_parameter/noise = SubResource("NoiseTexture2D_s4fnp") +shader_parameter/ccloud = Color(0.835938, 0.835938, 0.835938, 1) +shader_parameter/csky = Color(0.329412, 0.333333, 0.8, 1) + +[node name="MenuBackground" type="Node3D"] +script = ExtResource("1_pgu7b") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(0.614606, 0.499662, -0.610408, -0.00282255, 0.775198, 0.631712, 0.78883, -0.386531, 0.477852, -9.13611, 4.90356, 1.22532) +projection = 1 +current = true +size = 8.0 +far = 100.0 + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.290334, 0.904946, -0.311092, 0.336606, 0.207739, 0.918445, 0.895769, -0.371371, -0.244296, 0, 7, 0) +light_energy = 1.25 +shadow_enabled = true + +[node name="Environment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_slkjl") +script = ExtResource("2_7dwbj") +allow_sdfgi = false + +[node name="the-sky-tm" type="MeshInstance3D" parent="."] +transform = Transform3D(0.614606, 0.499662, -0.610408, -0.00282255, 0.775198, 0.631712, 0.78883, -0.386531, 0.477851, 6, -13, -11) +mesh = SubResource("QuadMesh_fvp2p") +surface_material_override/0 = SubResource("ShaderMaterial_gd87g") + +[node name="Map" parent="." instance=ExtResource("4_nslxb")] diff --git a/client/gui/menus/main/clouds.gdshader b/client/gui/menus/main/clouds.gdshader new file mode 100644 index 00000000..8103f691 --- /dev/null +++ b/client/gui/menus/main/clouds.gdshader @@ -0,0 +1,36 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +shader_type spatial; +render_mode unshaded; + +uniform sampler2D noise : source_color; +uniform vec3 ccloud : source_color; +uniform vec3 csky : source_color; + +void fragment() { + vec2 uv = UV * 0.9; + uv += TIME * vec2(0.001,0.002); + + float f = texture(noise, uv).x; + f = 1. - f; + f = pow(f, 1.5); + f = floor(f*5.)/5.; + f = pow(f, 2.); + + ALBEDO = mix(csky, ccloud, f); +} diff --git a/client/gui/menus/main/clouds.gdshader.uid b/client/gui/menus/main/clouds.gdshader.uid new file mode 100644 index 00000000..00c2d21a --- /dev/null +++ b/client/gui/menus/main/clouds.gdshader.uid @@ -0,0 +1 @@ +uid://b1k6ipo0sagli diff --git a/client/gui/menus/main/main.gd b/client/gui/menus/main/main.gd new file mode 100644 index 00000000..423f756e --- /dev/null +++ b/client/gui/menus/main/main.gd @@ -0,0 +1,44 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +@onready var quit_button = $side/margin/options/first/quit +@onready var margin_container: MarginContainer = $side/margin + +func _ready(): + super() + if OS.has_feature("web"): + quit_button.hide() + Sound.play_music("MainMenu") + ServerList.one_shot() + +func _menu_cover(state): + $side.visible = not state + +func _on_quit_pressed(): + quit() + +func _on_about_pressed(): + submenu("res://gui/menus/main/about.tscn") + +func _on_change_character_pressed(): + replace_menu("res://gui/menus/character.tscn", null, "res://gui/menus/main.tscn") + +func _on_settings_pressed(): + submenu("res://gui/menus/settings/settings.tscn") + +func _on_play_pressed(): + submenu("res://gui/menus/main/play.tscn") diff --git a/client/gui/menus/main/main.gd.uid b/client/gui/menus/main/main.gd.uid new file mode 100644 index 00000000..dc2cecd3 --- /dev/null +++ b/client/gui/menus/main/main.gd.uid @@ -0,0 +1 @@ +uid://bpiynadrmdd37 diff --git a/client/gui/menus/main/main.tscn b/client/gui/menus/main/main.tscn new file mode 100644 index 00000000..81595966 --- /dev/null +++ b/client/gui/menus/main/main.tscn @@ -0,0 +1,94 @@ +[gd_scene load_steps=10 format=3 uid="uid://dbj8508whxgwv"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_3qfu3"] +[ext_resource type="Script" uid="uid://bpiynadrmdd37" path="res://gui/menus/main/main.gd" id="2_xjnc3"] +[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://gui/menus/main/background.tscn" id="3_4evao"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="4_nx4vf"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_0mn56"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="5_k7bqq"] +[ext_resource type="StyleBox" uid="uid://bw4jamyna1top" path="res://gui/resources/style/panel_style_sidebar.tres" id="5_qlyeo"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="7_btdj1"] + +[sub_resource type="FontVariation" id="FontVariation_htgmg"] +base_font = ExtResource("5_k7bqq") +variation_embolden = 0.5 + +[node name="MainMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_3qfu3") +script = ExtResource("2_xjnc3") + +[node name="MenuBackground" parent="." instance=ExtResource("3_4evao")] + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("4_nx4vf") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = ExtResource("5_qlyeo") +script = ExtResource("5_0mn56") + +[node name="margin" type="MarginContainer" parent="side"] +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 +script = ExtResource("7_btdj1") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_htgmg") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="first" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 + +[node name="play" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.play" +alignment = 0 + +[node name="change_character" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.my_chef" +alignment = 0 + +[node name="settings" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.settings" +alignment = 0 + +[node name="about" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.about" +alignment = 0 + +[node name="quit" type="Button" parent="side/margin/options/first"] +layout_mode = 2 +text = "c.menu.quit" +alignment = 0 + +[connection signal="pressed" from="side/margin/options/first/play" to="." method="_on_play_pressed"] +[connection signal="pressed" from="side/margin/options/first/change_character" to="." method="_on_change_character_pressed"] +[connection signal="pressed" from="side/margin/options/first/settings" to="." method="_on_settings_pressed"] +[connection signal="pressed" from="side/margin/options/first/about" to="." method="_on_about_pressed"] +[connection signal="pressed" from="side/margin/options/first/quit" to="." method="_on_quit_pressed"] diff --git a/client/gui/menus/main/play.gd b/client/gui/menus/main/play.gd new file mode 100644 index 00000000..c9cbee2f --- /dev/null +++ b/client/gui/menus/main/play.gd @@ -0,0 +1,208 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +var server_list_item: PackedScene = preload("res://gui/menus/main/server_list_item.tscn") +var url_regex: RegEx = RegEx.new() + +@onready var server_list: VBoxContainer = $side/margin/options/second/ScrollContainerCustom/ServerList +@onready var server_list_loading: Label = $side/margin/options/second/Loading +@onready var server_list_empty: Label = $side/margin/options/second/NoServers +@onready var connect_uri = $side/margin/options/second/connect/uri +@onready var server = $side/margin/options/second/server +@onready var server_control = $side/margin/options/second/server/control +@onready var server_connect = $side/margin/options/second/server/connect +@onready var editor_control = $side/margin/options/second/editor/control +@onready var editor_connect = $side/margin/options/second/editor/connect +@onready var editor_container = $side/margin/options/second/editor + + +func _ready(): + url_regex.compile("^(?:(ws|wss)://)?([^:]+)(?::([0-9]+))?$") + if OS.has_feature("web"): + server.hide() + connect_uri.text = Global.get_profile("last_server_url") + Sound.play_music("MainMenu") + + ServerList.update_server_list.connect(update_server_list) + ServerList.update_loading.connect(update_server_list_loading) + update_server_list(ServerList.current_list) + update_server_list_loading(ServerList.loading) + + super() + if not Global.get_profile("registry_asked"): + var popup_data := MenuPopup.Data.new() + popup_data.text = tr("c.menu.play.allow_query_registry").format([Global.get_setting("online.registry_url")]) + var allow_button := Button.new() + allow_button.text = tr("c.menu.accept") + var deny_button := Button.new() + deny_button.text = tr("c.menu.deny") + allow_button.pressed.connect(func(): Global.set_setting("online.use_registry", true)) + deny_button.pressed.connect(func(): Global.set_setting("online.use_registry", false)) + popup_data.buttons = [allow_button, deny_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + Global.set_profile("registry_asked", true) + Global.save_settings() + Global.save_profile() + + ServerList.start() + +func update_server_list(lists: Array[Array]): + # Find out the index of the currently focused server in the list + var prev_selected_idx := -1 + for i in range(server_list.get_children().size()): + if server_list.get_child(i).button.has_focus(): + prev_selected_idx = i + break + + for c in server_list.get_children(): + c.queue_free() + + var idx := 0 + for l in lists: + for i in l: + var server_item: ServerListItem = server_list_item.instantiate() + server_list.add_child(server_item) + # TODO: Implement fallback address correctly + server_item.setup(i.name, roundi(i.players_online), i.version) + server_item.button.pressed.connect(connect_to.bind(i.address[0])) + # Focus the same server with the same index as the previously focused one + if idx == prev_selected_idx: + server_item.button.grab_focus() + idx += 1 + + if prev_selected_idx > idx: + # Same index cannot be focused, since number of servers decreased + if idx - 1 < 0: + connect_uri.grab_focus() + else: + server_list.get_child(idx - 1).button.grab_focus() + + # Show message if no servers available + server_list_empty.visible = idx == 0 + +func update_server_list_loading(status: bool): + server_list_loading.visible = status + +func _menu_cover(state): + $side.visible = not state + +func _on_connect_pressed(): + var url = connect_uri.text + var result := url_regex.search(url) + if result != null: + if result.get_string(1) == "": + url = "ws://" + url + # only set default port for non-tls websocket connections + if result.get_string(3) == "" and result.get_string(1) != "wss": + url = url + ":27032" + connect_uri.text = url + Global.set_profile("last_server_url", url) + Global.save_profile() + connect_to(url) + +func _on_quick_connect_pressed(): + if OS.has_feature("web"): + connect_to(JavaScriptBridge.eval(""" + window.location.protocol.endsWith("s:") + ? `wss://${window.location.host}/` + : `ws://${window.location.hostname}:27032/` + """)) + else: + connect_to("wss://hurrycurry.metamuffin.org/") + +func connect_to(url: String): + print("Connecting to %s" % url) + get_parent().replace_menu("res://gui/menus/game.tscn", url) + +func _on_server_control_pressed(): + match Server.state: + Service.State.RUNNING: Server.stop() + Service.State.STOPPED: Server.start() + Service.State.FAILED: Server.start() + +func _on_editor_control_pressed(): + match Editor.state: + Service.State.RUNNING: Editor.stop() + Service.State.STOPPED: Editor.start(); Server.start() + Service.State.FAILED: Editor.start() + +func _on_server_connect_pressed(): + connect_to("ws://%s:%d" % [Server.connect_address(), Global.get_setting("server.bind_port")]) + +func _on_editor_connect_pressed(): + connect_to("ws://[::1]:27032/") + +func _process(_delta): + server_control.disabled = false + server_connect.visible = Server.state == Service.State.RUNNING + server_control.modulate = Color.WHITE + match Server.state: + Service.State.RUNNING: + server_control.text = tr("c.menu.play.server_stop") + server_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + server_control.text = tr("c.menu.play.server_testing") + server_control.disabled = true + Service.State.STARTING: + server_control.text = tr("c.menu.play.server_starting") + server_control.disabled = true + Service.State.STOPPED: + server_control.text = tr("c.menu.play.server_start") + Service.State.FAILED: + server_control.text = tr("c.menu.play.server_failed") + server_control.modulate = Color(1, 0.4, 0.5) + server_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + server_control.text = tr("c.menu.play.server_unavailable") + server_control.disabled = true + server_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + editor_control.disabled = false + editor_connect.visible = Editor.state == Service.State.RUNNING + editor_control.modulate = Color.WHITE + editor_container.visible = Editor.state != Service.State.UNAVAILABLE + match Editor.state: + Service.State.RUNNING: + editor_control.text = tr("c.menu.play.editor_stop") + editor_control.modulate = Color.AQUAMARINE + Service.State.TESTING: + editor_control.text = tr("c.menu.play.editor_testing") + editor_control.disabled = true + Service.State.STARTING: + editor_control.text = tr("c.menu.play.editor_starting") + editor_control.disabled = true + Service.State.STOPPED: + editor_control.text = tr("c.menu.play.editor_start") + Service.State.FAILED: + editor_control.text = tr("c.menu.play.editor_failed") + editor_control.modulate = Color(1, 0.4, 0.5) + editor_control.tooltip_text = tr("c.menu.play.server_failed_tooltip") + Service.State.UNAVAILABLE: + editor_control.text = tr("c.menu.play.editor_unavailable") + editor_control.disabled = true + editor_control.tooltip_text = tr("c.menu.play.server_binary_not_found") + + +func _on_uri_text_changed(new_text): + connect_uri.modulate = Color.WHITE if url_regex.search(new_text) else Color.RED + +func _on_back_pressed(): + exit() + +func _menu_exit(): + ServerList.stop() + super() diff --git a/client/gui/menus/main/play.gd.uid b/client/gui/menus/main/play.gd.uid new file mode 100644 index 00000000..d8ca168f --- /dev/null +++ b/client/gui/menus/main/play.gd.uid @@ -0,0 +1 @@ +uid://b126k2228nj4s diff --git a/client/gui/menus/main/play.tscn b/client/gui/menus/main/play.tscn new file mode 100644 index 00000000..441024a2 --- /dev/null +++ b/client/gui/menus/main/play.tscn @@ -0,0 +1,149 @@ +[gd_scene load_steps=9 format=3 uid="uid://c8url5fpttbem"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_cckds"] +[ext_resource type="Script" uid="uid://b126k2228nj4s" path="res://gui/menus/main/play.gd" id="2_phxx0"] +[ext_resource type="Material" uid="uid://2j8a0c0a2ta5" path="res://gui/resources/materials/blur_material.tres" id="3_fsbt7"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="4_gst6r"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="5_cm120"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="5_ojpbf"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ukani"] + +[sub_resource type="FontVariation" id="FontVariation_htgmg"] +base_font = ExtResource("5_ojpbf") +variation_embolden = 0.5 + +[node name="PlayMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_cckds") +script = ExtResource("2_phxx0") +support_anim = false + +[node name="side" type="PanelContainer" parent="."] +material = ExtResource("3_fsbt7") +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 294.0 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ukani") + +[node name="margin" type="MarginContainer" parent="side"] +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 +script = ExtResource("4_gst6r") + +[node name="options" type="VBoxContainer" parent="side/margin"] +layout_mode = 2 + +[node name="title" type="Label" parent="side/margin/options"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) +theme_override_constants/outline_size = 10 +theme_override_fonts/font = SubResource("FontVariation_htgmg") +theme_override_font_sizes/font_size = 48 +text = "Hurry Curry!" + +[node name="spacer" type="Control" parent="side/margin/options"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="second" type="VBoxContainer" parent="side/margin/options"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Loading" type="Label" parent="side/margin/options/second"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.fetching_list" +horizontal_alignment = 1 + +[node name="NoServers" type="Label" parent="side/margin/options/second"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.no_servers" +horizontal_alignment = 1 + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="side/margin/options/second"] +layout_mode = 2 +size_flags_vertical = 3 +horizontal_scroll_mode = 0 +script = ExtResource("5_cm120") + +[node name="ServerList" type="VBoxContainer" parent="side/margin/options/second/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="spacer" type="Control" parent="side/margin/options/second"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="connect" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="uri" type="LineEdit" parent="side/margin/options/second/connect"] +auto_translate_mode = 2 +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "wss://example.org" + +[node name="connect" type="Button" parent="side/margin/options/second/connect"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="server" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="control" type="Button" parent="side/margin/options/second/server"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.server" +alignment = 0 + +[node name="connect" type="Button" parent="side/margin/options/second/server"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="editor" type="HBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[node name="control" type="Button" parent="side/margin/options/second/editor"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "c.menu.play.editor" +alignment = 0 + +[node name="connect" type="Button" parent="side/margin/options/second/editor"] +layout_mode = 2 +text = "c.menu.play.connect" + +[node name="spacer2" type="Control" parent="side/margin/options/second"] +custom_minimum_size = Vector2(0, 10) +layout_mode = 2 + +[node name="back" type="Button" parent="side/margin/options/second"] +layout_mode = 2 +text = "c.menu.back" +alignment = 0 + +[node name="VBoxContainer" type="VBoxContainer" parent="side/margin/options/second"] +layout_mode = 2 + +[connection signal="text_changed" from="side/margin/options/second/connect/uri" to="." method="_on_uri_text_changed"] +[connection signal="pressed" from="side/margin/options/second/connect/connect" to="." method="_on_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/server/control" to="." method="_on_server_control_pressed"] +[connection signal="pressed" from="side/margin/options/second/server/connect" to="." method="_on_server_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/editor/control" to="." method="_on_editor_control_pressed"] +[connection signal="pressed" from="side/margin/options/second/editor/connect" to="." method="_on_editor_connect_pressed"] +[connection signal="pressed" from="side/margin/options/second/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/main/server_list_item.gd b/client/gui/menus/main/server_list_item.gd new file mode 100644 index 00000000..0cffdd72 --- /dev/null +++ b/client/gui/menus/main/server_list_item.gd @@ -0,0 +1,38 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name ServerListItem +extends PanelContainer + +var error_style_focus: StyleBoxFlat = preload("res://gui/resources/style/error_focus_style.tres") +@onready var title: Label = $MarginContainer/VBoxContainer/Title +@onready var info: Label = $MarginContainer/VBoxContainer/Info +@onready var button: Button = $Button + +func setup(name_: String, online_players: int, version: Array): + title.text = name_ + if version[0] != Multiplayer.VERSION_MAJOR or version[1] > Multiplayer.VERSION_MINOR: + button.disabled = true + button.add_theme_stylebox_override("focus", error_style_focus) + info.text = tr("c.menu.play.server_version_mismatch") + info.add_theme_color_override("font_color", Color("ff2222")) + return + info.text = tr("c.menu.play.server_players").format([online_players]) + + # This node is in group not no_click_sound, so sounds won't be automatically connected + # by menu system. Reason: These nodes are deleted and re-created every few seconds + # in server list, and signals are only connected on ready. + button.pressed.connect(Sound.play_click) + button.mouse_entered.connect(Sound.play_hover) diff --git a/client/gui/menus/main/server_list_item.gd.uid b/client/gui/menus/main/server_list_item.gd.uid new file mode 100644 index 00000000..276bb06f --- /dev/null +++ b/client/gui/menus/main/server_list_item.gd.uid @@ -0,0 +1 @@ +uid://xr5oigbgd0aw diff --git a/client/gui/menus/main/server_list_item.tscn b/client/gui/menus/main/server_list_item.tscn new file mode 100644 index 00000000..40e9eedb --- /dev/null +++ b/client/gui/menus/main/server_list_item.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=3 format=3 uid="uid://t2h60dhuvfsk"] + +[ext_resource type="Script" uid="uid://xr5oigbgd0aw" path="res://gui/menus/main/server_list_item.gd" id="1_1n1yg"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1n1yg"] + +[node name="ServerListItem" type="PanelContainer"] +offset_right = 400.0 +offset_bottom = 40.0 +size_flags_horizontal = 3 +theme_override_styles/panel = SubResource("StyleBoxEmpty_1n1yg") +script = ExtResource("1_1n1yg") + +[node name="Button" type="Button" parent="." groups=["no_click_sound"]] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +mouse_filter = 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 +mouse_filter = 2 + +[node name="Title" type="Label" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.87451, 0.87451, 0.87451, 1) +theme_override_font_sizes/font_size = 18 +text = "Example Server" + +[node name="Info" type="Label" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.749781, 0.74978, 0.74978, 1) +theme_override_font_sizes/font_size = 14 +text = "5 players online" diff --git a/client/gui/menus/menu.gd b/client/gui/menus/menu.gd new file mode 100644 index 00000000..0f6e0624 --- /dev/null +++ b/client/gui/menus/menu.gd @@ -0,0 +1,151 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name Menu +extends Control + + +#enum Anim { NONE, FADE } +#@export var animation: Anim = Anim.NONE +@export var support_anim := true +@export var auto_anim := true + +var data + +signal submenu_close() + +const transition_scene = preload("res://gui/menus/transition/scene_transition.tscn") +var transition: SceneTransition +var parent_menu: Menu = null +var previous_path = null # : String +var open_since = 0 + +func _ready(): + open_since = Time.get_ticks_msec() + Global.focused_menu = self + focus_first(self) + connect_button_sounds(self) + disable_context_menus(self) + update_parent_menu(self.get_parent()) + if support_anim: anim_setup() + if auto_anim: _menu_open() + get_tree().get_root().go_back_requested.connect(exit_maybe) + +func anim_setup(): + transition = transition_scene.instantiate() + add_child(transition) +func _menu_open(): + if transition != null: await transition.fade_in() +func _menu_exit(): + if transition != null: await transition.fade_out() +func _menu_cover(_state: bool): + pass + +var popup: Menu = null +var covered := false +func submenu(path: String, data_ = null): + var prev_focus = Global.focused_node + if popup != null: return + _disable_recursive(self, true) + covered = true + await _menu_cover(true) + popup = load(path).instantiate() + popup.data = data_ + add_child(popup) + print("Submenu opened ", path) + await submenu_close + print("Submenu closed ", path) + await _menu_cover(false) + covered = false + Global.focused_menu = self + _disable_recursive(self, false) + if prev_focus != null: prev_focus.grab_focus() + +func _disable_recursive(node: Node, state: bool): + if node is BaseButton: + if state and node.disabled: node.add_to_group("was_disabled") + else: node.remove_from_group("was_disabled") + node.disabled = state or node.is_in_group("was_disabled") + for c in node.get_children(): _disable_recursive(c, state) + +func exit(): + await self._menu_exit() + if previous_path != null: + replace_menu(previous_path) + else: + get_parent().submenu_close.emit() + queue_free() + +func quit(): + await exit() + get_parent().quit() + +func replace_menu(path: String, data_ = null, prev_path = null): # prev_path: String? + print("Replace menu: ", path) + if popup != null: await popup.exit() + _disable_recursive(self, true) + await _menu_exit() + var new_popup: Menu = load(path).instantiate() + new_popup.data = data_ + if prev_path != null: new_popup.previous_path = prev_path + get_parent().add_child(new_popup) + if parent_menu != null: parent_menu.popup = new_popup + queue_free() + +var focus_auto_changed := false +func focus_first(node: Node) -> bool: + focus_auto_changed = true + if node.is_in_group("no_auto_focus"): + return false + if node is Button or node.is_in_group("autoselect"): + node.grab_focus() + print("Node %s (%s) was selected for focus" % [node.name, node]) + return true + for c in node.get_children(): + if focus_first(c): + return true + return false + +func connect_button_sounds(node: Node): + if node is Button or node is TextureButton: + if not node.is_in_group("no_click_sound"): + node.pressed.connect(Sound.play_click) + if (node is Button and not node.disabled) or (node is LineEdit and node.editable) or node is Slider: + if not node.is_in_group("no_click_sound"): + node.mouse_entered.connect(Sound.play_hover) + for c in node.get_children(): + connect_button_sounds(c) + +func disable_context_menus(node: Node): + if node is LineEdit: + node.context_menu_enabled = false + for c in node.get_children(): + disable_context_menus(c) + +func update_parent_menu(node: Node): + if node is Menu: parent_menu = node + elif node.get_parent() != null: update_parent_menu(node.get_parent()) + +func _input(_event): + if Input.is_action_just_pressed("menu"): + exit_maybe() + +func exit_maybe() -> void: + # Exit menu if all conditions are met + if popup != null: return + var time := Time.get_ticks_msec() + if time - open_since < 100: return + Sound.play_click() + exit() diff --git a/client/gui/menus/menu.gd.uid b/client/gui/menus/menu.gd.uid new file mode 100644 index 00000000..5711a6e0 --- /dev/null +++ b/client/gui/menus/menu.gd.uid @@ -0,0 +1 @@ +uid://d2h2q16vykpl4 diff --git a/client/gui/menus/popup.gd b/client/gui/menus/popup.gd new file mode 100644 index 00000000..d4849e92 --- /dev/null +++ b/client/gui/menus/popup.gd @@ -0,0 +1,32 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu +class_name MenuPopup + +@onready var message := $MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer/Message +@onready var button_container := $MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer/HBoxContainer + +class Data: + var buttons: Array[Button] + var text: String + +func _ready(): + var setup: Data = self.data + for i in setup.buttons: + button_container.add_child(i) + i.pressed.connect(exit) + message.text = setup.text + super() diff --git a/client/gui/menus/popup.gd.uid b/client/gui/menus/popup.gd.uid new file mode 100644 index 00000000..4800ca4d --- /dev/null +++ b/client/gui/menus/popup.gd.uid @@ -0,0 +1 @@ +uid://bevyiytj5tawr diff --git a/client/gui/menus/popup.tscn b/client/gui/menus/popup.tscn new file mode 100644 index 00000000..13137ccb --- /dev/null +++ b/client/gui/menus/popup.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=6 format=3 uid="uid://lwtym0pbc17g"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_m0d0r"] +[ext_resource type="Script" uid="uid://bevyiytj5tawr" path="res://gui/menus/popup.gd" id="2_1h10j"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_iouvy"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_j0ajn"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_e4iqk"] + +[node name="Popup" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_m0d0r") +script = ExtResource("2_1h10j") +support_anim = false + +[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 +script = ExtResource("3_j0ajn") + +[node name="CenterContainer" type="CenterContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="Panel" type="PanelContainer" parent="MarginContainer/CenterContainer"] +material = ExtResource("3_iouvy") +layout_mode = 2 +script = ExtResource("4_e4iqk") + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/CenterContainer/Panel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 16 + +[node name="Message" type="Label" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer"] +custom_minimum_size = Vector2(400, 0) +layout_mode = 2 +horizontal_alignment = 1 +autowrap_mode = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/CenterContainer/Panel/MarginContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 diff --git a/client/gui/menus/popup_large.gd b/client/gui/menus/popup_large.gd new file mode 100644 index 00000000..909ee4c0 --- /dev/null +++ b/client/gui/menus/popup_large.gd @@ -0,0 +1,25 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +@onready var label = $OuterMargin/Panel/InnerMargin/Vert/ScrollContainer/CreditsText + +func _ready(): + super() + label.text = data + +func _on_back_pressed(): + exit() diff --git a/client/gui/menus/popup_large.gd.uid b/client/gui/menus/popup_large.gd.uid new file mode 100644 index 00000000..aef2a852 --- /dev/null +++ b/client/gui/menus/popup_large.gd.uid @@ -0,0 +1 @@ +uid://c3eimx76ucpsp diff --git a/client/gui/menus/popup_large.tscn b/client/gui/menus/popup_large.tscn new file mode 100644 index 00000000..993dde9d --- /dev/null +++ b/client/gui/menus/popup_large.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=7 format=3 uid="uid://7mqbxa054bjv"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_kabr3"] +[ext_resource type="Script" uid="uid://c3eimx76ucpsp" path="res://gui/menus/popup_large.gd" id="2_m0b5d"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_36vhf"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_8ybj3"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_63jf0"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="6_smk7v"] + +[node name="CreditsMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_kabr3") +script = ExtResource("2_m0b5d") +support_anim = false + +[node name="OuterMargin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("3_36vhf") + +[node name="Panel" type="Panel" parent="OuterMargin"] +material = ExtResource("4_8ybj3") +layout_mode = 2 +script = ExtResource("5_63jf0") + +[node name="InnerMargin" type="MarginContainer" parent="OuterMargin/Panel"] +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 = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="Vert" type="VBoxContainer" parent="OuterMargin/Panel/InnerMargin"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="OuterMargin/Panel/InnerMargin/Vert"] +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("6_smk7v") + +[node name="CreditsText" type="RichTextLabel" parent="OuterMargin/Panel/InnerMargin/Vert/ScrollContainer"] +auto_translate_mode = 2 +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/table_h_separation = 25 +theme_override_font_sizes/bold_italics_font_size = 22 +theme_override_font_sizes/italics_font_size = 22 +theme_override_font_sizes/mono_font_size = 22 +theme_override_font_sizes/normal_font_size = 22 +theme_override_font_sizes/bold_font_size = 22 +bbcode_enabled = true +fit_content = true +scroll_active = false + +[node name="back" type="Button" parent="OuterMargin/Panel/InnerMargin/Vert"] +layout_mode = 2 +text = "c.menu.back" + +[connection signal="pressed" from="OuterMargin/Panel/InnerMargin/Vert/back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/rating/desaturate.gdshader b/client/gui/menus/rating/desaturate.gdshader new file mode 100644 index 00000000..e6861560 --- /dev/null +++ b/client/gui/menus/rating/desaturate.gdshader @@ -0,0 +1,7 @@ +shader_type canvas_item; + +uniform float t : hint_range(0.0, 1.0); + +void fragment() { + COLOR.rgb = mix(vec3(pow((COLOR.r+COLOR.g+COLOR.b)/3.,3.)),COLOR.rgb,t); +} diff --git a/client/gui/menus/rating/desaturate.gdshader.uid b/client/gui/menus/rating/desaturate.gdshader.uid new file mode 100644 index 00000000..621837a6 --- /dev/null +++ b/client/gui/menus/rating/desaturate.gdshader.uid @@ -0,0 +1 @@ +uid://cekkkqsvd7rvw diff --git a/client/gui/menus/rating/rating.gd b/client/gui/menus/rating/rating.gd new file mode 100644 index 00000000..023c1333 --- /dev/null +++ b/client/gui/menus/rating/rating.gd @@ -0,0 +1,65 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +const PARTICLE_AMOUNTS = [1, 6, 32, 128] + +@onready var game: Game = $"../Game" +@onready var title: Label = $MarginContainer/PanelContainer/VBoxContainer/Text/Title +@onready var subtitle: Label = $MarginContainer/PanelContainer/VBoxContainer/Text/Subtitle +@onready var stars = $MarginContainer/PanelContainer/VBoxContainer/Stars.get_children() +@onready var star_timer = $StarTimer +@onready var particles = $Control/Particles +@onready var close_button: Button = $MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Close + +func _ready(): + super() + show_rating(data[0], data[1]) + close_button.disabled = true # Disable for short time period to prevent accidental button press + +func _process(_delta): + particles.emission_rect_extents = get_viewport_rect().size * Vector2(0.5, 0.5) + +func show_rating(stars_: int, points: int): + match stars_: + 0: title.text = tr("c.score.poor") + 1: title.text = tr("c.score.acceptable") + 2: title.text = tr("c.score.good") + 3: title.text = tr("c.score.excellent") + + subtitle.text = tr("c.score.points_par").format([points]) + + for i in range(0, stars_): + var star: TextureRect = stars[i] + star_timer.start() + await star_timer.timeout + star.material.set_shader_parameter("t", 1) + star.get_node("Sound").play() + + particles.amount = PARTICLE_AMOUNTS[stars_] + + if stars_ > 1: + particles.emitting = true + +func _on_close_pressed(): + exit() + +func _on_button_timer_timeout() -> void: + close_button.disabled = false + +func _on_scoreboard_pressed() -> void: + exit() + game.mp.send_chat(game.my_player_id, "/scoreboard %s" % Global.last_map_name) diff --git a/client/gui/menus/rating/rating.gd.uid b/client/gui/menus/rating/rating.gd.uid new file mode 100644 index 00000000..fd729d8f --- /dev/null +++ b/client/gui/menus/rating/rating.gd.uid @@ -0,0 +1 @@ +uid://5tmklxkaa6e0 diff --git a/client/gui/menus/rating/rating.tscn b/client/gui/menus/rating/rating.tscn new file mode 100644 index 00000000..062dcca2 --- /dev/null +++ b/client/gui/menus/rating/rating.tscn @@ -0,0 +1,168 @@ +[gd_scene load_steps=12 format=3 uid="uid://buu3cdpigs8qq"] + +[ext_resource type="Texture2D" uid="uid://b10goh4dsa3b0" path="res://player/particles/satisfied/star.webp" id="1_7qv7r"] +[ext_resource type="Shader" uid="uid://cekkkqsvd7rvw" path="res://gui/menus/rating/desaturate.gdshader" id="1_pddsm"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_uwajf"] +[ext_resource type="Script" uid="uid://5tmklxkaa6e0" path="res://gui/menus/rating/rating.gd" id="2_cq0se"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_hdurb"] +[ext_resource type="AudioStream" uid="uid://camy77x26mmpv" path="res://gui/resources/sounds/success.ogg" id="5_tutpj"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_oi7xd"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ney6s"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_27tx1"] +shader = ExtResource("1_pddsm") +shader_parameter/t = 0.0 + +[sub_resource type="Curve" id="Curve_dqga7"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.0954774, 1), 0.262418, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="Gradient" id="Gradient_majwe"] +offsets = PackedFloat32Array(0, 0.0584795, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) + +[node name="Rating" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_uwajf") +script = ExtResource("2_cq0se") +support_anim = false + +[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 = 128 +theme_override_constants/margin_top = 64 +theme_override_constants/margin_right = 128 +theme_override_constants/margin_bottom = 64 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"] +material = ExtResource("4_hdurb") +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer"] +layout_mode = 2 +theme_override_constants/separation = 64 +alignment = 1 + +[node name="Text" type="VBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Title" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text"] +layout_mode = 2 +theme_override_font_sizes/font_size = 48 +text = "Title here" +horizontal_alignment = 1 + +[node name="Subtitle" type="Label" parent="MarginContainer/PanelContainer/VBoxContainer/Text"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "Subtitle here" +horizontal_alignment = 1 + +[node name="Stars" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Star1" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_oi7xd") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star1"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.5 + +[node name="Star2" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_ney6s") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star2"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.65 + +[node name="Star3" type="TextureRect" parent="MarginContainer/PanelContainer/VBoxContainer/Stars"] +material = SubResource("ShaderMaterial_27tx1") +custom_minimum_size = Vector2(128, 128) +layout_mode = 2 +texture = ExtResource("1_7qv7r") +expand_mode = 1 +stretch_mode = 5 + +[node name="Sound" type="AudioStreamPlayer" parent="MarginContainer/PanelContainer/VBoxContainer/Stars/Star3"] +stream = ExtResource("5_tutpj") +pitch_scale = 1.9 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 64 +alignment = 1 + +[node name="Scoreboard" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "c.menu.scoreboard.button" + +[node name="Close" type="Button" parent="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "c.menu.accept" + +[node name="StarTimer" type="Timer" parent="."] +wait_time = 0.5 +one_shot = true + +[node name="ButtonTimer" type="Timer" parent="."] +one_shot = true +autostart = true + +[node name="Control" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Particles" type="CPUParticles2D" parent="Control"] +emitting = false +amount = 32 +texture = ExtResource("1_7qv7r") +emission_shape = 3 +emission_rect_extents = Vector2(512, 256) +direction = Vector2(0, -1) +initial_velocity_min = 256.0 +initial_velocity_max = 256.0 +angular_velocity_min = -30.0 +angular_velocity_max = 30.0 +angle_min = -20.0 +angle_max = 20.0 +scale_amount_min = 0.1 +scale_amount_max = 0.2 +scale_amount_curve = SubResource("Curve_dqga7") +color_ramp = SubResource("Gradient_majwe") + +[connection signal="pressed" from="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Scoreboard" to="." method="_on_scoreboard_pressed"] +[connection signal="pressed" from="MarginContainer/PanelContainer/VBoxContainer/HBoxContainer/Close" to="." method="_on_close_pressed"] +[connection signal="timeout" from="ButtonTimer" to="." method="_on_button_timer_timeout"] diff --git a/client/gui/menus/settings/button_setting.gd b/client/gui/menus/settings/button_setting.gd new file mode 100644 index 00000000..fff8c184 --- /dev/null +++ b/client/gui/menus/settings/button_setting.gd @@ -0,0 +1,30 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name ButtonSetting +extends GameSetting + +var callback + +func _init(new_id: String, new_default, callback_): + callback = callback_ + super (new_id, new_default) + +func create_row(): + var row = super () + row.value_node = Button.new() + row.value_node.text = tr(nskey + ".button_label") + row.value_node.pressed.connect(callback) + return row diff --git a/client/gui/menus/settings/button_setting.gd.uid b/client/gui/menus/settings/button_setting.gd.uid new file mode 100644 index 00000000..cf0a8d95 --- /dev/null +++ b/client/gui/menus/settings/button_setting.gd.uid @@ -0,0 +1 @@ +uid://dku75bw31ux1k diff --git a/client/gui/menus/settings/dropdown_setting.gd b/client/gui/menus/settings/dropdown_setting.gd new file mode 100644 index 00000000..514df666 --- /dev/null +++ b/client/gui/menus/settings/dropdown_setting.gd @@ -0,0 +1,36 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name DropdownSetting +extends GameSetting + +var options: Array + +func _init(new_id: String, new_default, new_options: Array): + super(new_id, new_default) + options = new_options + +func create_row(): + var row = super() + row.value_node = OptionButton.new() + row.value_node.clip_text = true + for i in options: row.value_node.add_item(tr(nskey + "." + i)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.select(options.find(value)) + ) + row.value_node.item_selected.connect(func(item): Global.set_setting(key, options[item])) + return row diff --git a/client/gui/menus/settings/dropdown_setting.gd.uid b/client/gui/menus/settings/dropdown_setting.gd.uid new file mode 100644 index 00000000..409bf3ab --- /dev/null +++ b/client/gui/menus/settings/dropdown_setting.gd.uid @@ -0,0 +1 @@ +uid://cjqswo4mwbvon diff --git a/client/gui/menus/settings/game_setting.gd b/client/gui/menus/settings/game_setting.gd new file mode 100644 index 00000000..1c04ad3b --- /dev/null +++ b/client/gui/menus/settings/game_setting.gd @@ -0,0 +1,46 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name GameSetting +extends Object + +var default +var key: String +var nskey: String + +func _init(new_id: String, new_default = null): + default = new_default + key = new_id + +func set_parent(parent: GameSetting): + if parent != null: key = parent.key + "." + key + nskey = "c.settings." + key + +func create_row(): + var row = preload("res://gui/menus/settings/settings_row.tscn").instantiate() + row.description = tr(nskey) + row.reset.connect(func(): Global.set_setting(key, default)) + return row + +func check(): + if default != null: + if not key in Global.settings: + Global.set_setting_unchecked(key, default) + if typeof(default) != typeof(Global.settings[key]): + Global.set_setting_unchecked(key, default) + +func changed_keys(): + if Global.get_setting(key) != default: return [key] + else: return [] diff --git a/client/gui/menus/settings/game_setting.gd.uid b/client/gui/menus/settings/game_setting.gd.uid new file mode 100644 index 00000000..99d79bee --- /dev/null +++ b/client/gui/menus/settings/game_setting.gd.uid @@ -0,0 +1 @@ +uid://cyy8l32i44l63 diff --git a/client/gui/menus/settings/input/input_manager.gd b/client/gui/menus/settings/input/input_manager.gd new file mode 100644 index 00000000..e3158a03 --- /dev/null +++ b/client/gui/menus/settings/input/input_manager.gd @@ -0,0 +1,101 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Node + +enum EventType { + KEYBOARD, + JOYPAD, + TOUCH, + OTHER +} + +var default_input_map = {} +var input_map: Dictionary + +func _init(): + default_input_map = get_input_map() + input_map = default_input_map.duplicate(true) + +func get_input_map() -> Dictionary: + var actions = InputMap.get_actions().filter(func isBuiltIn(k: String): return !k.begins_with("ui_")) + var kb = {} + for a in actions: + var input_events: Array[InputEvent] = InputMap.action_get_events(a).duplicate(true) + kb[a] = input_events + return kb + +func get_events(action_name: String) -> Array: + if not input_map.has(action_name): + push_error("Tried to get action %s in input map which does not exist" % action_name) + return [] + return input_map[action_name] + +func settings() -> Array: + var entries := [] + for k in input_map.keys(): entries.append(InputSetting.new(k)) + return entries + +func change_input_map_action(action_name: String, events: Array, save: bool = true): + if !InputMap.has_action(action_name): + push_error("Action %s does not exist" % action_name, false) + return + # Erase previous keybindings + InputMap.action_erase_events(action_name) + # Add new keybindings + for e in events: + InputMap.action_add_event(action_name, e) + + if save: + # Update input map dictionary + input_map = get_input_map() + # Save settings + Global.set_setting("input_map", input_map.duplicate(true)) + +func apply_input_map(new_input_map: Dictionary): + # Load into input map dictionary + for k in new_input_map.keys(): + input_map[k] = [] + for a in new_input_map[k]: + input_map[k].append(a) + + # Apply keybindings + for k in input_map.keys(): + change_input_map_action(k, input_map[k], false) + +func reset_input_map(): + Global.set_setting("input_map", default_input_map.duplicate()) + apply_input_map(Global.get_setting("input_map")) + +func get_event_type(input_event: InputEvent) -> EventType: + if input_event is InputEventKey or input_event is InputEventMouseButton: + return EventType.KEYBOARD + elif input_event is InputEventJoypadButton or input_event is InputEventJoypadMotion: + return EventType.JOYPAD + elif input_event is InputEventScreenTouch or input_event is InputEventScreenDrag: + return EventType.TOUCH + return EventType.OTHER + +func display_input_event(input_event: InputEvent) -> String: + if input_event is InputEventKey: + return tr("c.settings.input.keyboard").format([OS.get_keycode_string(input_event.physical_keycode)]) + elif input_event is InputEventMouseButton: + return tr("c.settings.input.mouse_button").format([input_event.button_index]) + elif input_event is InputEventJoypadButton: + return tr("c.settings.input.joypad").format([input_event.button_index]) + elif input_event is InputEventJoypadMotion: + return tr("c.settings.input.joypad_axis").format([input_event.axis]) + else: + return tr("c.settings.input.other_event") diff --git a/client/gui/menus/settings/input/input_manager.gd.uid b/client/gui/menus/settings/input/input_manager.gd.uid new file mode 100644 index 00000000..678c2192 --- /dev/null +++ b/client/gui/menus/settings/input/input_manager.gd.uid @@ -0,0 +1 @@ +uid://bfu78iwybbu2s diff --git a/client/gui/menus/settings/input/input_setting.gd b/client/gui/menus/settings/input/input_setting.gd new file mode 100644 index 00000000..fa903771 --- /dev/null +++ b/client/gui/menus/settings/input/input_setting.gd @@ -0,0 +1,39 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name InputSetting +extends GameSetting + +const INPUT_VALUE_NODE_SCENE = preload("res://gui/menus/settings/input/input_value_node.tscn") + +func _init(new_id: String): + super(new_id) + default = InputManager.default_input_map[new_id] + +func create_row(): + var row = super() + row.value_node = INPUT_VALUE_NODE_SCENE.instantiate() + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.value = value + ) + row.value_node.changed.connect(func(): Global.set_setting(key, row.value_node.value)) + return row + +func changed_keys(): + return [key] + # if Global.array_eq(Global.get_setting(key), default): return [key] + # else: return [] diff --git a/client/gui/menus/settings/input/input_setting.gd.uid b/client/gui/menus/settings/input/input_setting.gd.uid new file mode 100644 index 00000000..7866fc2f --- /dev/null +++ b/client/gui/menus/settings/input/input_setting.gd.uid @@ -0,0 +1 @@ +uid://d2xwn2u4ycpe8 diff --git a/client/gui/menus/settings/input/input_value_node.gd b/client/gui/menus/settings/input/input_value_node.gd new file mode 100644 index 00000000..7c718e25 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.gd @@ -0,0 +1,74 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends VBoxContainer +class_name InputValueNode + +var value: Array[InputEvent] = [] +var listening := false + +signal changed() + +@onready var actions_container: VBoxContainer = $ActionsContainer +@onready var add_button: Button = $Add +@onready var add_text = add_button.text + +func _ready(): + update() + +func update(fix_focus: bool = false): + for c in actions_container.get_children(): + c.queue_free() + + for e: InputEvent in value: + var description: String = InputManager.display_input_event(e) + var button := Button.new() + + button.text = description + button.pressed.connect(erase_event.bind(e)) + actions_container.add_child(button) + + if fix_focus: + add_button.grab_focus() + +func erase_event(e: InputEvent): + value.erase(e) + update(true) + changed.emit() + +func _input(e: InputEvent): + if listening: + if e is InputEventKey or e is InputEventMouseButton or e is InputEventJoypadButton or e is InputEventJoypadMotion: + # Check if key was already added + for e2 in value: + if events_equal(e, e2): return + + value.append(e) + _on_add_pressed() + update() + changed.emit() + +func events_equal(e1: InputEvent, e2: InputEvent) -> bool: + if e1 is InputEventKey and e2 is InputEventKey: + return e1.physical_keycode == e2.physical_keycode + if (e1 is InputEventMouseButton and e2 is InputEventMouseButton) or (e1 is InputEventJoypadButton and e2 is InputEventJoypadButton): + return e1.button_index == e2.button_index + if e1 is InputEventJoypadMotion and e2 is InputEventJoypadMotion: + return e1.axis == e2.axis + return false + +func _on_add_pressed() -> void: + listening = not listening + add_button.text = tr("c.settings.input.press_any_key") if listening else add_text diff --git a/client/gui/menus/settings/input/input_value_node.gd.uid b/client/gui/menus/settings/input/input_value_node.gd.uid new file mode 100644 index 00000000..3669b991 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.gd.uid @@ -0,0 +1 @@ +uid://ckb78voiq05e3 diff --git a/client/gui/menus/settings/input/input_value_node.tscn b/client/gui/menus/settings/input/input_value_node.tscn new file mode 100644 index 00000000..1b2e89c4 --- /dev/null +++ b/client/gui/menus/settings/input/input_value_node.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=3 format=3 uid="uid://c6r0nv5daq7wc"] + +[ext_resource type="Script" uid="uid://ckb78voiq05e3" path="res://gui/menus/settings/input/input_value_node.gd" id="1_snxax"] +[ext_resource type="Texture2D" uid="uid://cnfjbowd2i02r" path="res://gui/resources/icons/plus.svg" id="2_3vlvc"] + +[node name="InputValueNode" type="VBoxContainer"] +offset_right = 128.0 +offset_bottom = 31.0 +theme_override_constants/separation = 0 +script = ExtResource("1_snxax") + +[node name="ActionsContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="Add" type="Button" parent="."] +custom_minimum_size = Vector2(128, 0) +layout_mode = 2 +size_flags_vertical = 3 +text = "c.settings.input.add" +icon = ExtResource("2_3vlvc") +expand_icon = true + +[connection signal="pressed" from="Add" to="." method="_on_add_pressed"] diff --git a/client/gui/menus/settings/number_setting.gd b/client/gui/menus/settings/number_setting.gd new file mode 100644 index 00000000..5fa5a115 --- /dev/null +++ b/client/gui/menus/settings/number_setting.gd @@ -0,0 +1,41 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name NumberSetting +extends GameSetting + +var placeholder: String +var min_value: int +var max_value: int + +func _init(new_id: String, new_default: int, new_min_value: int, new_max_value: int): + super(new_id, new_default) + min_value = new_min_value + max_value = new_max_value + +func create_row(): + var row = super() + var input := SpinBox.new() + input.min_value = min_value + input.max_value = max_value + + input.value_changed.connect(func(value): Global.set_setting(key, value as int)) + Settings.hook_changed_init(key, true, + func(v): + if is_instance_valid(input): + input.value = v + ) + row.value_node = input + return row diff --git a/client/gui/menus/settings/number_setting.gd.uid b/client/gui/menus/settings/number_setting.gd.uid new file mode 100644 index 00000000..4301c642 --- /dev/null +++ b/client/gui/menus/settings/number_setting.gd.uid @@ -0,0 +1 @@ +uid://babmw2ohuhmuk diff --git a/client/gui/menus/settings/path_setting.gd b/client/gui/menus/settings/path_setting.gd new file mode 100644 index 00000000..37492ed7 --- /dev/null +++ b/client/gui/menus/settings/path_setting.gd @@ -0,0 +1,64 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name PathSetting +extends TextSetting + +var select_file_icon: Texture2D = preload("res://gui/resources/icons/select_file.svg") +var select_dir_icon: Texture2D = preload("res://gui/resources/icons/select_directory.svg") + +var access: FileDialog.Access +var file_mode: FileDialog.FileMode + +func _init(new_id: String, + new_default: String, + new_file_mode: FileDialog.FileMode, + new_placeholder: String = "", + new_access: FileDialog.Access = FileDialog.Access.ACCESS_FILESYSTEM +): + super(new_id, new_default) + placeholder = new_placeholder + access = new_access + file_mode = new_file_mode + +func create_row(): + var row = super () + var input: LineEdit = row.value_node; + input.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.value_node = HBoxContainer.new() + row.value_node.add_child(input) + var button := Button.new() + button.icon = select_file_icon if file_mode == FileDialog.FileMode.FILE_MODE_OPEN_FILE else select_dir_icon + row.value_node.add_child(button) + button.pressed.connect(func(): + var d := FileDialog.new() + Global.focused_menu.add_child(d) + d.move_to_center() + d.use_native_dialog = true + d.borderless = true + d.dir_selected.connect(_selected.bind(input)) + d.file_selected.connect(_selected.bind(input)) + d.file_mode = file_mode + d.access = access + d.show() + # this feels wrong + d.canceled.connect(d.queue_free) + d.confirmed.connect(d.queue_free) + ) + return row + +func _selected(path: String, input: LineEdit): + input.text = path + input.text_changed.emit(path) diff --git a/client/gui/menus/settings/path_setting.gd.uid b/client/gui/menus/settings/path_setting.gd.uid new file mode 100644 index 00000000..a524b17c --- /dev/null +++ b/client/gui/menus/settings/path_setting.gd.uid @@ -0,0 +1 @@ +uid://cj5jf7t771j5b diff --git a/client/gui/menus/settings/preset_row.gd b/client/gui/menus/settings/preset_row.gd new file mode 100644 index 00000000..f3c46a26 --- /dev/null +++ b/client/gui/menus/settings/preset_row.gd @@ -0,0 +1,46 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name PresetRow +extends GameSetting + +var options: Dictionary +var arr: Array[Button] + +func _init(id: String, options_: Dictionary): + super(id) + options = options_ + +var prefix = "" +func set_parent(parent): + super(parent) + if parent != null: prefix = parent.key + +func apply(preset_name: String): + var preset = options[preset_name] + for i in preset.keys(): + Global.set_setting(prefix + "." + i, preset[i]) + +func create_row(): + var row = super() + row.value_node = HBoxContainer.new() + for i in options.keys(): + var button := Button.new() + button.pressed.connect(apply.bind(i)) + button.text = tr(nskey + "." + i) + row.value_node.add_child(button) + return row + +func changed_keys(): return [] diff --git a/client/gui/menus/settings/preset_row.gd.uid b/client/gui/menus/settings/preset_row.gd.uid new file mode 100644 index 00000000..51605058 --- /dev/null +++ b/client/gui/menus/settings/preset_row.gd.uid @@ -0,0 +1 @@ +uid://dawqyyllgis0b diff --git a/client/gui/menus/settings/range_setting.gd b/client/gui/menus/settings/range_setting.gd new file mode 100644 index 00000000..b8d392a4 --- /dev/null +++ b/client/gui/menus/settings/range_setting.gd @@ -0,0 +1,44 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name RangeSetting +extends GameSetting + +var min_value: float +var max_value: float +var tick_count +var smooth: bool + +func _init(new_id: String, new_default: float, new_min_value: float, new_max_value: float, new_smooth: bool = true, new_tick_count = null): + super(new_id, new_default) + min_value = new_min_value + max_value = new_max_value + tick_count = new_tick_count + smooth = new_smooth + +func create_row(): + var row = super() + row.value_node = HSlider.new() + row.value_node.min_value = min_value + row.value_node.max_value = max_value + row.value_node.tick_count = abs(max_value - min_value) if tick_count == null else tick_count + row.value_node.step = 0 if smooth else (1 if tick_count == null else abs(max_value - min_value) / (tick_count - 1)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.value = value + ) + row.value_node.value_changed.connect(func(value): Global.set_setting(key, value)) + return row diff --git a/client/gui/menus/settings/range_setting.gd.uid b/client/gui/menus/settings/range_setting.gd.uid new file mode 100644 index 00000000..a4ca49a2 --- /dev/null +++ b/client/gui/menus/settings/range_setting.gd.uid @@ -0,0 +1 @@ +uid://civr7cckqfndj diff --git a/client/gui/menus/settings/settings.gd b/client/gui/menus/settings/settings.gd new file mode 100644 index 00000000..32da54cc --- /dev/null +++ b/client/gui/menus/settings/settings.gd @@ -0,0 +1,40 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +@onready var container = $OuterGap/Panel/InnerGap/VBoxContainer +@onready var outer_gap = $OuterGap + +func _ready(): + super() + var row = Global.settings_tree.create_row() + container.add_child(row) + container.move_child(row, 1) + +func _process(_dt): + var os := OS.get_name() + if os == "iOS" or os == "Android": return + # TODO probably bad performance, only update on change + var margin = max((self.size.x - 1200) / 2, 20) + outer_gap.add_theme_constant_override("margin_left", margin) + outer_gap.add_theme_constant_override("margin_right", margin) + +func _on_back_pressed(): + exit() + +func exit(): + Global.save_settings() + super() diff --git a/client/gui/menus/settings/settings.gd.uid b/client/gui/menus/settings/settings.gd.uid new file mode 100644 index 00000000..79b89b85 --- /dev/null +++ b/client/gui/menus/settings/settings.gd.uid @@ -0,0 +1 @@ +uid://bbqmsf8u5rhtn diff --git a/client/gui/menus/settings/settings.tscn b/client/gui/menus/settings/settings.tscn new file mode 100644 index 00000000..71549464 --- /dev/null +++ b/client/gui/menus/settings/settings.tscn @@ -0,0 +1,61 @@ +[gd_scene load_steps=6 format=3 uid="uid://8ic77jmadadj"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_1vjiw"] +[ext_resource type="Script" uid="uid://bbqmsf8u5rhtn" path="res://gui/menus/settings/settings.gd" id="2_5xn7x"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="3_h533i"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="4_b0x33"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_dvivs"] + +[node name="SettingsMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_1vjiw") +script = ExtResource("2_5xn7x") +support_anim = false + +[node name="OuterGap" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 80 +script = ExtResource("3_h533i") + +[node name="Panel" type="Panel" parent="OuterGap"] +material = ExtResource("4_b0x33") +layout_mode = 2 +script = ExtResource("5_dvivs") + +[node name="InnerGap" type="MarginContainer" parent="OuterGap/Panel"] +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 = 40 +theme_override_constants/margin_top = 40 +theme_override_constants/margin_right = 40 +theme_override_constants/margin_bottom = 40 + +[node name="VBoxContainer" type="VBoxContainer" parent="OuterGap/Panel/InnerGap"] +layout_mode = 2 + +[node name="Title" type="Label" parent="OuterGap/Panel/InnerGap/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_font_sizes/font_size = 36 +text = "c.menu.settings" + +[node name="Back" type="Button" parent="OuterGap/Panel/InnerGap/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 8 +text = "c.settings.apply" + +[connection signal="pressed" from="OuterGap/Panel/InnerGap/VBoxContainer/Back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/settings/settings_category.gd b/client/gui/menus/settings/settings_category.gd new file mode 100644 index 00000000..bf85abd9 --- /dev/null +++ b/client/gui/menus/settings/settings_category.gd @@ -0,0 +1,49 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name SettingsCategory +extends GameSetting + +var settings: Array # Dictionary[String, GameSetting] + +func _init(new_id: String, new_settings: Array): + super(new_id) + settings = new_settings + +func set_parent(parent: GameSetting): + super(parent) + for c in settings: + c.set_parent(self) + +func create_row(): + var row = ScrollContainerCustom.new() + var options = VBoxContainer.new() + row.name = tr(nskey) + row.size_flags_horizontal = Control.SIZE_EXPAND_FILL + options.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.add_child(options) + + for r in settings: options.add_child(r.create_row()) + return row + +func check(): + for c in settings: + c.check() + +func changed_keys(): + var changed = [] + for c in settings: + changed.append_array(c.changed_keys()) + return changed diff --git a/client/gui/menus/settings/settings_category.gd.uid b/client/gui/menus/settings/settings_category.gd.uid new file mode 100644 index 00000000..421ce213 --- /dev/null +++ b/client/gui/menus/settings/settings_category.gd.uid @@ -0,0 +1 @@ +uid://b8s3cqb01w3wh diff --git a/client/gui/menus/settings/settings_root.gd b/client/gui/menus/settings/settings_root.gd new file mode 100644 index 00000000..a9a024d8 --- /dev/null +++ b/client/gui/menus/settings/settings_root.gd @@ -0,0 +1,40 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends GameSetting +class_name SettingsRoot + +var children: Array +func _init(new_children: Array): + super("root") + children = new_children + for c in children: + c.set_parent(null) + +func create_row(): + var row = TabContainer.new() + row.size_flags_vertical = Control.SIZE_EXPAND_FILL + for r in children: row.add_child(r.create_row()) + return row + +func check(): + for c in children: + c.check() + +func changed_keys(): + var changed = [] + for c in children: + changed.append_array(c.changed_keys()) + return changed diff --git a/client/gui/menus/settings/settings_root.gd.uid b/client/gui/menus/settings/settings_root.gd.uid new file mode 100644 index 00000000..95a46d5e --- /dev/null +++ b/client/gui/menus/settings/settings_root.gd.uid @@ -0,0 +1 @@ +uid://jonib2ixqsp7 diff --git a/client/gui/menus/settings/settings_row.gd b/client/gui/menus/settings/settings_row.gd new file mode 100644 index 00000000..d88d49c1 --- /dev/null +++ b/client/gui/menus/settings/settings_row.gd @@ -0,0 +1,37 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name SettingsRow +extends PanelContainer + +signal reset() + +@onready var value_parent = $HBoxContainer/BoxContainer +@onready var label = $HBoxContainer/Label +@onready var reset_button = $HBoxContainer/Reset + +var value_node: Node +var description = "No value was given to the row" + +func _ready(): + if value_node != null: + var c: Control = value_node + c.size_flags_vertical = Control.SIZE_EXPAND_FILL + c.size_flags_horizontal = Control.SIZE_EXPAND_FILL + label.text = description + value_parent.add_child(c) + +func _on_reset_pressed(): + reset.emit() diff --git a/client/gui/menus/settings/settings_row.gd.uid b/client/gui/menus/settings/settings_row.gd.uid new file mode 100644 index 00000000..a6dea492 --- /dev/null +++ b/client/gui/menus/settings/settings_row.gd.uid @@ -0,0 +1 @@ +uid://b3m1f76o5qo68 diff --git a/client/gui/menus/settings/settings_row.tscn b/client/gui/menus/settings/settings_row.tscn new file mode 100644 index 00000000..09378ab6 --- /dev/null +++ b/client/gui/menus/settings/settings_row.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=7 format=3 uid="uid://o5e5vpem8w0k"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_iij3k"] +[ext_resource type="Script" uid="uid://b3m1f76o5qo68" path="res://gui/menus/settings/settings_row.gd" id="2_l8i7p"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="3_7k5da"] +[ext_resource type="Texture2D" uid="uid://cucnmy0j5n8l8" path="res://gui/resources/icons/reset.svg" id="4_bj3dr"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_pk3rs"] +content_margin_left = 16.0 + +[sub_resource type="FontVariation" id="FontVariation_o6i7s"] +base_font = ExtResource("3_7k5da") + +[node name="SettingsRow" type="PanelContainer"] +offset_right = 105.0 +offset_bottom = 23.0 +size_flags_horizontal = 3 +theme = ExtResource("1_iij3k") +script = ExtResource("2_l8i7p") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Label" type="Label" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_styles/normal = SubResource("StyleBoxEmpty_pk3rs") + +[node name="BoxContainer" type="BoxContainer" parent="HBoxContainer"] +custom_minimum_size = Vector2(300, 50) +layout_mode = 2 +alignment = 2 + +[node name="Reset" type="Button" parent="HBoxContainer"] +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_o6i7s") +theme_override_font_sizes/font_size = 24 +icon = ExtResource("4_bj3dr") + +[connection signal="pressed" from="HBoxContainer/Reset" to="." method="_on_reset_pressed"] diff --git a/client/gui/menus/settings/text_setting.gd b/client/gui/menus/settings/text_setting.gd new file mode 100644 index 00000000..8e2b6bec --- /dev/null +++ b/client/gui/menus/settings/text_setting.gd @@ -0,0 +1,38 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name TextSetting +extends GameSetting + +var placeholder: String + +func _init(new_id: String, new_default: String, new_placeholder: String = ""): + super(new_id, new_default) + placeholder = new_placeholder + +func create_row(): + var row = super() + var input := LineEdit.new() + input.placeholder_text = placeholder + input.text_changed.connect(func(text): Global.set_setting(key, text)) + Settings.hook_changed_init(key, true, + func(text): + if is_instance_valid(input): + var pos = input.caret_column + input.text = text + input.caret_column = pos + ) + row.value_node = input + return row diff --git a/client/gui/menus/settings/text_setting.gd.uid b/client/gui/menus/settings/text_setting.gd.uid new file mode 100644 index 00000000..58ac5abe --- /dev/null +++ b/client/gui/menus/settings/text_setting.gd.uid @@ -0,0 +1 @@ +uid://3rgucgbbt135 diff --git a/client/gui/menus/settings/toggle_setting.gd b/client/gui/menus/settings/toggle_setting.gd new file mode 100644 index 00000000..abcb7f4a --- /dev/null +++ b/client/gui/menus/settings/toggle_setting.gd @@ -0,0 +1,31 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name ToggleSetting +extends GameSetting + +func _init(new_id: String, new_default: bool): + super(new_id, new_default) + +func create_row(): + var row = super() + row.value_node = CheckButton.new() + row.value_node.pressed.connect(func(): Global.set_setting(key, row.value_node.button_pressed)) + Settings.hook_changed_init(key, true, + func(value): + if is_instance_valid(row): + row.value_node.button_pressed = value + ) + return row diff --git a/client/gui/menus/settings/toggle_setting.gd.uid b/client/gui/menus/settings/toggle_setting.gd.uid new file mode 100644 index 00000000..1d2ca55b --- /dev/null +++ b/client/gui/menus/settings/toggle_setting.gd.uid @@ -0,0 +1 @@ +uid://cojnv8bmv6aw5 diff --git a/client/gui/menus/setup/hairstyle_preview.gd b/client/gui/menus/setup/hairstyle_preview.gd new file mode 100644 index 00000000..78576491 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.gd @@ -0,0 +1,27 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name HairstylePreview +extends VBoxContainer + +signal selected(character_style: Dictionary) + +func setup(hairstyle: int, group: ButtonGroup): + var character_style = Global.default_profile.character_style + character_style.hairstyle = hairstyle + $HairViewport/Node3D/Character.set_style(character_style, "chef") + $Select.button_group = group + $Select.text = tr("c.setup.uniform.value").format([hairstyle + 1]) + $Select.pressed.connect(func(): selected.emit(character_style)) diff --git a/client/gui/menus/setup/hairstyle_preview.gd.uid b/client/gui/menus/setup/hairstyle_preview.gd.uid new file mode 100644 index 00000000..8f5b3cd4 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.gd.uid @@ -0,0 +1 @@ +uid://dvveoqur81l0s diff --git a/client/gui/menus/setup/hairstyle_preview.tscn b/client/gui/menus/setup/hairstyle_preview.tscn new file mode 100644 index 00000000..ee4a65e9 --- /dev/null +++ b/client/gui/menus/setup/hairstyle_preview.tscn @@ -0,0 +1,55 @@ +[gd_scene load_steps=7 format=3 uid="uid://dfon56nwd2tgn"] + +[ext_resource type="Script" uid="uid://dvveoqur81l0s" path="res://gui/menus/setup/hairstyle_preview.gd" id="1_0qdmv"] +[ext_resource type="Shader" uid="uid://qjrh2imc53u1" path="res://gui/resources/shaders/grayscale.gdshader" id="1_sf0gc"] +[ext_resource type="PackedScene" uid="uid://b3hhir2fvnunu" path="res://player/character/character.tscn" id="2_jtitc"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_entrs"] +shader = ExtResource("1_sf0gc") + +[sub_resource type="ViewportTexture" id="ViewportTexture_giuq2"] +viewport_path = NodePath("HairViewport") + +[sub_resource type="ButtonGroup" id="ButtonGroup_c5p7t"] + +[node name="HairstylePreview" type="VBoxContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +script = ExtResource("1_0qdmv") + +[node name="Preview" type="TextureRect" parent="."] +material = SubResource("ShaderMaterial_entrs") +layout_mode = 2 +texture = SubResource("ViewportTexture_giuq2") + +[node name="Select" type="CheckBox" parent="."] +layout_mode = 2 +button_group = SubResource("ButtonGroup_c5p7t") +text = "Hairstyle 1" + +[node name="HairViewport" type="SubViewport" parent="."] +own_world_3d = true +transparent_bg = true +msaa_3d = 1 +size = Vector2i(128, 128) + +[node name="Node3D" type="Node3D" parent="HairViewport"] + +[node name="Camera3D" type="Camera3D" parent="HairViewport/Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 1.5) +fov = 25.5 + +[node name="Character" parent="HairViewport/Node3D" instance=ExtResource("2_jtitc")] + +[node name="SpotLight3D" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(0.866025, 0, -0.5, 0, 1, 0, 0.5, 0, 0.866025, -2, 0, 2) + +[node name="SpotLight3D2" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(0.876399, 0, 0.481585, 0, 1, 0, -0.481585, 0, 0.876399, 2, 0.499189, 2) +light_color = Color(0.857819, 0.80038, 0.775519, 1) +light_energy = 4.11 + +[node name="SpotLight3D3" type="SpotLight3D" parent="HairViewport/Node3D"] +transform = Transform3D(-0.965926, 0, -0.258819, -0.129409, 0.866025, 0.482963, 0.224144, 0.5, -0.836516, -1, 2, -2) +light_color = Color(0.540595, 0.865144, 1, 1) +light_energy = 8.2 diff --git a/client/gui/menus/setup/setup.gd b/client/gui/menus/setup/setup.gd new file mode 100644 index 00000000..6170786c --- /dev/null +++ b/client/gui/menus/setup/setup.gd @@ -0,0 +1,110 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Menu + +const SCROLL_SPEED := 500. + +var character_style = null # : Dictionary? + +@onready var anim: AnimationPlayer = $AnimationPlayer +@onready var username: LineEdit = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry/LineEdit +@onready var sign_sound: AudioStreamPlayer = $Sign +@onready var sign_button: Button = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign/Signature +@onready var scroll: ScrollContainer = $ScrollContainer +@onready var select_uniform: HBoxContainer = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectUniform +@onready var skip_tutorial: CheckBox = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience/CheckBox + +func _ready(): + anim.play("paper_slide") + var button_group := ButtonGroup.new() + for i in range(3): + var preview: HairstylePreview = preload("res://gui/menus/setup/hairstyle_preview.tscn").instantiate() + select_uniform.add_child(preview) + preview.setup(i, button_group) + preview.selected.connect(_character_selected) + if i < 2: + var spacer = Control.new() + spacer.size_flags_vertical = Control.SIZE_EXPAND + spacer.custom_minimum_size.x = 50 + select_uniform.add_child(spacer) + + # Enable msaa 2D for this scene + Global.get_viewport().msaa_2d = Viewport.MSAA_4X + + if Global.profile.username != "": username.text = Global.profile.username + + if TranslationServer.get_locale().begins_with("zh"): + $ScrollContainer/Control/TextureRect.rotation = 0 + increase_font_size(self) + + super() + $Back.visible = not is_instance_of(parent_menu, Entry) + +func increase_font_size(node: Node): + if node is RichTextLabel: + for oname in ["bold_italics_font_size", "italics_font_size", "normal_font_size", "mono_font_size", "bold_font_size"]: + node.add_theme_font_size_override(oname, node.get_theme_default_font_size() * 1.2) + for c in node.get_children(): increase_font_size(c) + +func _on_back_pressed() -> void: + exit() + +func _character_selected(style: Dictionary): + character_style = style + +func _process(delta): + var s = Input.get_axis("rotate_up", "rotate_down") + scroll.set_deferred("scroll_vertical", scroll.scroll_vertical + s * delta * SCROLL_SPEED) + + +func check(): + if username.text == "": return tr("c.error.empty_username") + if character_style == null: return tr("c.error.select_hairstyle") + return null + +func _on_sign_pressed(): + if check() != null: + var popup_data := MenuPopup.Data.new() + popup_data.text = check() + var accept_button := Button.new() + accept_button.text = tr("c.menu.accept") + popup_data.buttons = [accept_button] + await submenu("res://gui/menus/popup.tscn", popup_data) + return + + sign_button.disabled = true + + sign_sound.play() + await sign_sound.finished + anim.play_backwards("paper_slide") + await anim.animation_finished + + Global.set_profile("username", username.text) + Global.set_profile("character_style", character_style) + if skip_tutorial.button_pressed: + for k in Global.profile["hints"].keys(): + Global.set_hint(k, true) + Global.save_profile() + + Global.set_setting("gameplay.hints_started", skip_tutorial.button_pressed) + Global.set_setting("gameplay.tutorial_disabled", skip_tutorial.button_pressed) + Global.set_setting("gameplay.setup_completed", true) + Global.save_settings() + + Global.get_viewport().msaa_2d = Viewport.MSAA_DISABLED + + if not is_instance_of(parent_menu, Entry): exit() + else: replace_menu("res://gui/menu/main/main.tscn") diff --git a/client/gui/menus/setup/setup.gd.uid b/client/gui/menus/setup/setup.gd.uid new file mode 100644 index 00000000..c9c2be3c --- /dev/null +++ b/client/gui/menus/setup/setup.gd.uid @@ -0,0 +1 @@ +uid://dxn6ow6hiwhbf diff --git a/client/gui/menus/setup/setup.tscn b/client/gui/menus/setup/setup.tscn new file mode 100644 index 00000000..d0cce350 --- /dev/null +++ b/client/gui/menus/setup/setup.tscn @@ -0,0 +1,398 @@ +[gd_scene load_steps=15 format=3 uid="uid://ddl3efikvqp66"] + +[ext_resource type="Script" uid="uid://dxn6ow6hiwhbf" path="res://gui/menus/setup/setup.gd" id="1_mo46n"] +[ext_resource type="Theme" uid="uid://ci2qajdoa1an1" path="res://gui/resources/theme/paper.tres" id="1_yq0aa"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="2_4caf2"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_2vg4d"] +[ext_resource type="AudioStream" uid="uid://do7ii5hx71p0m" path="res://gui/resources/sounds/page.ogg" id="5_xac6d"] +[ext_resource type="AudioStream" uid="uid://5b3noxjmasmu" path="res://gui/resources/sounds/sign.ogg" id="6_wf0gh"] + +[sub_resource type="Animation" id="Animation_m4a1a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("ScrollContainer:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} + +[sub_resource type="Animation" id="Animation_s1to2"] +resource_name = "paper_slide" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("ScrollContainer:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, -1800), Vector2(0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_wjgak"] +_data = { +&"RESET": SubResource("Animation_m4a1a"), +&"paper_slide": SubResource("Animation_s1to2") +} + +[sub_resource type="Gradient" id="Gradient_nsc3h"] +colors = PackedColorArray(0.941084, 0.949219, 0.918643, 1, 1, 1, 1, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_amioi"] + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_bvvl7"] +color_ramp = SubResource("Gradient_nsc3h") +noise = SubResource("FastNoiseLite_amioi") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e7xn5"] +bg_color = Color(0.196078, 0.196078, 0.235294, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="FontVariation" id="FontVariation_2cc7p"] +base_font = ExtResource("3_2vg4d") + +[node name="SetupMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_mo46n") +support_anim = null +auto_anim = null + +[node name="ColorRect" type="ColorRect" parent="."] +layout_mode = 2 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.196078, 0.196078, 0.235294, 1) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_wjgak") +} +speed_scale = 2.0 + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +clip_contents = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +follow_focus = true +horizontal_scroll_mode = 0 +script = ExtResource("2_4caf2") + +[node name="Control" type="Control" parent="ScrollContainer"] +custom_minimum_size = Vector2(0, 1500) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Control"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -400.0 +offset_top = -559.57 +offset_right = 400.0 +offset_bottom = 571.801 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0174533 +theme = ExtResource("1_yq0aa") +texture = SubResource("NoiseTexture2D_bvvl7") + +[node name="Hole1" type="Panel" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -365.0 +offset_top = -189.686 +offset_right = -345.0 +offset_bottom = -169.686 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5") + +[node name="Hole2" type="Panel" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -365.0 +offset_top = 130.314 +offset_right = -345.0 +offset_bottom = 150.314 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_e7xn5") + +[node name="PaperMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Contents" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin"] +layout_mode = 2 + +[node name="Title" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 30 +text = "c.setup.contract_title" + +[node name="Sep" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="Intro" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.contract_desc" +fit_content = true +scroll_active = false + +[node name="Name" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.name" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="NameEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +tooltip_text = "c.setup.name.desc" + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 2 +max_length = 32 + +[node name="Control" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry"] +layout_mode = 2 + +[node name="Position" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.position" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="PositionEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 2 +theme_override_colors/font_uneditable_color = Color(0.458824, 0, 0, 1) +theme_override_colors/font_color = Color(0.458824, 0, 0, 1) +editable = false + +[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/PositionEntry/LineEdit"] +custom_minimum_size = Vector2(300, 30) +layout_mode = 1 +offset_left = 9.97753 +offset_top = 3.2088 +offset_right = 309.978 +offset_bottom = 33.2088 +theme_override_colors/font_color = Color(0.458824, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_2vg4d") +text = "c.setup.position.value" + +[node name="Uniform" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.uniform" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="SelectUniform" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +alignment = 1 + +[node name="Experience" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.experience" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="SelectExperience" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +alignment = 1 + +[node name="CheckBox" type="CheckBox" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/SelectExperience"] +layout_mode = 2 +text = "c.setup.experience.skip" +text_direction = 3 + +[node name="Duties" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.duties" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Terms" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.additional_terms" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Compensation" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="CompensationEntry" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(15.045, 0) +layout_mode = 2 + +[node name="Text1" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(100.08, 0) +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation.salary.prefix" +fit_content = true +scroll_active = false +autowrap_mode = 0 + +[node name="LineEdit" type="LineEdit" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(50, 30) +layout_mode = 2 +theme_override_colors/font_uneditable_color = Color(0.478431, 0, 0, 1) +editable = false + +[node name="LineEdit2" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry/LineEdit"] +custom_minimum_size = Vector2(50, 30) +layout_mode = 1 +offset_left = 9.55965 +offset_top = 4.09178 +offset_right = 79.5597 +offset_bottom = 34.0918 +theme_override_colors/font_color = Color(0.478431, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_2vg4d") +text = "c.setup.compensation.salary" + +[node name="Text2" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/CompensationEntry"] +custom_minimum_size = Vector2(100.08, 0) +layout_mode = 2 +bbcode_enabled = true +text = "c.setup.compensation.salary.suffix" +scroll_active = false + +[node name="Spacer" type="Control" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +custom_minimum_size = Vector2(0, 200) +layout_mode = 2 + +[node name="Signatures" type="HBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents"] +layout_mode = 2 + +[node name="EmployerMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"] +layout_mode = 2 + +[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin"] +layout_mode = 2 + +[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 15 +bbcode_enabled = true +text = "c.setup.frank_signature.desc" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Signature" type="Label" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +custom_minimum_size = Vector2(200, 80) +layout_mode = 2 +theme_override_colors/font_color = Color(0.415686, 0.0253044, 0.135441, 1) +theme_override_fonts/font = SubResource("FontVariation_2cc7p") +theme_override_font_sizes/font_size = 31 +text = "c.setup.frank_signature" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployerMargin/Sign"] +layout_mode = 2 + +[node name="EmployeeMargin" type="MarginContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures"] +layout_mode = 2 + +[node name="Sign" type="VBoxContainer" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin"] +layout_mode = 2 + +[node name="Desc" type="RichTextLabel" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 15 +bbcode_enabled = true +text = "c.setup.user_signature.desc" +fit_content = true +scroll_active = false +text_direction = 3 + +[node name="Signature" type="Button" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign" groups=["no_click_sound"]] +custom_minimum_size = Vector2(200, 80) +layout_mode = 2 +text = "c.setup.user_signature" + +[node name="Underline" type="HSeparator" parent="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign"] +layout_mode = 2 + +[node name="Back" type="Button" parent="."] +layout_mode = 1 +offset_right = 106.0 +offset_bottom = 31.0 +text = "c.menu.back" + +[node name="Page" type="AudioStreamPlayer" parent="."] +stream = ExtResource("5_xac6d") +volume_db = -16.0 +autoplay = true + +[node name="Sign" type="AudioStreamPlayer" parent="."] +stream = ExtResource("6_wf0gh") +volume_db = -16.0 + +[connection signal="pressed" from="ScrollContainer/Control/TextureRect/PaperMargin/Contents/Signatures/EmployeeMargin/Sign/Signature" to="." method="_on_sign_pressed"] +[connection signal="pressed" from="Back" to="." method="_on_back_pressed"] diff --git a/client/gui/menus/transition/scene_transition.gd b/client/gui/menus/transition/scene_transition.gd new file mode 100644 index 00000000..330d67d6 --- /dev/null +++ b/client/gui/menus/transition/scene_transition.gd @@ -0,0 +1,66 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name SceneTransition +extends Control + +@onready var black_anim: AnimationPlayer = $black_fader +@onready var text_anim: AnimationPlayer = $text_fader +@onready var text: Label = $text_margin/text + +var s_current = false +var s_target = false +var fading = false + +func _ready(): + $black.visible = true + text.visible = true + text.text = "" + +func set_loading_text(s: String): + text.text = s + text_anim.play("fade") + +func next(): + while fading: await black_anim.animation_finished + if s_target == s_current: return + fading = true + if s_target: + if text.text != "": + text_anim.play_backwards("fade") + await text_anim.animation_finished + black_anim.play_backwards("fade") + await black_anim.animation_finished + self.mouse_filter = Control.MOUSE_FILTER_IGNORE + set_loading_text("") + s_current = true + else: + self.mouse_filter = Control.MOUSE_FILTER_STOP + black_anim.play("fade") + await black_anim.animation_finished + await get_tree().process_frame # animation finishes one frame early + s_current = false + fading = false + await next() + +func fade_in(): + s_target = true + await next() +func fade_out(): + s_target = false + await next() + +func _exit_tree(): + if fading: push_error("SceneTransition destroyed while fading") diff --git a/client/gui/menus/transition/scene_transition.gd.uid b/client/gui/menus/transition/scene_transition.gd.uid new file mode 100644 index 00000000..60f764ae --- /dev/null +++ b/client/gui/menus/transition/scene_transition.gd.uid @@ -0,0 +1 @@ +uid://ciml1u2x4f1ci diff --git a/client/gui/menus/transition/scene_transition.tscn b/client/gui/menus/transition/scene_transition.tscn new file mode 100644 index 00000000..dab16084 --- /dev/null +++ b/client/gui/menus/transition/scene_transition.tscn @@ -0,0 +1,135 @@ +[gd_scene load_steps=11 format=3 uid="uid://bg2d78ycorcqk"] + +[ext_resource type="Script" uid="uid://ciml1u2x4f1ci" path="res://gui/menus/transition/scene_transition.gd" id="1_fpbwj"] +[ext_resource type="Shader" uid="uid://bmxrbbw18xq7u" path="res://gui/menus/transition/text_loading_anim.gdshader" id="2_g21ck"] + +[sub_resource type="Animation" id="Animation_g21ck"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("black:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = false +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0, 0, 0, 1)] +} + +[sub_resource type="Animation" id="Animation_e6dcd"] +resource_name = "fade" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("black:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_00tv0"] +_data = { +&"RESET": SubResource("Animation_g21ck"), +&"fade": SubResource("Animation_e6dcd") +} + +[sub_resource type="Animation" id="Animation_xgn2a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("text_margin/text:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} + +[sub_resource type="Animation" id="Animation_cq5i2"] +resource_name = "fade" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("text_margin/text:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_pea72"] +_data = { +&"RESET": SubResource("Animation_xgn2a"), +&"fade": SubResource("Animation_cq5i2") +} + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_00tv0"] +shader = ExtResource("2_g21ck") + +[sub_resource type="LabelSettings" id="LabelSettings_e6dcd"] +font_size = 34 + +[node name="SceneTransition" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_fpbwj") + +[node name="black_fader" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_00tv0") +} +speed_scale = 4.0 + +[node name="black" type="ColorRect" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 1) + +[node name="text_fader" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_pea72") +} +speed_scale = 4.0 + +[node name="text_margin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -107.0 +offset_right = 401.0 +grow_vertical = 0 +mouse_filter = 2 +theme_override_constants/margin_left = 50 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 50 +theme_override_constants/margin_bottom = 50 + +[node name="text" type="Label" parent="text_margin"] +modulate = Color(1, 1, 1, 0) +material = SubResource("ShaderMaterial_00tv0") +layout_mode = 2 +text = "Loading something..." +label_settings = SubResource("LabelSettings_e6dcd") diff --git a/client/gui/menus/transition/text_loading_anim.gdshader b/client/gui/menus/transition/text_loading_anim.gdshader new file mode 100644 index 00000000..145dab78 --- /dev/null +++ b/client/gui/menus/transition/text_loading_anim.gdshader @@ -0,0 +1,13 @@ +shader_type canvas_item; + +varying vec4 vertex_color; +void vertex() { + vertex_color = COLOR; +} + +void fragment() { + vec4 tex = texture(TEXTURE, UV) * COLOR; + float wave = sin(VERTEX.x*0.01-TIME*10.) * 0.5 + 0.5; + wave = pow(wave, 3.); + COLOR = tex * (1. - wave * 0.2); +} diff --git a/client/gui/menus/transition/text_loading_anim.gdshader.uid b/client/gui/menus/transition/text_loading_anim.gdshader.uid new file mode 100644 index 00000000..26730c73 --- /dev/null +++ b/client/gui/menus/transition/text_loading_anim.gdshader.uid @@ -0,0 +1 @@ +uid://bmxrbbw18xq7u diff --git a/client/gui/overlays/ingame/announce_title.gd b/client/gui/overlays/ingame/announce_title.gd new file mode 100644 index 00000000..227e184f --- /dev/null +++ b/client/gui/overlays/ingame/announce_title.gd @@ -0,0 +1,42 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control + +@onready var init_delay: Timer = $InitialDelay +@onready var prep_timer: Timer = $PreperationTimer +@onready var anim_player: AnimationPlayer = $AnimationPlayer +@onready var label: Label = $Center/Node2D/Label + +func announce_start() -> void: + init_delay.start() + await init_delay.timeout + + Sound.play_game_start() + show() + label.text = tr("c.announce.ready") + anim_player.play("fade_in") + await anim_player.animation_finished + prep_timer.start() + await prep_timer.timeout + anim_player.play("fade_out") + await anim_player.animation_finished + + label.text = tr("c.announce.go") + anim_player.play("fade_in") + await anim_player.animation_finished + anim_player.play("fade_out") + await anim_player.animation_finished + hide() diff --git a/client/gui/overlays/ingame/announce_title.gd.uid b/client/gui/overlays/ingame/announce_title.gd.uid new file mode 100644 index 00000000..e57b9722 --- /dev/null +++ b/client/gui/overlays/ingame/announce_title.gd.uid @@ -0,0 +1 @@ +uid://ci08whhm2ej1m diff --git a/client/gui/overlays/ingame/chat.gd b/client/gui/overlays/ingame/chat.gd new file mode 100644 index 00000000..673dc979 --- /dev/null +++ b/client/gui/overlays/ingame/chat.gd @@ -0,0 +1,34 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name ChatPreview + +const CHAT_MESSAGE_SCENE = preload("res://gui/components/message/chat_message.tscn") + +@onready var game: Game = $"../Game" +@onready var messages_container: VBoxContainer = $MarginContainer/ScrollContainer/PanelContainer/Messages + +func _ready(): + game.text_message.connect(func(message: Game.TextMessage): + var chat_message: ChatMessage = CHAT_MESSAGE_SCENE.instantiate() + messages_container.add_child(chat_message) + chat_message.set_message( + message.username, + message.text, + message.color, + true, + message.timeout_remaining) + ) diff --git a/client/gui/overlays/ingame/chat.gd.uid b/client/gui/overlays/ingame/chat.gd.uid new file mode 100644 index 00000000..7a372630 --- /dev/null +++ b/client/gui/overlays/ingame/chat.gd.uid @@ -0,0 +1 @@ +uid://bgt04y4ncl1fv diff --git a/client/gui/overlays/ingame/chat.tscn b/client/gui/overlays/ingame/chat.tscn new file mode 100644 index 00000000..f5b1060c --- /dev/null +++ b/client/gui/overlays/ingame/chat.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=5 format=3 uid="uid://xcxbmynn8mhi"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_lmy51"] +[ext_resource type="Script" uid="uid://bgt04y4ncl1fv" path="res://gui/overlays/ingame/chat.gd" id="2_3543w"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_15i2y"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_3rmhr"] + +[node name="ChatPreview" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_lmy51") +script = ExtResource("2_3543w") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +anchor_bottom = 1.0 +offset_right = 296.0 +grow_vertical = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"] +layout_mode = 2 +horizontal_scroll_mode = 0 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/ScrollContainer"] +material = ExtResource("3_15i2y") +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +mouse_filter = 2 +script = ExtResource("4_3rmhr") + +[node name="Messages" type="VBoxContainer" parent="MarginContainer/ScrollContainer/PanelContainer"] +layout_mode = 2 +mouse_filter = 2 diff --git a/client/gui/overlays/ingame/score.gd b/client/gui/overlays/ingame/score.gd new file mode 100644 index 00000000..d4e2e3d3 --- /dev/null +++ b/client/gui/overlays/ingame/score.gd @@ -0,0 +1,68 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +class_name Overlay +extends PanelContainer + +const LABEL_SCALE: Vector2 = Vector2(1.5, 1.5) + +var failed: int = 0 +var completed: int = 0 +var points: int = 0 + +@onready var failed_label: Label = $Score/Paper/Margin/Lines/Line2/Failed +@onready var completed_label: Label = $Score/Paper/Margin/Lines/Line1/Completed +@onready var points_label: Label = $Score/Paper/Margin/Lines/Line3/Points +@onready var timer: Timer = $Timer +@onready var seconds_label: Label = $Time/Paper/Line/Seconds +@onready var decimals_label: Label = $Time/Paper/Line/Decimals +@onready var announcement = $Announcement + +func update(failed_: int, completed_: int, points_: int, time: float): + if failed_ - failed: + failed_label.text = str(failed_) + failed_label.scale = LABEL_SCALE + failed = failed_ + if completed_ - completed: + completed_label.text = str(completed_) + completed_label.scale = LABEL_SCALE + completed = completed_ + if points_ - points: + points_label.text = str(points_) + points_label.scale = LABEL_SCALE + points = points_ + + timer.stop() + if time > 0.: + timer.wait_time = time + timer.start() + +func set_ingame(_state: bool, lobby: bool): + if lobby: + hide() + timer.stop() + else: + show() + +func announce_start(): + announcement.announce_start() + +func _process(delta): + failed_label.scale = G.interpolate(failed_label.scale, Vector2(1, 1), delta * 4.) + completed_label.scale = G.interpolate(completed_label.scale, Vector2(1, 1), delta * 4.) + points_label.scale = G.interpolate(points_label.scale, Vector2(1, 1), delta * 4.) + var seconds: float = floor(timer.time_left) + seconds_label.text = str(int(seconds)) + decimals_label.text = "%01d" % int((timer.time_left - seconds) * 10) diff --git a/client/gui/overlays/ingame/score.gd.uid b/client/gui/overlays/ingame/score.gd.uid new file mode 100644 index 00000000..ff13fb53 --- /dev/null +++ b/client/gui/overlays/ingame/score.gd.uid @@ -0,0 +1 @@ +uid://mcgg3q0l03dx diff --git a/client/gui/overlays/ingame/score.tscn b/client/gui/overlays/ingame/score.tscn new file mode 100644 index 00000000..497275f5 --- /dev/null +++ b/client/gui/overlays/ingame/score.tscn @@ -0,0 +1,555 @@ +[gd_scene load_steps=14 format=3 uid="uid://bpikve6wlsjfl"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_4kujw"] +[ext_resource type="Script" uid="uid://mcgg3q0l03dx" path="res://gui/overlays/ingame/score.gd" id="2_kbjds"] +[ext_resource type="Texture2D" uid="uid://chxkwohi56cxx" path="res://gui/resources/shaders/paper.tres" id="3_oum5g"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_u54fv"] +[ext_resource type="Script" uid="uid://ci08whhm2ej1m" path="res://gui/overlays/ingame/announce_title.gd" id="5_874f2"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_04ujj"] +bg_color = Color(0, 0, 0, 0) + +[sub_resource type="FontVariation" id="FontVariation_8f216"] +base_font = ExtResource("3_u54fv") +variation_embolden = 0.5 + +[sub_resource type="Animation" id="Animation_owy7i"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:scale:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:scale:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:r") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:g") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:modulate:b") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:modulate:a") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_kmsgw"] +resource_name = "fade_in" +length = 0.5 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:scale:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:scale:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:r") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:g") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:modulate:b") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:modulate:a") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5) +} + +[sub_resource type="Animation" id="Animation_874f2"] +resource_name = "fade_in_and_out" +length = 0.8 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.3, 0.8) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Center/Node2D:scale:x") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 2, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.8) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Center/Node2D:scale:y") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1e-05, -0.25, 0, 0.25, 0, 2, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.8) +} + +[sub_resource type="Animation" id="Animation_x6gse"] +resource_name = "fade_out" +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 1) +} + +[sub_resource type="Animation" id="Animation_deqe4"] +resource_name = "fade_out_quick" +length = 0.25 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Center/Node2D:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Center/Node2D:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Center/Node2D:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 1, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Center/Node2D:modulate:a") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(1, -0.125, 0, 0.125, 0, 0, -0.125, 0, 0.125, 0), +"times": PackedFloat32Array(0, 0.25) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_deqe4"] +_data = { +&"RESET": SubResource("Animation_owy7i"), +&"fade_in": SubResource("Animation_kmsgw"), +&"fade_in_and_out": SubResource("Animation_874f2"), +&"fade_out": SubResource("Animation_x6gse"), +&"fade_out_quick": SubResource("Animation_deqe4") +} + +[node name="Overlay" type="PanelContainer"] +layout_direction = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = ExtResource("1_4kujw") +theme_override_styles/panel = SubResource("StyleBoxFlat_04ujj") +script = ExtResource("2_kbjds") + +[node name="Timer" type="Timer" parent="."] +wait_time = 30.0 + +[node name="Score" type="Control" parent="."] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 0 + +[node name="Paper" type="TextureRect" parent="Score"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -242.0 +offset_top = -327.0 +offset_right = 270.0 +offset_bottom = 185.0 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0610865 +texture = ExtResource("3_oum5g") + +[node name="Margin" type="MarginContainer" parent="Score/Paper"] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -142.0 +offset_right = 258.0 +grow_vertical = 0 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_bottom = 10 + +[node name="Lines" type="VBoxContainer" parent="Score/Paper/Margin"] +layout_direction = 1 +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 8 + +[node name="Line1" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line1"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 25 +text = "c.score.completed" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line1"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Completed" type="Label" parent="Score/Paper/Margin/Lines/Line1"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0.278431, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "0" +horizontal_alignment = 1 + +[node name="Line2" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line2"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 25 +text = "c.score.failed" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Failed" type="Label" parent="Score/Paper/Margin/Lines/Line2"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0.505882, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "0" +horizontal_alignment = 1 + +[node name="Line3" type="HBoxContainer" parent="Score/Paper/Margin/Lines"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Score/Paper/Margin/Lines/Line3"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 35 +text = "c.score.points" + +[node name="Spacer" type="Control" parent="Score/Paper/Margin/Lines/Line3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Points" type="Label" parent="Score/Paper/Margin/Lines/Line3"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "0" +horizontal_alignment = 1 + +[node name="Time" type="Control" parent="."] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 + +[node name="Paper" type="TextureRect" parent="Time"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -206.0 +offset_top = -119.0 +offset_right = 306.0 +offset_bottom = 393.0 +grow_horizontal = 2 +grow_vertical = 2 +rotation = 0.0610865 +texture = ExtResource("3_oum5g") + +[node name="Line" type="HBoxContainer" parent="Time/Paper"] +layout_mode = 0 + +[node name="Seconds" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "300" +horizontal_alignment = 2 + +[node name="Point" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "." +horizontal_alignment = 1 + +[node name="Decimals" type="Label" parent="Time/Paper/Line"] +auto_translate_mode = 2 +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_u54fv") +theme_override_font_sizes/font_size = 45 +text = "00" + +[node name="Announcement" type="Control" parent="."] +visible = false +layout_mode = 2 +script = ExtResource("5_874f2") + +[node name="Center" type="Control" parent="Announcement"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Node2D" type="Node2D" parent="Announcement/Center"] +modulate = Color(1, 1, 1, 0) +scale = Vector2(1e-05, 1e-05) + +[node name="Label" type="Label" parent="Announcement/Center/Node2D"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -375.0 +offset_top = -50.0 +offset_right = 375.0 +offset_bottom = 50.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 1 +theme_override_colors/font_outline_color = Color(0.564706, 0.207843, 0.266667, 1) +theme_override_constants/outline_size = 20 +theme_override_fonts/font = SubResource("FontVariation_8f216") +theme_override_font_sizes/font_size = 64 +text = "GO!" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Announcement"] +libraries = { +&"": SubResource("AnimationLibrary_deqe4") +} + +[node name="PreperationTimer" type="Timer" parent="Announcement"] +one_shot = true + +[node name="InitialDelay" type="Timer" parent="Announcement"] +wait_time = 0.5 +one_shot = true diff --git a/client/gui/overlays/lobby/lobby.gd b/client/gui/overlays/lobby/lobby.gd new file mode 100644 index 00000000..3971dbb3 --- /dev/null +++ b/client/gui/overlays/lobby/lobby.gd @@ -0,0 +1,204 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name Lobby + +const MAX_BOT_COUNT_PER_TYPE: int = 3 +const PLAYER = preload("res://gui/overlays/lobby/player.tscn") + +var map_count +var selected_map := 0 +var selected_map_name: String + +var bots_enabled := false +var bot_counts := {} +var bot_reset_buttons := {} +var bot_inc_buttons := {} +var bot_dec_buttons := {} + +@onready var game: Game = $"../Game" +@onready var player_container = $PlayerList/VBoxContainer/Players + +@onready var map_name_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Name +@onready var map_player_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Players +@onready var map_difficulty_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Difficulty +@onready var map_list_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList/VBoxContainer +@onready var map_list = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList + +@onready var map_selector = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer +@onready var prev_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer/Left +@onready var next_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2/Right + +@onready var bots_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots +@onready var bot_settings = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom/BotSettings +@onready var bot_settings_conainer = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom + +@onready var join_spectate = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/JoinSpectate +@onready var start_button = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/Start + +func _ready(): + game.update_players.connect(update_players) + initialize() + game.data_updated.connect(initialize) + game.join_state_updated.connect(_on_game_join_state_updated) + _on_game_join_state_updated(game.join_state) + check_for_music() + +func initialize(): + map_count = game.maps.size() + + for c in map_list_container.get_children(): + c.queue_free() + for c in bot_settings.get_children(): + c.queue_free() + + var i := 0 + for m in game.maps: + var b := Button.new() + b.name = m[0] + b.text = "%s (%d)" % [m[1]["name"], m[1]["players"]] + b.pressed.connect(select_map.bind(i)) + b.focus_entered.connect(select_map.bind(i)) + map_list_container.add_child(b) + i += 1 + select_map(0) + + for algo_id: String in game.bot_algos: + if algo_id == "customer" or algo_id == "test": + continue + + bot_counts[algo_id] = 0 + + var h := HBoxContainer.new() + h.name = algo_id + var add := Button.new() + add.text = "+" + var reset := Button.new() + reset.size_flags_horizontal = SIZE_EXPAND_FILL + var remove := Button.new() + remove.text = "-" + bot_reset_buttons[algo_id] = reset + bot_inc_buttons[algo_id] = add + bot_dec_buttons[algo_id] = remove + update_bot_reset_text(algo_id) + add.pressed.connect(increase_bot_count.bind(algo_id)) + reset.pressed.connect(reset_bot_count.bind(algo_id)) + remove.pressed.connect(decrease_bot_count.bind(algo_id)) + h.add_child(remove) + h.add_child(reset) + h.add_child(add) + bot_settings.add_child(h) + +func select_map(i: int): + if i >= map_count: + return + selected_map = i + var map_data: Dictionary = game.maps[i][1] + map_name_label.text = map_data["name"] + map_player_label.text = tr("c.map.players_recommended").format([roundi(map_data["players"])]) + map_difficulty_label.text = tr("c.map.difficulty.%d" % (map_data["difficulty"] - 1)) + selected_map_name = game.maps[i][0] + if not game.menu.covered: + map_list_container.get_child(i).grab_focus() + +func increase_bot_count(algo_id: String): + bot_counts[algo_id] += 1 + update_bot_reset_text(algo_id) + +func decrease_bot_count(algo_id: String): + bot_counts[algo_id] -= 1 + update_bot_reset_text(algo_id) + +func reset_bot_count(algo_id: String): + bot_counts[algo_id] = 0 + update_bot_reset_text(algo_id) + +func update_bot_reset_text(algo_id: String): + var display_name: String = tr("s.bot.%s" % algo_id) + bot_reset_buttons[algo_id].text = "%s (%d)" % [display_name, bot_counts[algo_id]] + bot_inc_buttons[algo_id].disabled = not bot_counts[algo_id] < MAX_BOT_COUNT_PER_TYPE + bot_dec_buttons[algo_id].disabled = not bot_counts[algo_id] > 0 + +func update_players(player_list: Dictionary): + for i in player_container.get_children(): + i.queue_free() + + for i in player_list.keys(): + var p: PlayerTag = PLAYER.instantiate() + player_container.add_child(p) + p.setup(player_list[i].username) + +func _input(_event): + if not visible: + return + + if Input.is_action_just_pressed("previous") and not prev_map.disabled: + prev_map.emit_signal("pressed") + elif Input.is_action_just_pressed("next") and not next_map.disabled: + next_map.emit_signal("pressed") + +func _on_left_pressed(): + selected_map = (selected_map - 1) % map_count + select_map(selected_map) + +func _on_right_pressed(): + selected_map = (selected_map + 1) % map_count + select_map(selected_map) + +func _on_start_pressed(): + if selected_map_name != null: + var start_msg := "/start %s" % selected_map_name + + if bots_enabled: + for k in bot_counts.keys(): + for i in range(bot_counts[k]): + start_msg += "\ncreate-bot %s" % k + + game.mp.send_chat(game.my_player_id, start_msg) + Sound.play_music("stop") # TODO: Game music enter + +func _on_game_join_state_updated(state: Game.JoinState): + match state: + Game.JoinState.JOINED: + map_selector.show() + map_list.show() + bots_container.show() + start_button.disabled = false + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.spectate") + Game.JoinState.SPECTATING: + map_selector.hide() + map_list.hide() + bots_container.hide() + start_button.disabled = true + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.join") + Game.JoinState.WAITING: + join_spectate.disabled = true + +func _on_join_spectate_pressed(): + game.toggle_join() + +func check_for_music(): + if visible: + Sound.play_music("Lobby") + else: + Sound.play_music("stop") # TODO: Game music enter + +func _on_enable_bots_toggled(toggled_on): + bots_enabled = toggled_on + bot_settings_conainer.visible = toggled_on + bots_container.size_flags_vertical = SIZE_EXPAND_FILL if toggled_on else SIZE_FILL diff --git a/client/gui/overlays/lobby/lobby.gd.uid b/client/gui/overlays/lobby/lobby.gd.uid new file mode 100644 index 00000000..b92e8681 --- /dev/null +++ b/client/gui/overlays/lobby/lobby.gd.uid @@ -0,0 +1 @@ +uid://bssjvsu44l0fn diff --git a/client/gui/overlays/lobby/lobby.tscn b/client/gui/overlays/lobby/lobby.tscn new file mode 100644 index 00000000..58ae2add --- /dev/null +++ b/client/gui/overlays/lobby/lobby.tscn @@ -0,0 +1,191 @@ +[gd_scene load_steps=17 format=3 uid="uid://bc50la65ntifb"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_u18ke"] +[ext_resource type="Script" uid="uid://bssjvsu44l0fn" path="res://gui/overlays/lobby/lobby.gd" id="2_7657i"] +[ext_resource type="StyleBox" uid="uid://de80aw86emnql" path="res://gui/resources/style/lobby_panel_override.tres" id="3_6iqoe"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_esmbx"] +[ext_resource type="Texture2D" uid="uid://35rd5gamtyqm" path="res://gui/resources/icons/arrow.svg" id="3_jxleg"] +[ext_resource type="Texture2D" uid="uid://j75dbytlbju" path="res://gui/resources/icons/arrow_pressed.svg" id="4_eapmn"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="5_am8pt"] +[ext_resource type="Texture2D" uid="uid://b33qmctbpf48g" path="res://gui/resources/icons/arrow_hover.svg" id="5_odwav"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="6_7mu2u"] +[ext_resource type="Texture2D" uid="uid://by3qsrpxnfq4w" path="res://gui/resources/icons/arrow_focus.svg" id="6_tulu3"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="8_cwbpa"] +[ext_resource type="Texture2D" uid="uid://bsx6fo7mv2u6a" path="res://gui/resources/icons/controller_x.svg" id="9_q14bw"] +[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="10_bgene"] +[ext_resource type="Texture2D" uid="uid://cr2a6ide6vnnv" path="res://gui/resources/icons/controller_y.svg" id="11_5uugf"] +[ext_resource type="Script" uid="uid://b1eomxildrq30" path="res://gui/components/controller_button.gd" id="12_7mu2u"] + +[sub_resource type="FontVariation" id="FontVariation_5xxr2"] +base_font = ExtResource("8_cwbpa") +variation_embolden = 1.5 + +[node name="Lobby" type="Control" groups=["no_auto_focus"]] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_u18ke") +script = ExtResource("2_7657i") + +[node name="PlayerList" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 342 +theme_override_constants/margin_top = 32 +theme_override_constants/margin_right = 342 +theme_override_constants/margin_bottom = 32 + +[node name="VBoxContainer" type="VBoxContainer" parent="PlayerList"] +layout_mode = 2 + +[node name="Players" type="HBoxContainer" parent="PlayerList/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Sidebar" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 2 + +[node name="Bottom" type="PanelContainer" parent="Sidebar"] +material = ExtResource("3_esmbx") +layout_mode = 2 +theme_override_styles/panel = ExtResource("3_6iqoe") +script = ExtResource("5_am8pt") + +[node name="MarginContainer" type="MarginContainer" parent="Sidebar/Bottom"] +layout_mode = 2 +script = ExtResource("6_7mu2u") + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 24 + +[node name="HBoxContainer" type="HBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_direction = 2 +layout_mode = 2 +alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Left" type="TextureButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"] +custom_minimum_size = Vector2(19, 28) +layout_mode = 2 +focus_mode = 0 +texture_normal = ExtResource("3_jxleg") +texture_pressed = ExtResource("4_eapmn") +texture_hover = ExtResource("5_odwav") +texture_focused = ExtResource("6_tulu3") +ignore_texture_size = true +stretch_mode = 4 +flip_h = true + +[node name="Map" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 + +[node name="Name" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +theme_override_fonts/font = SubResource("FontVariation_5xxr2") +theme_override_font_sizes/font_size = 24 +text = "Map name" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Players" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +layout_mode = 2 +text = "Players" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Difficulty" type="Label" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map"] +layout_mode = 2 +text = "Difficulty" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="VBoxContainer2" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="Right" type="TextureButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2"] +custom_minimum_size = Vector2(19, 28) +layout_mode = 2 +focus_mode = 0 +texture_normal = ExtResource("3_jxleg") +texture_pressed = ExtResource("4_eapmn") +texture_hover = ExtResource("5_odwav") +texture_focused = ExtResource("6_tulu3") +ignore_texture_size = true +stretch_mode = 4 + +[node name="MapList" type="ScrollContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("10_bgene") + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/MapList"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Bots" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="EnableBots" type="CheckButton" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots"] +layout_mode = 2 +text = "c.menu.lobby.enable_bots" + +[node name="ScrollContainerCustom" type="ScrollContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots"] +visible = false +layout_mode = 2 +size_flags_vertical = 3 +script = ExtResource("10_bgene") + +[node name="BotSettings" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="Sidebar/Bottom/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 15 +alignment = 1 + +[node name="JoinSpectate" type="Button" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "c.menu.ingame.spectate" +expand_icon = true +script = ExtResource("12_7mu2u") +controller_texture = ExtResource("11_5uugf") +press_action = "join_spectate" +metadata/_custom_type_script = "uid://b1eomxildrq30" + +[node name="Start" type="Button" parent="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "c.menu.lobby.start" +expand_icon = true +script = ExtResource("12_7mu2u") +controller_texture = ExtResource("9_q14bw") +press_action = "start_game" +metadata/_custom_type_script = "uid://b1eomxildrq30" + +[connection signal="visibility_changed" from="." to="." method="check_for_music"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer/Left" to="." method="_on_left_pressed"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2/Right" to="." method="_on_right_pressed"] +[connection signal="toggled" from="Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/EnableBots" to="." method="_on_enable_bots_toggled"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/JoinSpectate" to="." method="_on_join_spectate_pressed"] +[connection signal="pressed" from="Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/Start" to="." method="_on_start_pressed"] diff --git a/client/gui/overlays/lobby/player.gd b/client/gui/overlays/lobby/player.gd new file mode 100644 index 00000000..175d6341 --- /dev/null +++ b/client/gui/overlays/lobby/player.gd @@ -0,0 +1,22 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends PanelContainer +class_name PlayerTag + +@onready var name_label = $MarginContainer/HBoxContainer/Label + +func setup(player_name: String): + name_label.text = player_name diff --git a/client/gui/overlays/lobby/player.gd.uid b/client/gui/overlays/lobby/player.gd.uid new file mode 100644 index 00000000..b0971cdb --- /dev/null +++ b/client/gui/overlays/lobby/player.gd.uid @@ -0,0 +1 @@ +uid://buxb488rr2ncs diff --git a/client/gui/overlays/lobby/player.tscn b/client/gui/overlays/lobby/player.tscn new file mode 100644 index 00000000..aa8997a1 --- /dev/null +++ b/client/gui/overlays/lobby/player.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3 uid="uid://gmldnel4xbxy"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_flfqn"] +[ext_resource type="Texture2D" uid="uid://222w1wha75od" path="res://gui/resources/icons/user.webp" id="2_mnaqt"] +[ext_resource type="Script" uid="uid://buxb488rr2ncs" path="res://gui/overlays/lobby/player.gd" id="2_w3lyk"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1227j"] +bg_color = Color(0, 0, 0, 1) +corner_radius_top_left = 16 +corner_radius_top_right = 16 +corner_radius_bottom_right = 16 +corner_radius_bottom_left = 16 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3yp6e"] +content_margin_right = 8.0 + +[node name="Player" type="PanelContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +theme = ExtResource("1_flfqn") +theme_override_styles/panel = SubResource("StyleBoxFlat_1227j") +script = ExtResource("2_w3lyk") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="Icon" type="TextureRect" parent="MarginContainer/HBoxContainer"] +layout_mode = 2 +texture = ExtResource("2_mnaqt") +expand_mode = 2 + +[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"] +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxEmpty_3yp6e") +text = "Player" +vertical_alignment = 1 diff --git a/client/gui/resources/fonts/font-azaret-mono.woff2 b/client/gui/resources/fonts/font-azaret-mono.woff2 Binary files differnew file mode 100644 index 00000000..c413b182 --- /dev/null +++ b/client/gui/resources/fonts/font-azaret-mono.woff2 diff --git a/client/gui/resources/fonts/font-azaret-mono.woff2.import b/client/gui/resources/fonts/font-azaret-mono.woff2.import new file mode 100644 index 00000000..364d3ba3 --- /dev/null +++ b/client/gui/resources/fonts/font-azaret-mono.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bk704sc5gkrb3" +path="res://.godot/imported/font-azaret-mono.woff2-d201b5a023a336fb85edf509d0dd9fe6.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-azaret-mono.woff2" +dest_files=["res://.godot/imported/font-azaret-mono.woff2-d201b5a023a336fb85edf509d0dd9fe6.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/fonts/font-josefin-sans.woff2 b/client/gui/resources/fonts/font-josefin-sans.woff2 Binary files differnew file mode 100644 index 00000000..dce2708f --- /dev/null +++ b/client/gui/resources/fonts/font-josefin-sans.woff2 diff --git a/client/gui/resources/fonts/font-josefin-sans.woff2.import b/client/gui/resources/fonts/font-josefin-sans.woff2.import new file mode 100644 index 00000000..849d69a4 --- /dev/null +++ b/client/gui/resources/fonts/font-josefin-sans.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://5ixo6b3bd3km" +path="res://.godot/imported/font-josefin-sans.woff2-f1848192fffe0aa973b972af6b2bb0c4.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-josefin-sans.woff2" +dest_files=["res://.godot/imported/font-josefin-sans.woff2-f1848192fffe0aa973b972af6b2bb0c4.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/fonts/font-sansita-swashed.woff2 b/client/gui/resources/fonts/font-sansita-swashed.woff2 Binary files differnew file mode 100644 index 00000000..5c665fb0 --- /dev/null +++ b/client/gui/resources/fonts/font-sansita-swashed.woff2 diff --git a/client/gui/resources/fonts/font-sansita-swashed.woff2.import b/client/gui/resources/fonts/font-sansita-swashed.woff2.import new file mode 100644 index 00000000..7dab3339 --- /dev/null +++ b/client/gui/resources/fonts/font-sansita-swashed.woff2.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bo4vh5xkpvrh1" +path="res://.godot/imported/font-sansita-swashed.woff2-094d5cb1ef3d4e2539ac9238e4b7564c.fontdata" + +[deps] + +source_file="res://gui/resources/fonts/font-sansita-swashed.woff2" +dest_files=["res://.godot/imported/font-sansita-swashed.woff2-094d5cb1ef3d4e2539ac9238e4b7564c.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/client/gui/resources/icons/arrow.svg b/client/gui/resources/icons/arrow.svg new file mode 100644 index 00000000..bafc9e69 --- /dev/null +++ b/client/gui/resources/icons/arrow.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 100"><path stroke="white" stroke-width="10" fill="none" d="M20,20 L50,50 L 20,80" /></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/arrow.svg.import b/client/gui/resources/icons/arrow.svg.import new file mode 100644 index 00000000..5ea9e3c4 --- /dev/null +++ b/client/gui/resources/icons/arrow.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://35rd5gamtyqm" +path="res://.godot/imported/arrow.svg-5c6a786f82da6fec05fdd009d40f9e81.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow.svg" +dest_files=["res://.godot/imported/arrow.svg-5c6a786f82da6fec05fdd009d40f9e81.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=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_focus.svg b/client/gui/resources/icons/arrow_focus.svg new file mode 100644 index 00000000..456f0261 --- /dev/null +++ b/client/gui/resources/icons/arrow_focus.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 100"><path stroke="#aaaaff" stroke-width="10" fill="none" d="M20,20 L50,50 L 20,80" /></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/arrow_focus.svg.import b/client/gui/resources/icons/arrow_focus.svg.import new file mode 100644 index 00000000..e46a7698 --- /dev/null +++ b/client/gui/resources/icons/arrow_focus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by3qsrpxnfq4w" +path="res://.godot/imported/arrow_focus.svg-186cef816cf6f92795a6ffbcf94d9391.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_focus.svg" +dest_files=["res://.godot/imported/arrow_focus.svg-186cef816cf6f92795a6ffbcf94d9391.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=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_hover.svg b/client/gui/resources/icons/arrow_hover.svg new file mode 100644 index 00000000..098063ec --- /dev/null +++ b/client/gui/resources/icons/arrow_hover.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 100"><path stroke="#aaaaaa" stroke-width="10" fill="none" d="M20,20 L50,50 L 20,80" /></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/arrow_hover.svg.import b/client/gui/resources/icons/arrow_hover.svg.import new file mode 100644 index 00000000..f750cbbc --- /dev/null +++ b/client/gui/resources/icons/arrow_hover.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b33qmctbpf48g" +path="res://.godot/imported/arrow_hover.svg-c150da1cc405914a2d4c1388aea94f6b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_hover.svg" +dest_files=["res://.godot/imported/arrow_hover.svg-c150da1cc405914a2d4c1388aea94f6b.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=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/arrow_pressed.svg b/client/gui/resources/icons/arrow_pressed.svg new file mode 100644 index 00000000..1abd9a8f --- /dev/null +++ b/client/gui/resources/icons/arrow_pressed.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 100"><path stroke="gray" stroke-width="10" fill="none" d="M20,20 L50,50 L 20,80" /></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/arrow_pressed.svg.import b/client/gui/resources/icons/arrow_pressed.svg.import new file mode 100644 index 00000000..0cc07c10 --- /dev/null +++ b/client/gui/resources/icons/arrow_pressed.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j75dbytlbju" +path="res://.godot/imported/arrow_pressed.svg-72b6835d5e0ec811cf9d5e7abb401b66.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/arrow_pressed.svg" +dest_files=["res://.godot/imported/arrow_pressed.svg-72b6835d5e0ec811cf9d5e7abb401b66.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=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/client/gui/resources/icons/boost.webp b/client/gui/resources/icons/boost.webp Binary files differnew file mode 100644 index 00000000..afea92df --- /dev/null +++ b/client/gui/resources/icons/boost.webp diff --git a/client/gui/resources/icons/boost.webp.import b/client/gui/resources/icons/boost.webp.import new file mode 100644 index 00000000..9fb9ddf8 --- /dev/null +++ b/client/gui/resources/icons/boost.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnxllatlo4clg" +path="res://.godot/imported/boost.webp-877bfed2e298bb49bb39ce05f703e97f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/boost.webp" +dest_files=["res://.godot/imported/boost.webp-877bfed2e298bb49bb39ce05f703e97f.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 diff --git a/client/gui/resources/icons/circle.svg b/client/gui/resources/icons/circle.svg new file mode 100644 index 00000000..05fab1cb --- /dev/null +++ b/client/gui/resources/icons/circle.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle stroke="none" fill="black" cx="50" cy="50" r="50" /></svg> diff --git a/client/gui/resources/icons/circle.svg.import b/client/gui/resources/icons/circle.svg.import new file mode 100644 index 00000000..d49f9bc4 --- /dev/null +++ b/client/gui/resources/icons/circle.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2xf8qdh01e41" +path="res://.godot/imported/circle.svg-87329764c20f8477bea7d035824f68a6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/circle.svg" +dest_files=["res://.godot/imported/circle.svg-87329764c20f8477bea7d035824f68a6.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 diff --git a/client/gui/resources/icons/controller_x.svg b/client/gui/resources/icons/controller_x.svg new file mode 100644 index 00000000..9a5df2ea --- /dev/null +++ b/client/gui/resources/icons/controller_x.svg @@ -0,0 +1,6 @@ +<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs/> + <g> + <path stroke="none" fill="#009FEB" d="M56 32 Q56 42 48.95 48.95 42 56 32 56 22.05 56 15 48.95 8 42 8 32 8 22.05 15 15 22.05 8 32 8 42 8 48.95 15 56 22.05 56 32 M23 25 L29 32 23 39 23 40 25.25 42 26.4 42 32 35.5 37.65 42 38.75 42 41 40 41 39 35 32 41 25 41 24 38.75 22 37.65 22 32 28.55 26.4 22 25.25 22 23 24 23 25"/> + </g> +</svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/controller_x.svg.import b/client/gui/resources/icons/controller_x.svg.import new file mode 100644 index 00000000..568c8672 --- /dev/null +++ b/client/gui/resources/icons/controller_x.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bsx6fo7mv2u6a" +path="res://.godot/imported/controller_x.svg-84020d372efbd30d861ba44f5b1c1f7a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/controller_x.svg" +dest_files=["res://.godot/imported/controller_x.svg-84020d372efbd30d861ba44f5b1c1f7a.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 diff --git a/client/gui/resources/icons/controller_y.svg b/client/gui/resources/icons/controller_y.svg new file mode 100644 index 00000000..a378078b --- /dev/null +++ b/client/gui/resources/icons/controller_y.svg @@ -0,0 +1,6 @@ +<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs/> + <g> + <path stroke="none" fill="#FEB504" d="M56 32 Q56 42 48.95 48.95 42 56 32 56 22.05 56 15 48.95 8 42 8 32 8 22.05 15 15 22.05 8 32 8 42 8 48.95 15 56 22.05 56 32 M23 25 L30 32.9 30 42 34 42 34 32.9 41 25 41 24 38.75 22 37.65 22 32 28.55 26.4 22 25.25 22 23 24 23 25"/> + </g> +</svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/controller_y.svg.import b/client/gui/resources/icons/controller_y.svg.import new file mode 100644 index 00000000..f3f67231 --- /dev/null +++ b/client/gui/resources/icons/controller_y.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cr2a6ide6vnnv" +path="res://.godot/imported/controller_y.svg-a116dee9a585fceb0e69cea069bc92d3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/controller_y.svg" +dest_files=["res://.godot/imported/controller_y.svg-a116dee9a585fceb0e69cea069bc92d3.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 diff --git a/client/gui/resources/icons/hint.svg b/client/gui/resources/icons/hint.svg new file mode 100644 index 00000000..ad64de91 --- /dev/null +++ b/client/gui/resources/icons/hint.svg @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="64px" viewBox="0 0 64 64" version="1.1"> +<g id="surface1"> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,85.098039%,51.372549%);fill-opacity:1;" d="M 51.554688 19.664062 C 51.554688 31.109375 42.667969 32.886719 42.667969 43.554688 C 42.667969 49.0625 37.113281 49.527344 32.890625 49.527344 C 29.238281 49.527344 21.179688 48.140625 21.179688 43.550781 C 21.179688 32.890625 12.445312 31.109375 12.445312 19.664062 C 12.445312 8.941406 21.839844 0.25 32.148438 0.25 C 42.457031 0.25 51.554688 8.941406 51.554688 19.664062 Z M 51.554688 19.664062 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80%,83.921569%,86.666667%);fill-opacity:1;" d="M 39.40625 57.777344 C 39.40625 59.25 35.4375 62.222656 32 62.222656 C 28.5625 62.222656 24.59375 59.25 24.59375 57.777344 C 24.59375 56.304688 28.5625 56.890625 32 56.890625 C 35.4375 56.890625 39.40625 56.304688 39.40625 57.777344 Z M 39.40625 57.777344 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,80%,30.196078%);fill-opacity:1;" d="M 40.367188 18.296875 C 39.671875 17.605469 38.550781 17.605469 37.855469 18.296875 L 32 24.152344 L 26.144531 18.296875 C 25.449219 17.605469 24.328125 17.605469 23.632812 18.296875 C 22.9375 18.992188 22.9375 20.117188 23.632812 20.8125 L 30.222656 27.402344 L 30.222656 46.222656 C 30.222656 47.207031 31.019531 48 32 48 C 32.980469 48 33.777344 47.207031 33.777344 46.222656 L 33.777344 27.402344 L 40.367188 20.8125 C 41.0625 20.117188 41.0625 18.992188 40.367188 18.296875 Z M 40.367188 18.296875 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(60%,66.666667%,70.980392%);fill-opacity:1;" d="M 42.667969 55.109375 C 42.667969 57.074219 41.074219 58.667969 39.109375 58.667969 L 24.890625 58.667969 C 22.925781 58.667969 21.332031 57.074219 21.332031 55.109375 L 21.332031 44.445312 L 42.667969 44.445312 Z M 42.667969 55.109375 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80%,83.921569%,86.666667%);fill-opacity:1;" d="M 21.332031 56.890625 C 20.476562 56.890625 19.722656 56.273438 19.582031 55.402344 C 19.417969 54.4375 20.074219 53.519531 21.042969 53.359375 L 42.375 49.800781 C 43.34375 49.628906 44.257812 50.296875 44.417969 51.265625 C 44.582031 52.230469 43.925781 53.148438 42.957031 53.308594 L 21.625 56.863281 C 21.527344 56.882812 21.425781 56.890625 21.332031 56.890625 Z M 21.332031 49.777344 C 20.476562 49.777344 19.722656 49.160156 19.582031 48.292969 C 19.417969 47.324219 20.074219 46.40625 21.042969 46.246094 L 42.375 42.691406 C 43.34375 42.519531 44.257812 43.183594 44.417969 44.152344 C 44.582031 45.121094 43.925781 46.039062 42.957031 46.199219 L 21.625 49.753906 C 21.527344 49.769531 21.425781 49.777344 21.332031 49.777344 Z M 21.332031 49.777344 "/> +</g> +</svg> diff --git a/client/gui/resources/icons/hint.svg.import b/client/gui/resources/icons/hint.svg.import new file mode 100644 index 00000000..841acfb5 --- /dev/null +++ b/client/gui/resources/icons/hint.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2uv5rf0enikf" +path="res://.godot/imported/hint.svg-d7d8c196848a6c538326a5f8ec385b64.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/hint.svg" +dest_files=["res://.godot/imported/hint.svg-d7d8c196848a6c538326a5f8ec385b64.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 diff --git a/client/gui/resources/icons/interact.webp b/client/gui/resources/icons/interact.webp Binary files differnew file mode 100644 index 00000000..cf57c4c0 --- /dev/null +++ b/client/gui/resources/icons/interact.webp diff --git a/client/gui/resources/icons/interact.webp.import b/client/gui/resources/icons/interact.webp.import new file mode 100644 index 00000000..64d375eb --- /dev/null +++ b/client/gui/resources/icons/interact.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dcgt82qkya880" +path="res://.godot/imported/interact.webp-ba4dc2c22b6ace23a59d368b045b45ae.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/interact.webp" +dest_files=["res://.godot/imported/interact.webp-ba4dc2c22b6ace23a59d368b045b45ae.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 diff --git a/client/gui/resources/icons/pause.webp b/client/gui/resources/icons/pause.webp Binary files differnew file mode 100644 index 00000000..24ec72d8 --- /dev/null +++ b/client/gui/resources/icons/pause.webp diff --git a/client/gui/resources/icons/pause.webp.import b/client/gui/resources/icons/pause.webp.import new file mode 100644 index 00000000..a79d5b1e --- /dev/null +++ b/client/gui/resources/icons/pause.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qto5rj6wlaeb" +path="res://.godot/imported/pause.webp-59d9c713545753734e408e3bcfa465c6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/pause.webp" +dest_files=["res://.godot/imported/pause.webp-59d9c713545753734e408e3bcfa465c6.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 diff --git a/client/gui/resources/icons/plus.svg b/client/gui/resources/icons/plus.svg new file mode 100644 index 00000000..c79169ba --- /dev/null +++ b/client/gui/resources/icons/plus.svg @@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> + <rect stroke="none" fill="white" x="42.5" y="0" width="15" height="100" /> + <rect stroke="none" fill="white" x="0" y="42.5" width="100" height="15" /> +</svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/plus.svg.import b/client/gui/resources/icons/plus.svg.import new file mode 100644 index 00000000..98e9bf8e --- /dev/null +++ b/client/gui/resources/icons/plus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnfjbowd2i02r" +path="res://.godot/imported/plus.svg-5dcb9f0bf2e5a1c55b74537b98e2ec06.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/plus.svg" +dest_files=["res://.godot/imported/plus.svg-5dcb9f0bf2e5a1c55b74537b98e2ec06.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 diff --git a/client/gui/resources/icons/reset.svg b/client/gui/resources/icons/reset.svg new file mode 100644 index 00000000..660d7759 --- /dev/null +++ b/client/gui/resources/icons/reset.svg @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + height="16px" + viewBox="0 0 16 16" + width="16px" + version="1.1" + id="svg1" + sodipodi:docname="reset.svg" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs1" /> + <sodipodi:namedview + id="namedview1" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:zoom="50.3125" + inkscape:cx="5.4857143" + inkscape:cy="7.642236" + inkscape:window-width="1920" + inkscape:window-height="1011" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg1" /> + <path + d="m 8.914062 2 c -0.574218 0.007812 -1.152343 0.085938 -1.726562 0.238281 c -3.054688 0.820313 -5.1875 3.597657 -5.1875 6.761719 h -2 v 1 h 0.0078125 c -0.00390625 0.265625 0.1015625 0.519531 0.2851565 0.707031 l 2 2 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 l 2 -2 c 0.183594 -0.1875 0.289063 -0.441406 0.289063 -0.707031 h 0.003906 v -1 h -2 c 0 -2.269531 1.515625 -4.242188 3.707031 -4.832031 c 2.1875 -0.585938 4.488281 0.367187 5.625 2.332031 c 1.132813 1.964844 0.808594 4.429688 -0.796875 6.035156 c -0.390625 0.390625 -0.390625 1.023438 0 1.414063 s 1.023438 0.390625 1.414063 0 c 2.238281 -2.238281 2.695312 -5.710938 1.113281 -8.449219 c -1.1875 -2.054688 -3.304688 -3.324219 -5.578125 -3.480469 c -0.191406 -0.015625 -0.378906 -0.023437 -0.570313 -0.019531 z m 0 0" + fill="#222222" + id="path1" + style="fill:#ffffff;fill-opacity:1" /> +</svg> diff --git a/client/gui/resources/icons/reset.svg.import b/client/gui/resources/icons/reset.svg.import new file mode 100644 index 00000000..16ba79b7 --- /dev/null +++ b/client/gui/resources/icons/reset.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cucnmy0j5n8l8" +path="res://.godot/imported/reset.svg-0004b05ae1181f52f03d82241e998f81.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/reset.svg" +dest_files=["res://.godot/imported/reset.svg-0004b05ae1181f52f03d82241e998f81.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 diff --git a/client/gui/resources/icons/select_directory.svg b/client/gui/resources/icons/select_directory.svg new file mode 100644 index 00000000..d3de2ef5 --- /dev/null +++ b/client/gui/resources/icons/select_directory.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#FFFFFF"><path d="M170.87-183.87q-36.78 0-59.89-24.11t-23.11-58.89v-426.26q0-35.02 23.11-59.01 23.11-23.99 59.89-23.99h209.54L480-676.54h310.13q36.02 0 58.51 24.11 22.49 24.1 24.49 58.89H170.87v327.87l77.04-255.87h694.55l-82.61 272.08q-10.87 31.37-28.06 48.48-17.18 17.11-51.03 17.11H170.87Z"/></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/select_directory.svg.import b/client/gui/resources/icons/select_directory.svg.import new file mode 100644 index 00000000..020fbd97 --- /dev/null +++ b/client/gui/resources/icons/select_directory.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kxer318lo1oj" +path="res://.godot/imported/select_directory.svg-412137f7e6d959d951f8a9fb909150e5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/select_directory.svg" +dest_files=["res://.godot/imported/select_directory.svg-412137f7e6d959d951f8a9fb909150e5.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 diff --git a/client/gui/resources/icons/select_file.svg b/client/gui/resources/icons/select_file.svg new file mode 100644 index 00000000..f44866de --- /dev/null +++ b/client/gui/resources/icons/select_file.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#FFFFFF"><path d="M850-88.11 749.5-188.85v79.37h-83V-330.5h221.02v83h-80.37L907.65-147 850-88.11ZM525.13-634.13h168l-168-168v168ZM266.87-100.87q-34.48 0-58.74-24.26-24.26-24.26-24.26-58.74v-618.26q0-34.48 24.26-58.74 24.26-24.26 58.74-24.26h312.48l196.78 196.78v285.85H594.5v301.63H266.87Z"/></svg>
\ No newline at end of file diff --git a/client/gui/resources/icons/select_file.svg.import b/client/gui/resources/icons/select_file.svg.import new file mode 100644 index 00000000..fe57469a --- /dev/null +++ b/client/gui/resources/icons/select_file.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bsw8vqebvc38c" +path="res://.godot/imported/select_file.svg-c2b2816e900869263e022805bb92f83c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/select_file.svg" +dest_files=["res://.godot/imported/select_file.svg-c2b2816e900869263e022805bb92f83c.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 diff --git a/client/gui/resources/icons/user.webp b/client/gui/resources/icons/user.webp Binary files differnew file mode 100644 index 00000000..5bba0540 --- /dev/null +++ b/client/gui/resources/icons/user.webp diff --git a/client/gui/resources/icons/user.webp.import b/client/gui/resources/icons/user.webp.import new file mode 100644 index 00000000..3a21e21d --- /dev/null +++ b/client/gui/resources/icons/user.webp.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://222w1wha75od" +path="res://.godot/imported/user.webp-0851517d1d18a09719e1adf5c0bc8b2e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/resources/icons/user.webp" +dest_files=["res://.godot/imported/user.webp-0851517d1d18a09719e1adf5c0bc8b2e.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 diff --git a/client/gui/resources/materials/blur_material.tres b/client/gui/resources/materials/blur_material.tres new file mode 100644 index 00000000..a0e9d58c --- /dev/null +++ b/client/gui/resources/materials/blur_material.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://2j8a0c0a2ta5"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_d16rd"] + +[resource] +shader = ExtResource("1_d16rd") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.3 +shader_parameter/mix_amount_no_blur = 0.5 +shader_parameter/color_over = null +shader_parameter/enable_blur = false diff --git a/client/gui/resources/materials/dark_blur_material.tres b/client/gui/resources/materials/dark_blur_material.tres new file mode 100644 index 00000000..96cf1d3f --- /dev/null +++ b/client/gui/resources/materials/dark_blur_material.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://beea1pc5nt67r"] + +[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_cynu0"] + +[resource] +shader = ExtResource("1_cynu0") +shader_parameter/blur_amount = 3.5 +shader_parameter/mix_amount = 0.5 +shader_parameter/mix_amount_no_blur = 0.7 +shader_parameter/color_over = null +shader_parameter/enable_blur = null diff --git a/client/gui/resources/materials/grayscale_material.tres b/client/gui/resources/materials/grayscale_material.tres new file mode 100644 index 00000000..236ad443 --- /dev/null +++ b/client/gui/resources/materials/grayscale_material.tres @@ -0,0 +1,6 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://bplhkekj6rebp"] + +[ext_resource type="Shader" uid="uid://qjrh2imc53u1" path="res://gui/resources/shaders/grayscale.gdshader" id="1_u0c2c"] + +[resource] +shader = ExtResource("1_u0c2c") diff --git a/client/gui/resources/materials/printed_material.tres b/client/gui/resources/materials/printed_material.tres new file mode 100644 index 00000000..3cc4a88c --- /dev/null +++ b/client/gui/resources/materials/printed_material.tres @@ -0,0 +1,6 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://dogdyoqrmy6ft"] + +[ext_resource type="Shader" uid="uid://5p1xlwoc8qe5" path="res://gui/resources/shaders/printed.gdshader" id="1_sevww"] + +[resource] +shader = ExtResource("1_sevww") diff --git a/client/gui/resources/shaders/blur_mix.gdshader b/client/gui/resources/shaders/blur_mix.gdshader new file mode 100644 index 00000000..97686a54 --- /dev/null +++ b/client/gui/resources/shaders/blur_mix.gdshader @@ -0,0 +1,34 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +shader_type canvas_item; + +uniform float blur_amount : hint_range(-2.0, 10.0); +uniform float mix_amount : hint_range(0.0, 1.0); +uniform float mix_amount_no_blur : hint_range(0.0, 1.0); +uniform vec4 color_over: source_color; +uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; +uniform bool enable_blur; + +void fragment() { + if (enable_blur) { + vec4 blurred = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount); + COLOR = mix(blurred, color_over, mix_amount); + } else { + COLOR = mix(texture(SCREEN_TEXTURE, SCREEN_UV), color_over, mix_amount_no_blur); + } +}
\ No newline at end of file diff --git a/client/gui/resources/shaders/blur_mix.gdshader.uid b/client/gui/resources/shaders/blur_mix.gdshader.uid new file mode 100644 index 00000000..7279563b --- /dev/null +++ b/client/gui/resources/shaders/blur_mix.gdshader.uid @@ -0,0 +1 @@ +uid://cwldxegcj55if diff --git a/client/gui/resources/shaders/grayscale.gdshader b/client/gui/resources/shaders/grayscale.gdshader new file mode 100644 index 00000000..c058e7bf --- /dev/null +++ b/client/gui/resources/shaders/grayscale.gdshader @@ -0,0 +1,25 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +shader_type canvas_item; + +void fragment() { + float brightness = 0.2126 * COLOR.r + 0.7152 * COLOR.g + 0.0722 * COLOR.b; + brightness = (brightness - .5) * 2.; + COLOR.rgb = vec3(brightness); + COLOR.a *= 1. - brightness; +} diff --git a/client/gui/resources/shaders/grayscale.gdshader.uid b/client/gui/resources/shaders/grayscale.gdshader.uid new file mode 100644 index 00000000..b721a6e0 --- /dev/null +++ b/client/gui/resources/shaders/grayscale.gdshader.uid @@ -0,0 +1 @@ +uid://qjrh2imc53u1 diff --git a/client/gui/resources/shaders/paper.tres b/client/gui/resources/shaders/paper.tres new file mode 100644 index 00000000..2c681244 --- /dev/null +++ b/client/gui/resources/shaders/paper.tres @@ -0,0 +1,14 @@ +[gd_resource type="NoiseTexture2D" load_steps=3 format=3 uid="uid://chxkwohi56cxx"] + +[sub_resource type="Gradient" id="Gradient_pkrjd"] +colors = PackedColorArray(0.917969, 0.866454, 0.770122, 1, 0.832031, 0.781817, 0.666307, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_k7p6k"] +noise_type = 0 +frequency = 0.0084 +domain_warp_enabled = true +domain_warp_frequency = -1.465 + +[resource] +color_ramp = SubResource("Gradient_pkrjd") +noise = SubResource("FastNoiseLite_k7p6k") diff --git a/client/gui/resources/shaders/printed.gdshader b/client/gui/resources/shaders/printed.gdshader new file mode 100644 index 00000000..c24cb679 --- /dev/null +++ b/client/gui/resources/shaders/printed.gdshader @@ -0,0 +1,22 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +shader_type canvas_item; + +void fragment() { + COLOR = floor(COLOR*5.)/5.; +} diff --git a/client/gui/resources/shaders/printed.gdshader.uid b/client/gui/resources/shaders/printed.gdshader.uid new file mode 100644 index 00000000..7c5fe12e --- /dev/null +++ b/client/gui/resources/shaders/printed.gdshader.uid @@ -0,0 +1 @@ +uid://5p1xlwoc8qe5 diff --git a/client/gui/resources/sounds/click.ogg b/client/gui/resources/sounds/click.ogg Binary files differnew file mode 100644 index 00000000..db4aaf4e --- /dev/null +++ b/client/gui/resources/sounds/click.ogg diff --git a/client/gui/resources/sounds/click.ogg.import b/client/gui/resources/sounds/click.ogg.import new file mode 100644 index 00000000..4c4604ec --- /dev/null +++ b/client/gui/resources/sounds/click.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cpyn511c5mtni" +path="res://.godot/imported/click.ogg-ec24cb35b5d300c7ddbb1f50c2522ac5.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/click.ogg" +dest_files=["res://.godot/imported/click.ogg-ec24cb35b5d300c7ddbb1f50c2522ac5.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/failure.ogg b/client/gui/resources/sounds/failure.ogg Binary files differnew file mode 100644 index 00000000..ef6d6ea4 --- /dev/null +++ b/client/gui/resources/sounds/failure.ogg diff --git a/client/gui/resources/sounds/failure.ogg.import b/client/gui/resources/sounds/failure.ogg.import new file mode 100644 index 00000000..495c1d96 --- /dev/null +++ b/client/gui/resources/sounds/failure.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cv4isy6po6pqd" +path="res://.godot/imported/failure.ogg-cf79159cd8bc7c6cb1fc08dc9f16fc65.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/failure.ogg" +dest_files=["res://.godot/imported/failure.ogg-cf79159cd8bc7c6cb1fc08dc9f16fc65.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/game_start.ogg b/client/gui/resources/sounds/game_start.ogg Binary files differnew file mode 100644 index 00000000..3282ff99 --- /dev/null +++ b/client/gui/resources/sounds/game_start.ogg diff --git a/client/gui/resources/sounds/game_start.ogg.import b/client/gui/resources/sounds/game_start.ogg.import new file mode 100644 index 00000000..79e28ada --- /dev/null +++ b/client/gui/resources/sounds/game_start.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://dft3m8utnxhs7" +path="res://.godot/imported/game_start.ogg-94857aa980bf125ce248d75f3d2a8bc2.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/game_start.ogg" +dest_files=["res://.godot/imported/game_start.ogg-94857aa980bf125ce248d75f3d2a8bc2.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/hover.ogg b/client/gui/resources/sounds/hover.ogg Binary files differnew file mode 100644 index 00000000..17d414ca --- /dev/null +++ b/client/gui/resources/sounds/hover.ogg diff --git a/client/gui/resources/sounds/hover.ogg.import b/client/gui/resources/sounds/hover.ogg.import new file mode 100644 index 00000000..0bb47b0d --- /dev/null +++ b/client/gui/resources/sounds/hover.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://dtr1khfyqr56o" +path="res://.godot/imported/hover.ogg-604c32500c7d24a64b5d68b6146e31cc.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/hover.ogg" +dest_files=["res://.godot/imported/hover.ogg-604c32500c7d24a64b5d68b6146e31cc.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/page.ogg b/client/gui/resources/sounds/page.ogg Binary files differnew file mode 100644 index 00000000..3038a8d9 --- /dev/null +++ b/client/gui/resources/sounds/page.ogg diff --git a/client/gui/resources/sounds/page.ogg.import b/client/gui/resources/sounds/page.ogg.import new file mode 100644 index 00000000..9c65dc93 --- /dev/null +++ b/client/gui/resources/sounds/page.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://do7ii5hx71p0m" +path="res://.godot/imported/page.ogg-0b33370bdbe86f4cddfd8a42d8f62a5d.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/page.ogg" +dest_files=["res://.godot/imported/page.ogg-0b33370bdbe86f4cddfd8a42d8f62a5d.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/sign.ogg b/client/gui/resources/sounds/sign.ogg Binary files differnew file mode 100644 index 00000000..8811c50a --- /dev/null +++ b/client/gui/resources/sounds/sign.ogg diff --git a/client/gui/resources/sounds/sign.ogg.import b/client/gui/resources/sounds/sign.ogg.import new file mode 100644 index 00000000..8e524403 --- /dev/null +++ b/client/gui/resources/sounds/sign.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://5b3noxjmasmu" +path="res://.godot/imported/sign.ogg-9091117f7048611453ca1b0853de53ea.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/sign.ogg" +dest_files=["res://.godot/imported/sign.ogg-9091117f7048611453ca1b0853de53ea.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/sounds/success.ogg b/client/gui/resources/sounds/success.ogg Binary files differnew file mode 100644 index 00000000..37cd2bcd --- /dev/null +++ b/client/gui/resources/sounds/success.ogg diff --git a/client/gui/resources/sounds/success.ogg.import b/client/gui/resources/sounds/success.ogg.import new file mode 100644 index 00000000..1c42b2e5 --- /dev/null +++ b/client/gui/resources/sounds/success.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://camy77x26mmpv" +path="res://.godot/imported/success.ogg-d726a1955ea1a9943ae576d6eb7645bb.oggvorbisstr" + +[deps] + +source_file="res://gui/resources/sounds/success.ogg" +dest_files=["res://.godot/imported/success.ogg-d726a1955ea1a9943ae576d6eb7645bb.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/client/gui/resources/style/error_focus_style.tres b/client/gui/resources/style/error_focus_style.tres new file mode 100644 index 00000000..f7c44505 --- /dev/null +++ b/client/gui/resources/style/error_focus_style.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://devnduinj535f"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 0, 0, 0.12549) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(1, 0.81804, 0.818076, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/focus_style.tres b/client/gui/resources/style/focus_style.tres new file mode 100644 index 00000000..a01843fe --- /dev/null +++ b/client/gui/resources/style/focus_style.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://b86kbd3pfkd5w"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0627451) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.818673, 0.926505, 1, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/hover_style.tres b/client/gui/resources/style/hover_style.tres new file mode 100644 index 00000000..963ee2ca --- /dev/null +++ b/client/gui/resources/style/hover_style.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://dua4jqje3704w"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.266667) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/item_bubble_progress_style.tres b/client/gui/resources/style/item_bubble_progress_style.tres new file mode 100644 index 00000000..68054918 --- /dev/null +++ b/client/gui/resources/style/item_bubble_progress_style.tres @@ -0,0 +1,5 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://brw8uogdgx2gf"] + +[resource] +resource_local_to_scene = true +bg_color = Color(0.501961, 0, 0, 1) diff --git a/client/gui/resources/style/item_bubble_progress_style_background.tres b/client/gui/resources/style/item_bubble_progress_style_background.tres new file mode 100644 index 00000000..972b7055 --- /dev/null +++ b/client/gui/resources/style/item_bubble_progress_style_background.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://cu0his4018e7h"] + +[resource] +resource_local_to_scene = true diff --git a/client/gui/resources/style/lobby_panel_override.tres b/client/gui/resources/style/lobby_panel_override.tres new file mode 100644 index 00000000..04fd16b0 --- /dev/null +++ b/client/gui/resources/style/lobby_panel_override.tres @@ -0,0 +1,4 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://de80aw86emnql"] + +[resource] +bg_color = Color(0.0941176, 0.0941176, 0.0941176, 1) diff --git a/client/gui/resources/style/normal_style.tres b/client/gui/resources/style/normal_style.tres new file mode 100644 index 00000000..96aecc8e --- /dev/null +++ b/client/gui/resources/style/normal_style.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://pi5uhe0lrgka"] + +[resource] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0352941) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 diff --git a/client/gui/resources/style/panel_style.tres b/client/gui/resources/style/panel_style.tres new file mode 100644 index 00000000..d1f27667 --- /dev/null +++ b/client/gui/resources/style/panel_style.tres @@ -0,0 +1,8 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bcd4xcvtv7tws"] + +[resource] +bg_color = Color(0, 0, 0, 0.6) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/client/gui/resources/style/panel_style_sidebar.tres b/client/gui/resources/style/panel_style_sidebar.tres new file mode 100644 index 00000000..9615d88b --- /dev/null +++ b/client/gui/resources/style/panel_style_sidebar.tres @@ -0,0 +1,3 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bw4jamyna1top"] + +[resource] diff --git a/client/gui/resources/style/paper_panel_style.tres b/client/gui/resources/style/paper_panel_style.tres new file mode 100644 index 00000000..effa2310 --- /dev/null +++ b/client/gui/resources/style/paper_panel_style.tres @@ -0,0 +1,6 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=3 uid="uid://bqhs5wtdp2oax"] + +[ext_resource type="Texture2D" uid="uid://chxkwohi56cxx" path="res://gui/resources/shaders/paper.tres" id="1_u1kqj"] + +[resource] +texture = ExtResource("1_u1kqj") diff --git a/client/gui/resources/theme/paper.tres b/client/gui/resources/theme/paper.tres new file mode 100644 index 00000000..41417f39 --- /dev/null +++ b/client/gui/resources/theme/paper.tres @@ -0,0 +1,109 @@ +[gd_resource type="Theme" load_steps=17 format=3 uid="uid://ci2qajdoa1an1"] + +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="1_koj1m"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="1_tc8bk"] + +[sub_resource type="FontVariation" id="FontVariation_pirkj"] +base_font = ExtResource("1_tc8bk") +variation_embolden = 0.5 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l5fao"] +bg_color = Color(0, 0, 0, 0.305882) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.819608, 0.92549, 1, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3p3im"] +bg_color = Color(0, 0, 0, 0.145098) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xxmhf"] +bg_color = Color(0, 0, 0, 0.305882) + +[sub_resource type="SystemFont" id="SystemFont_3j83h"] +font_names = PackedStringArray("Noto Sans") + +[sub_resource type="FontVariation" id="FontVariation_8qr07"] +base_font = SubResource("SystemFont_3j83h") +variation_embolden = -0.44 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rq65v"] +content_margin_left = 10.0 +bg_color = Color(1, 1, 1, 0) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_st08c"] +content_margin_left = 10.0 +bg_color = Color(0, 0, 0, 0) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.300781, 0.300781, 0.300781, 1) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_8q7ob"] +thickness = 3 + +[sub_resource type="FontVariation" id="FontVariation_cx2xx"] +base_font = ExtResource("1_koj1m") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_huhkg"] +content_margin_left = 10.0 +bg_color = Color(0.6, 0.6, 0.6, 0) +border_width_bottom = 2 +border_color = Color(0, 0, 0, 1) + +[sub_resource type="SystemFont" id="SystemFont_c2823"] + +[sub_resource type="FontVariation" id="FontVariation_c3ws0"] +base_font = SubResource("SystemFont_c2823") +variation_embolden = 0.53 + +[sub_resource type="FontVariation" id="FontVariation_ex8wc"] +base_font = SubResource("SystemFont_3j83h") +variation_embolden = -0.44 + +[resource] +Button/colors/font_color = Color(0.21875, 0.21875, 0.21875, 1) +Button/fonts/font = SubResource("FontVariation_pirkj") +Button/styles/focus = SubResource("StyleBoxFlat_l5fao") +Button/styles/hover = SubResource("StyleBoxFlat_3p3im") +Button/styles/normal = SubResource("StyleBoxFlat_xxmhf") +Button/styles/pressed = SubResource("StyleBoxFlat_xxmhf") +CheckBox/colors/font_color = Color(0, 0, 0, 1) +CheckBox/colors/font_disabled_color = Color(0, 0, 0, 1) +CheckBox/colors/font_focus_color = Color(0, 0, 0, 1) +CheckBox/colors/font_hover_color = Color(0, 0, 0, 1) +CheckBox/colors/font_hover_pressed_color = Color(0, 0, 0, 1) +CheckBox/colors/font_pressed_color = Color(0, 0, 0, 1) +CheckBox/constants/h_separation = 4 +CheckBox/fonts/font = SubResource("FontVariation_8qr07") +CheckBox/styles/disabled = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/focus = SubResource("StyleBoxFlat_st08c") +CheckBox/styles/hover = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/hover_pressed = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/normal = SubResource("StyleBoxFlat_rq65v") +CheckBox/styles/pressed = SubResource("StyleBoxFlat_rq65v") +HSeparator/constants/separation = 6 +HSeparator/styles/separator = SubResource("StyleBoxLine_8q7ob") +Label/colors/font_color = Color(0, 0, 0, 1) +LineEdit/colors/caret_color = Color(0, 0.0209808, 0.414062, 1) +LineEdit/colors/font_color = Color(0, 0.0196078, 0.415686, 1) +LineEdit/fonts/font = SubResource("FontVariation_cx2xx") +LineEdit/styles/focus = SubResource("StyleBoxFlat_huhkg") +LineEdit/styles/normal = SubResource("StyleBoxFlat_huhkg") +LineEdit/styles/read_only = SubResource("StyleBoxFlat_huhkg") +MarginContainer/constants/margin_bottom = 30 +MarginContainer/constants/margin_left = 70 +MarginContainer/constants/margin_right = 30 +MarginContainer/constants/margin_top = 30 +RichTextLabel/colors/default_color = Color(0, 0, 0, 1) +RichTextLabel/fonts/bold_font = SubResource("FontVariation_c3ws0") +RichTextLabel/fonts/bold_italics_font = null +RichTextLabel/fonts/italics_font = null +RichTextLabel/fonts/mono_font = null +RichTextLabel/fonts/normal_font = SubResource("FontVariation_ex8wc") diff --git a/client/gui/resources/theme/theme.tres b/client/gui/resources/theme/theme.tres new file mode 100644 index 00000000..ca87a81c --- /dev/null +++ b/client/gui/resources/theme/theme.tres @@ -0,0 +1,70 @@ +[gd_resource type="Theme" load_steps=12 format=3 uid="uid://b0qmvo504e457"] + +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://gui/resources/fonts/font-josefin-sans.woff2" id="1_f8qb0"] +[ext_resource type="StyleBox" uid="uid://b86kbd3pfkd5w" path="res://gui/resources/style/focus_style.tres" id="1_x88rs"] +[ext_resource type="StyleBox" uid="uid://pi5uhe0lrgka" path="res://gui/resources/style/normal_style.tres" id="2_8fwoi"] +[ext_resource type="StyleBox" uid="uid://dua4jqje3704w" path="res://gui/resources/style/hover_style.tres" id="2_ye28t"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="3_8u6ww"] +[ext_resource type="StyleBox" uid="uid://bcd4xcvtv7tws" path="res://gui/resources/style/panel_style.tres" id="4_42dlp"] + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_emtvk"] +content_margin_top = 5.0 +content_margin_bottom = 5.0 +color = Color(1, 1, 1, 1) +grow_begin = 0.0 +grow_end = 0.0 +thickness = 3 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_25x32"] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(1, 1, 1, 0.0352941) +corner_radius_top_left = 5 +corner_radius_top_right = 5 +corner_radius_bottom_right = 5 +corner_radius_bottom_left = 5 + +[sub_resource type="FontVariation" id="FontVariation_ff4nr"] +base_font = ExtResource("3_8u6ww") +variation_embolden = 0.7 + +[sub_resource type="FontVariation" id="FontVariation_lyo8w"] +base_font = ExtResource("1_f8qb0") +variation_embolden = 1.25 +spacing_top = 5 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_or5ri"] + +[resource] +default_font = SubResource("FontVariation_lyo8w") +Button/font_sizes/font_size = 18 +Button/styles/disabled = ExtResource("2_8fwoi") +Button/styles/focus = ExtResource("1_x88rs") +Button/styles/hover = ExtResource("2_ye28t") +Button/styles/normal = ExtResource("2_8fwoi") +Button/styles/pressed = ExtResource("2_8fwoi") +CheckButton/font_sizes/font_size = 18 +CheckButton/styles/disabled = ExtResource("2_8fwoi") +CheckButton/styles/focus = ExtResource("1_x88rs") +CheckButton/styles/hover = ExtResource("2_ye28t") +CheckButton/styles/hover_pressed = ExtResource("2_ye28t") +CheckButton/styles/normal = ExtResource("2_8fwoi") +CheckButton/styles/pressed = ExtResource("2_8fwoi") +HSeparator/styles/separator = SubResource("StyleBoxLine_emtvk") +Label/font_sizes/font_size = 16 +LineEdit/styles/focus = ExtResource("1_x88rs") +LineEdit/styles/normal = SubResource("StyleBoxFlat_25x32") +LineEdit/styles/read_only = SubResource("StyleBoxFlat_25x32") +MarginContainer/constants/margin_bottom = 32 +MarginContainer/constants/margin_left = 32 +MarginContainer/constants/margin_right = 32 +MarginContainer/constants/margin_top = 32 +Panel/styles/panel = ExtResource("4_42dlp") +PanelContainer/styles/panel = ExtResource("4_42dlp") +RichTextLabel/fonts/bold_font = SubResource("FontVariation_ff4nr") +RichTextLabel/fonts/bold_italics_font = SubResource("FontVariation_lyo8w") +RichTextLabel/fonts/italics_font = SubResource("FontVariation_lyo8w") +RichTextLabel/fonts/mono_font = SubResource("FontVariation_lyo8w") +TabContainer/styles/panel = SubResource("StyleBoxEmpty_or5ri") |