From c1e826625f3ca3116d482b27e2f0b230cbd55346 Mon Sep 17 00:00:00 2001 From: tpart Date: Mon, 29 Sep 2025 22:50:44 +0200 Subject: Add new controls explanation (Closes #427) --- client/game.gd | 7 + client/gui/menus/main/about.gd | 6 +- client/gui/menus/menu.gd | 2 +- .../gui/overlays/controls_visualization/arrow.svg | 9 + .../controls_visualization/arrow.svg.import | 43 +++ .../controller/controller.svg | 309 +++++++++++++++++++++ .../controller/controller.svg.import | 43 +++ .../controller/controller_explanation.gd | 45 +++ .../controller/controller_explanation.gd.uid | 1 + .../controller/controller_explanation.tscn | 126 +++++++++ .../controls_visualization/device_explanation.gd | 20 ++ .../device_explanation.gd.uid | 1 + .../overlays/controls_visualization/explanation.gd | 39 +++ .../controls_visualization/explanation.gd.uid | 1 + .../controls_visualization/explanation.tscn | 68 +++++ .../keyboard/keyboard_button.tscn | 33 +++ .../keyboard/keyboard_explanation.gd | 46 +++ .../keyboard/keyboard_explanation.gd.uid | 1 + .../keyboard/keyboard_explanation.tscn | 249 +++++++++++++++++ .../gui/resources/fonts/sansita-swashed-bold.tres | 9 + client/multiplayer.gd | 5 + client/system/profile.gd | 4 +- locale/en.ini | 34 ++- 23 files changed, 1084 insertions(+), 17 deletions(-) create mode 100644 client/gui/overlays/controls_visualization/arrow.svg create mode 100644 client/gui/overlays/controls_visualization/arrow.svg.import create mode 100644 client/gui/overlays/controls_visualization/controller/controller.svg create mode 100644 client/gui/overlays/controls_visualization/controller/controller.svg.import create mode 100644 client/gui/overlays/controls_visualization/controller/controller_explanation.gd create mode 100644 client/gui/overlays/controls_visualization/controller/controller_explanation.gd.uid create mode 100644 client/gui/overlays/controls_visualization/controller/controller_explanation.tscn create mode 100644 client/gui/overlays/controls_visualization/device_explanation.gd create mode 100644 client/gui/overlays/controls_visualization/device_explanation.gd.uid create mode 100644 client/gui/overlays/controls_visualization/explanation.gd create mode 100644 client/gui/overlays/controls_visualization/explanation.gd.uid create mode 100644 client/gui/overlays/controls_visualization/explanation.tscn create mode 100644 client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn create mode 100644 client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd create mode 100644 client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd.uid create mode 100644 client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn create mode 100644 client/gui/resources/fonts/sansita-swashed-bold.tres diff --git a/client/game.gd b/client/game.gd index 89a68be5..efb75c9f 100644 --- a/client/game.gd +++ b/client/game.gd @@ -299,6 +299,13 @@ func handle_packet(p): toggle_join() elif not is_replay: menu.submenu("res://gui/menus/ingame.tscn") + elif not in_lobby and not is_replay and not Global.using_touch and p.state: + if Global.hand_count == 1 and not Profile.read("controls_one_handed_explained"): + menu.submenu("res://gui/overlays/controls_visualization/explanation.tscn", false) + elif Global.hand_count == 2 and not Profile.read("controls_two_handed_explained"): + menu.submenu("res://gui/overlays/controls_visualization/explanation.tscn", true) + else: + mp.send_ready() "score": if p.time_remaining != null: overlay_score.update(p.demands_failed, p.demands_completed, p.points, p.time_remaining) diff --git a/client/gui/menus/main/about.gd b/client/gui/menus/main/about.gd index 56887203..95f98d30 100644 --- a/client/gui/menus/main/about.gd +++ b/client/gui/menus/main/about.gd @@ -61,6 +61,10 @@ var credits := [ ["Dillon Becker", "Super Dialogue Audio Pack V1", cc_by_4], ["Ekrcoaster", "Water steaming on hot surface #2", cc0] ]], + [tr("c.credits.other"), [ + ["Ray Trace", "Nintendo_Switch_Pro_Controller.svg", cc_by_4], + ["Amousey", "Curved solid arrow.svg", cc0] + ]], [tr("c.credits.translations"), { tr("c.settings.ui.language.zh_Hans"): ["Outbreak2096"], tr("c.settings.ui.language.zh_Hant"): ["hugoalh"], @@ -117,7 +121,7 @@ func credits_text() -> String: func legal_text() -> String: var all: Array[String] = [] var translators: Array[String] = [] - for c in credits[2][1].values(): + for c in credits[3][1].values(): translators.append_array(c) translators.shuffle() authors.shuffle() diff --git a/client/gui/menus/menu.gd b/client/gui/menus/menu.gd index e1dc8929..e0d5472a 100644 --- a/client/gui/menus/menu.gd +++ b/client/gui/menus/menu.gd @@ -109,7 +109,7 @@ 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"): + if (node is Button and not node.focus_mode == FocusMode.FOCUS_NONE) or node.is_in_group("autoselect"): node.grab_focus() # print("Node %s (%s) was selected for focus" % [node.name, node]) return true diff --git a/client/gui/overlays/controls_visualization/arrow.svg b/client/gui/overlays/controls_visualization/arrow.svg new file mode 100644 index 00000000..d4fda2c4 --- /dev/null +++ b/client/gui/overlays/controls_visualization/arrow.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/client/gui/overlays/controls_visualization/arrow.svg.import b/client/gui/overlays/controls_visualization/arrow.svg.import new file mode 100644 index 00000000..3d0a0c76 --- /dev/null +++ b/client/gui/overlays/controls_visualization/arrow.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cf8hrxilqe2ih" +path="res://.godot/imported/arrow.svg-94e1ee2c28cf422e8623ba865fb0f77b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/overlays/controls_visualization/arrow.svg" +dest_files=["res://.godot/imported/arrow.svg-94e1ee2c28cf422e8623ba865fb0f77b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/overlays/controls_visualization/controller/controller.svg b/client/gui/overlays/controls_visualization/controller/controller.svg new file mode 100644 index 00000000..ad616301 --- /dev/null +++ b/client/gui/overlays/controls_visualization/controller/controller.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/gui/overlays/controls_visualization/controller/controller.svg.import b/client/gui/overlays/controls_visualization/controller/controller.svg.import new file mode 100644 index 00000000..79a6e2d7 --- /dev/null +++ b/client/gui/overlays/controls_visualization/controller/controller.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doo07i13vtb34" +path="res://.godot/imported/controller.svg-cfc5787dc7bf7b1a87918dcfd10423cd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://gui/overlays/controls_visualization/controller/controller.svg" +dest_files=["res://.godot/imported/controller.svg-cfc5787dc7bf7b1a87918dcfd10423cd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/overlays/controls_visualization/controller/controller_explanation.gd b/client/gui/overlays/controls_visualization/controller/controller_explanation.gd new file mode 100644 index 00000000..84e93cfa --- /dev/null +++ b/client/gui/overlays/controls_visualization/controller/controller_explanation.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 . +# +class_name ControllerExplanation +extends DeviceExplanation + +const MODULATE_SPEED := 5. + +var double_handed := false + +@onready var left_hand: Node2D = $Control/Node2D/InteractLeft +@onready var right_hand: Node2D = $Control/Node2D/InteractRight + +@onready var left_arrow: Sprite2D = $Control/Node2D/Arrow4 + +@onready var interact_right_label: Label = $Control/Node2D/InteractRight/Label + +func toggle_double_handed(val: bool) -> void: + double_handed = val + left_hand.visible = val + left_arrow.visible = val + interact_right_label.text = tr("c.controls_explanation.interact_right") if val else tr("c.settings.input.interact") + +var t := 0. +func _process(delta: float) -> void: + if not double_handed: return + + t += delta + var weight: float = (cos(t * MODULATE_SPEED) - 1.) * -0.5 + for i: Node2D in [left_hand,right_hand]: + i.modulate = Color.WHITE.lerp(Color("ffcd59ff"), weight) + var size_ := lerpf(1, 1.2, weight) + i.scale = Vector2(size_, size_) diff --git a/client/gui/overlays/controls_visualization/controller/controller_explanation.gd.uid b/client/gui/overlays/controls_visualization/controller/controller_explanation.gd.uid new file mode 100644 index 00000000..5bdb1e6c --- /dev/null +++ b/client/gui/overlays/controls_visualization/controller/controller_explanation.gd.uid @@ -0,0 +1 @@ +uid://dsg537e6dc68 diff --git a/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn b/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn new file mode 100644 index 00000000..410f2592 --- /dev/null +++ b/client/gui/overlays/controls_visualization/controller/controller_explanation.tscn @@ -0,0 +1,126 @@ +[gd_scene load_steps=5 format=3 uid="uid://ceex0cpjrb81p"] + +[ext_resource type="Script" uid="uid://dsg537e6dc68" path="res://gui/overlays/controls_visualization/controller/controller_explanation.gd" id="1_n0s1n"] +[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="2_ewgm4"] +[ext_resource type="Texture2D" uid="uid://cf8hrxilqe2ih" path="res://gui/overlays/controls_visualization/arrow.svg" id="3_565r1"] +[ext_resource type="Texture2D" uid="uid://doo07i13vtb34" path="res://gui/overlays/controls_visualization/controller/controller.svg" id="5_nalwd"] + +[node name="ControllerExplanation" type="Control"] +custom_minimum_size = Vector2(0, 450) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_bottom = -270.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_n0s1n") + +[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="Node2D" type="Node2D" parent="Control"] +position = Vector2(0, 50) + +[node name="Controller" type="Sprite2D" parent="Control/Node2D"] +scale = Vector2(0.4, 0.4) +texture = ExtResource("5_nalwd") + +[node name="Arrow" type="Sprite2D" parent="Control/Node2D"] +position = Vector2(-250, -150) +rotation = 1.5707964 +scale = Vector2(0.5, 0.5) +texture = ExtResource("3_565r1") + +[node name="Arrow4" type="Sprite2D" parent="Control/Node2D"] +position = Vector2(45, -150) +scale = Vector2(0.5, -0.5) +texture = ExtResource("3_565r1") + +[node name="Arrow2" type="Sprite2D" parent="Control/Node2D"] +position = Vector2(260, -140) +rotation = 1.5707963 +scale = Vector2(0.5, -0.5) +texture = ExtResource("3_565r1") + +[node name="Arrow3" type="Sprite2D" parent="Control/Node2D"] +position = Vector2(215, 20) +rotation = -1.5707964 +scale = Vector2(0.5, 0.5) +texture = ExtResource("3_565r1") + +[node name="Move" type="Node2D" parent="Control/Node2D"] +position = Vector2(-330, -175) + +[node name="Label" type="Label" parent="Control/Node2D/Move"] +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = -549.0 +offset_top = -24.5 +offset_bottom = 24.5 +grow_horizontal = 0 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("2_ewgm4") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.move" +horizontal_alignment = 2 + +[node name="Boost" type="Node2D" parent="Control/Node2D"] +position = Vector2(335, -165) + +[node name="Label" type="Label" parent="Control/Node2D/Boost"] +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_top = -24.5 +offset_right = 549.0 +offset_bottom = 24.5 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("2_ewgm4") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.boost" + +[node name="InteractRight" type="Node2D" parent="Control/Node2D"] +position = Vector2(290, 25) + +[node name="Label" type="Label" parent="Control/Node2D/InteractRight"] +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_top = -24.5 +offset_right = 549.0 +offset_bottom = 24.5 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("2_ewgm4") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.interact_right" + +[node name="InteractLeft" type="Node2D" parent="Control/Node2D"] +position = Vector2(20, -250) + +[node name="Label" type="Label" parent="Control/Node2D/InteractLeft"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -274.5 +offset_top = -24.5 +offset_right = 274.5 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("2_ewgm4") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.interact_left" +horizontal_alignment = 1 diff --git a/client/gui/overlays/controls_visualization/device_explanation.gd b/client/gui/overlays/controls_visualization/device_explanation.gd new file mode 100644 index 00000000..7bfe2fb4 --- /dev/null +++ b/client/gui/overlays/controls_visualization/device_explanation.gd @@ -0,0 +1,20 @@ +# 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 . +# +@abstract +class_name DeviceExplanation +extends Control + +@abstract func toggle_double_handed(val: bool) -> void diff --git a/client/gui/overlays/controls_visualization/device_explanation.gd.uid b/client/gui/overlays/controls_visualization/device_explanation.gd.uid new file mode 100644 index 00000000..86ec5a25 --- /dev/null +++ b/client/gui/overlays/controls_visualization/device_explanation.gd.uid @@ -0,0 +1 @@ +uid://bh5s8l2cjnarb diff --git a/client/gui/overlays/controls_visualization/explanation.gd b/client/gui/overlays/controls_visualization/explanation.gd new file mode 100644 index 00000000..47716a42 --- /dev/null +++ b/client/gui/overlays/controls_visualization/explanation.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 . +# +extends Menu +class_name ControlsExplanation + +var two_handed: bool + +@onready var game: Game = $"../Game" + +@onready var title: Label = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/Title +@onready var keyboard_explanation: KeyboardExplanation = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/KeyboardExplanation +@onready var controller_explanation: ControllerExplanation = $MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/ControllerExplanation + +func _ready(): + two_handed = data + @warning_ignore("incompatible_ternary") + var explanation: DeviceExplanation = controller_explanation if Global.using_joypad else keyboard_explanation + explanation.visible = true + explanation.toggle_double_handed(two_handed) + title.text = tr("c.controls_explanation.two_handed") if two_handed else tr("c.settings.input") + super() + +func _on_accept_pressed() -> void: + Profile.write("controls_" + ("two" if two_handed else "one") + "_handed_explained", true) + game.mp.send_ready() + exit() diff --git a/client/gui/overlays/controls_visualization/explanation.gd.uid b/client/gui/overlays/controls_visualization/explanation.gd.uid new file mode 100644 index 00000000..4c10943d --- /dev/null +++ b/client/gui/overlays/controls_visualization/explanation.gd.uid @@ -0,0 +1 @@ +uid://bs2xryd5vamjf diff --git a/client/gui/overlays/controls_visualization/explanation.tscn b/client/gui/overlays/controls_visualization/explanation.tscn new file mode 100644 index 00000000..e102fa85 --- /dev/null +++ b/client/gui/overlays/controls_visualization/explanation.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=8 format=3 uid="uid://c7g5gpiyofmu8"] + +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://gui/resources/theme/theme.tres" id="1_81hfk"] +[ext_resource type="Script" uid="uid://bs2xryd5vamjf" path="res://gui/overlays/controls_visualization/explanation.gd" id="2_lxysr"] +[ext_resource type="Script" uid="uid://byshs20og68tn" path="res://gui/components/smart_margin_container.gd" id="2_m528b"] +[ext_resource type="Material" uid="uid://beea1pc5nt67r" path="res://gui/resources/materials/dark_blur_material.tres" id="3_pomap"] +[ext_resource type="Script" uid="uid://cmncjc06kadpe" path="res://gui/components/blur_setup.gd" id="4_v3ijr"] +[ext_resource type="PackedScene" uid="uid://wwj1ow1f437s" path="res://gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn" id="5_v3ijr"] +[ext_resource type="PackedScene" uid="uid://ceex0cpjrb81p" path="res://gui/overlays/controls_visualization/controller/controller_explanation.tscn" id="7_yuxcv"] + +[node name="Explanation" 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_81hfk") +script = ExtResource("2_lxysr") +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("2_m528b") +metadata/_custom_type_script = "uid://byshs20og68tn" + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"] +material = ExtResource("3_pomap") +layout_mode = 2 +script = ExtResource("4_v3ijr") + +[node name="SmartMarginContainer" type="MarginContainer" parent="MarginContainer/PanelContainer"] +layout_mode = 2 +script = ExtResource("2_m528b") +metadata/_custom_type_script = "uid://byshs20og68tn" + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/SmartMarginContainer"] +layout_mode = 2 + +[node name="Title" type="Label" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_font_sizes/font_size = 36 +text = "c.settings.input" +horizontal_alignment = 1 + +[node name="KeyboardExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" instance=ExtResource("5_v3ijr")] +visible = false +layout_mode = 2 + +[node name="ControllerExplanation" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer" instance=ExtResource("7_yuxcv")] +visible = false +layout_mode = 2 + +[node name="Spacer" type="Control" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Accept" type="Button" parent="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "c.menu.accept" + +[connection signal="pressed" from="MarginContainer/PanelContainer/SmartMarginContainer/VBoxContainer/Accept" to="." method="_on_accept_pressed"] diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn b/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn new file mode 100644 index 00000000..e4462464 --- /dev/null +++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_button.tscn @@ -0,0 +1,33 @@ +[gd_scene load_steps=2 format=3 uid="uid://dj7tqrgpdja42"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ilwpo"] +content_margin_left = 5.0 +content_margin_top = 5.0 +content_margin_right = 5.0 +content_margin_bottom = 5.0 +bg_color = Color(0.9, 0.9, 0.9, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0.15, 0.15, 0.15, 1) +corner_radius_top_left = 15 +corner_radius_top_right = 15 +corner_radius_bottom_right = 15 +corner_radius_bottom_left = 15 +shadow_size = 3 + +[node name="KeyboardButton" type="Button"] +custom_minimum_size = Vector2(75, 75) +offset_right = 8.0 +offset_bottom = 8.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_colors/font_disabled_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 36 +theme_override_styles/normal = SubResource("StyleBoxFlat_ilwpo") +theme_override_styles/disabled = SubResource("StyleBoxFlat_ilwpo") +disabled = true +text = "A" diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd new file mode 100644 index 00000000..5d6dfb42 --- /dev/null +++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.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 . +# +class_name KeyboardExplanation +extends DeviceExplanation + +const MODULATE_SPEED := 5. + +var double_handed := false + +@onready var j: Node2D = $VBoxContainer/Control2/JKL/J +@onready var l: Node2D = $VBoxContainer/Control2/JKL/L + +@onready var left_hand_label: Label = $VBoxContainer/Control2/JKL/LeftHand/Label +@onready var right_hand: Node2D = $VBoxContainer/Control2/JKL/RightHand +@onready var right_arrow: Sprite2D = $VBoxContainer/Control2/JKL/Sprite2D2 + +func toggle_double_handed(val: bool) -> void: + double_handed = val + right_hand.visible = val + right_arrow.visible = val + l.visible = val + left_hand_label.text = tr("c.controls_explanation.interact_left") if val else tr("c.settings.input.interact") + +var t := 0. +func _process(delta: float) -> void: + if not double_handed: return + + t += delta + var weight: float = (cos(t * MODULATE_SPEED) - 1.) * -0.5 + for i: Node2D in [j,l]: + i.modulate = Color.WHITE.lerp(Color("ffcd59ff"), weight) + var size_ := lerpf(1, 1.2, weight) + i.scale = Vector2(size_, size_) diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd.uid b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd.uid new file mode 100644 index 00000000..0d383385 --- /dev/null +++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd.uid @@ -0,0 +1 @@ +uid://dekpmw0i03eyi diff --git a/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn new file mode 100644 index 00000000..54001686 --- /dev/null +++ b/client/gui/overlays/controls_visualization/keyboard/keyboard_explanation.tscn @@ -0,0 +1,249 @@ +[gd_scene load_steps=5 format=3 uid="uid://wwj1ow1f437s"] + +[ext_resource type="Script" uid="uid://dekpmw0i03eyi" path="res://gui/overlays/controls_visualization/keyboard/keyboard_explanation.gd" id="1_ubxjd"] +[ext_resource type="PackedScene" uid="uid://dj7tqrgpdja42" path="res://gui/overlays/controls_visualization/keyboard/keyboard_button.tscn" id="2_8nrgi"] +[ext_resource type="FontVariation" uid="uid://cl6m4hqsnrpav" path="res://gui/resources/fonts/sansita-swashed-bold.tres" id="3_nvtkh"] +[ext_resource type="Texture2D" uid="uid://cf8hrxilqe2ih" path="res://gui/overlays/controls_visualization/arrow.svg" id="4_mjakv"] + +[node name="KeyboardExplanation" type="Control"] +custom_minimum_size = Vector2(0, 450) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_ubxjd") + +[node name="VBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Control" type="Control" parent="VBoxContainer"] +custom_minimum_size = Vector2(400, 375) +layout_mode = 2 +size_flags_vertical = 4 + +[node name="WASD" type="Node2D" parent="VBoxContainer/Control"] + +[node name="Node2D" type="Node2D" parent="VBoxContainer/Control/WASD"] +position = Vector2(200, 100) + +[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "W" + +[node name="Node2D2" type="Node2D" parent="VBoxContainer/Control/WASD"] +position = Vector2(200, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D2" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "S" + +[node name="Node2D3" type="Node2D" parent="VBoxContainer/Control/WASD"] +position = Vector2(125, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D3" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Node2D4" type="Node2D" parent="VBoxContainer/Control/WASD"] +position = Vector2(275, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control/WASD/Node2D4" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "D" + +[node name="Node2D5" type="Node2D" parent="VBoxContainer/Control/WASD"] +position = Vector2(200, 275) + +[node name="Label" type="Label" parent="VBoxContainer/Control/WASD/Node2D5"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -21.5 +offset_top = -11.5 +offset_right = 21.5 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_nvtkh") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.move" + +[node name="Spacer" type="Control" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Control2" type="Control" parent="VBoxContainer"] +custom_minimum_size = Vector2(750, 450) +layout_mode = 2 +size_flags_vertical = 4 + +[node name="JKL" type="Node2D" parent="VBoxContainer/Control2"] +position = Vector2(150, 0) + +[node name="K" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(200, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/K" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "K" + +[node name="J" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(125, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/J" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "J" + +[node name="L" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(275, 175) + +[node name="KeyboardButton" parent="VBoxContainer/Control2/JKL/L" instance=ExtResource("2_8nrgi")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -24.0 +offset_top = -24.5 +offset_right = 24.0 +offset_bottom = 24.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "L" + +[node name="LeftHand" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(25, 375) + +[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/LeftHand"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -21.5 +offset_top = -11.5 +offset_right = 21.5 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_nvtkh") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.interact_left" + +[node name="RightHand" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(375, 375) + +[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/RightHand"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -21.5 +offset_top = -11.5 +offset_right = 21.5 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_nvtkh") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.interact_right" + +[node name="Boost" type="Node2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(335, 65) + +[node name="Label" type="Label" parent="VBoxContainer/Control2/JKL/Boost"] +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_top = -29.0 +offset_right = 113.0 +offset_bottom = 20.0 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_nvtkh") +theme_override_font_sizes/font_size = 40 +text = "c.controls_explanation.boost" + +[node name="Sprite2D" type="Sprite2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(50, 275) +scale = Vector2(0.5, 0.5) +texture = ExtResource("4_mjakv") + +[node name="Sprite2D2" type="Sprite2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(350, 275) +scale = Vector2(-0.5, 0.5) +texture = ExtResource("4_mjakv") + +[node name="Sprite2D3" type="Sprite2D" parent="VBoxContainer/Control2/JKL"] +position = Vector2(250, 90) +rotation = -1.5707964 +scale = Vector2(-0.5, 0.5) +texture = ExtResource("4_mjakv") diff --git a/client/gui/resources/fonts/sansita-swashed-bold.tres b/client/gui/resources/fonts/sansita-swashed-bold.tres new file mode 100644 index 00000000..17903145 --- /dev/null +++ b/client/gui/resources/fonts/sansita-swashed-bold.tres @@ -0,0 +1,9 @@ +[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://cl6m4hqsnrpav"] + +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://gui/resources/fonts/font-sansita-swashed.woff2" id="1_x5a5j"] + +[resource] +base_font = ExtResource("1_x5a5j") +variation_opentype = { +2003265652: 900 +} diff --git a/client/multiplayer.gd b/client/multiplayer.gd index b94b044c..c550716c 100644 --- a/client/multiplayer.gd +++ b/client/multiplayer.gd @@ -145,6 +145,11 @@ func send_leave(player): "player": player, }) +func send_ready(): + send_packet({ + "type": "ready" + }) + func send_packet(p): var json = JSON.stringify(p) socket.send_text(json) diff --git a/client/system/profile.gd b/client/system/profile.gd index d0e04bb2..5fd7f548 100644 --- a/client/system/profile.gd +++ b/client/system/profile.gd @@ -25,7 +25,9 @@ static var default_profile := { }, "last_server_url": "", "tutorial_ingredients_played": [], - "registry_asked": false + "registry_asked": false, + "controls_one_handed_explained": false, + "controls_two_handed_explained": false } # profile is stored in a Dictionary[String, Any] diff --git a/locale/en.ini b/locale/en.ini index 3e707831..55dcdde5 100644 --- a/locale/en.ini +++ b/locale/en.ini @@ -2,9 +2,15 @@ c.announce.go=GO! c.announce.ready=READY? c.chat.write_message=Write message +c.controls_explanation.boost=Boost +c.controls_explanation.interact_left=Left hand +c.controls_explanation.interact_right=Right hand +c.controls_explanation.move=Move +c.controls_explanation.two_handed=You can use both hands in this map c.credits.contributors=with contributions from c.credits.developed_by=developed by c.credits.models=Models +c.credits.other=Other c.credits.sounds=Sounds c.credits.thanks=Thank You For Playing c.credits.title=Hurry Curry! - a game about cooking @@ -26,8 +32,6 @@ c.map.difficulty.2=Moderate c.map.difficulty.3=Unplayable c.map.difficulty.4=Very hard c.map.difficulty=Difficulty -c.system_message.screenshot_saved=Screenshot saved to {path} -c.system_message.sceneshot_saved=Sceneshot saved to {path} c.map.players_recommended={0} players recommended c.menu.about.credits=Credits c.menu.about.legal=Legal @@ -36,9 +40,10 @@ c.menu.about.version=Version c.menu.about=About c.menu.accept=Accept c.menu.back=Back +c.menu.customize_chef=Customize Chef c.menu.deny=Deny -c.menu.game.connecting=Connecting... c.menu.error.title=Error +c.menu.game.connecting=Connecting... c.menu.ingame.cancel=Abort current game c.menu.ingame.join=Join game c.menu.ingame.leave=Spectate @@ -51,7 +56,6 @@ c.menu.lobby.enable_bots=Enable bots c.menu.lobby.mapname=Map name c.menu.lobby.players=Players c.menu.lobby.start=Start game -c.menu.customize_chef=Customize Chef c.menu.play.allow_query_registry=To show a public server list a registry service is contacted regularly. The registry service is {0}. c.menu.play.connect=Connect c.menu.play.editor_failed=Editor (failed) @@ -62,18 +66,18 @@ c.menu.play.editor_testing=Map Editor (testing) c.menu.play.editor_unavailable=Map Editor (unavailable) c.menu.play.editor=Map Editor c.menu.play.fetching_list=Fetching server list… -c.menu.play.server_version_mismatch=Protocol version mismatch -c.menu.play.server_players={0} players online c.menu.play.no_servers=No servers available. c.menu.play.quick_connect=Quick Connect c.menu.play.server_binary_not_found=Server binary was not found. Please install the server separately. c.menu.play.server_failed_tooltip=The server crashed or exited in some way or another.%nYou should try starting the server from the command-line. c.menu.play.server_failed=Server (failed) +c.menu.play.server_players={0} players online c.menu.play.server_start=Start server c.menu.play.server_starting=Server is starting… c.menu.play.server_stop=Stop server c.menu.play.server_testing=Server (testing) c.menu.play.server_unavailable=Server (unavailable) +c.menu.play.server_version_mismatch=Protocol version mismatch c.menu.play=Play c.menu.quit=Quit c.menu.scoreboard.button=Show scoreboard @@ -104,12 +108,12 @@ c.settings.gameplay.interact_target=Interact Target Behaviour c.settings.gameplay.interpolate_camera_rotation=Smooth camera rotation c.settings.gameplay.invert_camera=Invert camera movement c.settings.gameplay.latch_boost=Always extend boost to maximum duration +c.settings.gameplay.screenshot_path=Screenshot directory c.settings.gameplay.setup_completed.button_label=Open setup form c.settings.gameplay.setup_completed=Initial setup completed c.settings.gameplay.tutorial_disabled=Disable tutorial c.settings.gameplay.usernames=Show username tags c.settings.gameplay.vibration=Enable vibrations -c.settings.gameplay.screenshot_path=Screenshot directory c.settings.gameplay=Gameplay c.settings.graphics.aa.disabled=Disabled c.settings.graphics.aa.fx=FXAA (computationally cheap but generated artifacts) @@ -139,16 +143,11 @@ c.settings.graphics.taa=Temporal Anti-Aliasing c.settings.graphics.ui_blur=Enable UI blur c.settings.graphics=Graphics c.settings.input.add=Add new -c.settings.input.screenshot=Take screenshot -c.settings.input.sceneshot=Take sceneshot (saves game world as glTF) -c.settings.input.toggle_overlay=Toggle overlay visibility -c.settings.input.toggle_debug=Toggle debug overlay -c.settings.input.toggle_first_person=Toggle first person camera c.settings.input.backwards=Move Backwards c.settings.input.boost=Boost movement c.settings.input.chat=Toggle chat -c.settings.input.fps_mouse_sensitivity=Mouse Sensitivity (FPS) c.settings.input.forwards=Move Forwards +c.settings.input.fps_mouse_sensitivity=Mouse Sensitivity (FPS) c.settings.input.fullscreen=Toggle fullscreen c.settings.input.interact_left=Interact (Left hand) c.settings.input.interact_right=Interact (Right hand) @@ -170,11 +169,16 @@ c.settings.input.rotate_down=Rotate camera down c.settings.input.rotate_left=Rotate camera left c.settings.input.rotate_right=Rotate camera right c.settings.input.rotate_up=Rotate camera up +c.settings.input.sceneshot=Take sceneshot (saves game world as glTF) +c.settings.input.screenshot=Take screenshot c.settings.input.scroll_down_discrete=Scroll down (discrete) c.settings.input.scroll_down=Scroll down c.settings.input.scroll_up_discrete=Scroll up (discrete) c.settings.input.scroll_up=Scroll up c.settings.input.start_game=Start game +c.settings.input.toggle_debug=Toggle debug overlay +c.settings.input.toggle_first_person=Toggle first person camera +c.settings.input.toggle_overlay=Toggle overlay visibility c.settings.input.unknown_event=Unknown event c.settings.input.zoom_in_discrete=Zoom in (discrete) c.settings.input.zoom_in=Zoom in @@ -197,13 +201,13 @@ c.settings.server.name=Server display name c.settings.server.register=Submit for public listing (requires port forwarding) c.settings.server.upnp=Automatic port forwarding (requires UPnP) c.settings.server=Server +c.settings.ui.hide_overlays=Hide in-game overlays (Orders, timer, etc.) c.settings.ui.language.system=System default c.settings.ui.language=Language c.settings.ui.scale_factor=UI scale factor c.settings.ui.scale_mode.disabled=Disabled c.settings.ui.scale_mode.resize=Resize c.settings.ui.scale_mode=UI scale mode -c.settings.ui.hide_overlays=Hide in-game overlays (Orders, timer, etc.) c.settings.ui.touch_controls.automatic=Automatic c.settings.ui.touch_controls.disabled=Disabled c.settings.ui.touch_controls.enabled=Enabled @@ -229,6 +233,8 @@ c.setup.uniform.value=Hairstyle {0} c.setup.uniform=3. [b]Working Uniform.[/b] You must always have one of the following hairstyles. c.setup.user_signature.desc=Signature of the Employee:%n%n%n c.setup.user_signature=Click to sign +c.system_message.sceneshot_saved=Sceneshot saved to {path} +c.system_message.screenshot_saved=Screenshot saved to {path} c.version.arch=Processor Architecture c.version.distribution=Distribution c.version.game=Game Version -- cgit v1.2.3-70-g09d2