diff options
author | nokoe <nokoe@mailbox.org> | 2024-06-26 16:39:50 +0200 |
---|---|---|
committer | nokoe <nokoe@mailbox.org> | 2024-06-26 16:39:50 +0200 |
commit | a8d17ba85a46169fa049c70e1a8f53ea97784c90 (patch) | |
tree | f84853b18396e510149b0704e7238c1c22b87e98 | |
parent | 5654b69e4c7e0aafe258ad0ab73105722a389def (diff) | |
parent | 677b9c898b0fc3faac2aa505cce438a2b2189265 (diff) | |
download | hurrycurry-a8d17ba85a46169fa049c70e1a8f53ea97784c90.tar hurrycurry-a8d17ba85a46169fa049c70e1a8f53ea97784c90.tar.bz2 hurrycurry-a8d17ba85a46169fa049c70e1a8f53ea97784c90.tar.zst |
Merge branch 'master' of ssh://codeberg.org/metamuffin/undercooked
32 files changed, 291 insertions, 248 deletions
diff --git a/client/global.gd b/client/global.gd index be230890..6e12d0cf 100644 --- a/client/global.gd +++ b/client/global.gd @@ -69,3 +69,13 @@ func load_dict(path: String, default: Dictionary) -> Dictionary: print("Loaded dict: ", res) return res + +func focus_first_button(node: Node) -> bool: + if node is Button: + 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_button(c): + return true + return false diff --git a/client/map/tiles/bark.tres b/client/map/tiles/bark.tres index 53b9adc6..24bc469b 100644 --- a/client/map/tiles/bark.tres +++ b/client/map/tiles/bark.tres @@ -10,6 +10,5 @@ metallic = 0.4 roughness = 0.301511 normal_enabled = true normal_texture = ExtResource("2_v3ray") -distance_fade_mode = 2 distance_fade_min_distance = 2.0 distance_fade_max_distance = 4.0 diff --git a/client/map/tiles/leaves.tres b/client/map/tiles/leaves.tres index 99486408..5c2b2082 100644 --- a/client/map/tiles/leaves.tres +++ b/client/map/tiles/leaves.tres @@ -7,6 +7,5 @@ resource_name = "NormalTree_Leaves" transparency = 4 albedo_texture = ExtResource("1_jg4r8") metallic_specular = 0.0 -distance_fade_mode = 2 distance_fade_min_distance = 2.0 distance_fade_max_distance = 4.0 diff --git a/client/menu/character_menu.gd b/client/menu/character_menu.gd index fd4e3707..3e535e71 100644 --- a/client/menu/character_menu.gd +++ b/client/menu/character_menu.gd @@ -21,9 +21,10 @@ extends Control func _ready(): $VBoxContainer/top_panel/a/username.text = Global.profile["username"] character.select_hairstyle(Global.profile["character"]) + Global.focus_first_button(self) func _on_back_pressed(): - $SceneTransition.transition_to("res://menu/main_menu.tscn") + $SceneTransition.transition_to("res://menu/menu_manager.tscn") func _on_username_text_changed(new_text): Global.profile["username"] = new_text diff --git a/client/menu/character_menu.tscn b/client/menu/character_menu.tscn index cad0cb35..b958cf9d 100644 --- a/client/menu/character_menu.tscn +++ b/client/menu/character_menu.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://1f7xpirm5d28"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_ak2pw"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_ak2pw"] [ext_resource type="Script" path="res://menu/character_menu.gd" id="1_brhd1"] [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://menu/scene_transition.tscn" id="4_c0ocf"] diff --git a/client/menu/credits_menu.gd b/client/menu/credits_menu.gd index e3ea4c51..07fffab9 100644 --- a/client/menu/credits_menu.gd +++ b/client/menu/credits_menu.gd @@ -21,9 +21,10 @@ var cc_by_3 := { "Glasses": "Jeremy Edelblut" } +@onready var menu_manager: MenuManager = get_parent() @onready var label = $Panel/MarginContainer/VBoxContainer/RichTextLabel -func _ready(): +func prepare(): contributors.shuffle() label.text = "[center][b]undercooked - a game about cooking[/b]\n\ndeveloped by\n\n[b]" label.text += ", ".join(contributors) @@ -34,6 +35,6 @@ func _ready(): label.text += "[b]\"%s\" %s[/b]\nLicensed under Creative Commons: By Attribution 3.0 License\nhttps://creativecommons.org/licenses/by/3.0/\n\n" % [k, v] label.text += "[b]Additional CC0 assets by:[/b]\n" + "\n".join(cc_0) - + func _on_back_pressed(): - $SceneTransition.transition_to("res://menu/main_menu.tscn") + menu_manager.goBack() diff --git a/client/menu/credits_menu.tscn b/client/menu/credits_menu.tscn index a6536e16..74d5cbc9 100644 --- a/client/menu/credits_menu.tscn +++ b/client/menu/credits_menu.tscn @@ -1,9 +1,7 @@ -[gd_scene load_steps=6 format=3 uid="uid://7mqbxa054bjv"] +[gd_scene load_steps=4 format=3 uid="uid://7mqbxa054bjv"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_emk5o"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_emk5o"] [ext_resource type="Script" path="res://menu/credits_menu.gd" id="1_igs63"] -[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://menu/menu_background.tscn" id="2_k0853"] -[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://menu/scene_transition.tscn" id="4_fbbdb"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_p2qmw"] bg_color = Color(0, 0, 0, 0.878431) @@ -18,8 +16,6 @@ grow_vertical = 2 theme = ExtResource("1_emk5o") script = ExtResource("1_igs63") -[node name="MenuBackground" parent="." instance=ExtResource("2_k0853")] - [node name="Panel" type="Panel" parent="."] layout_mode = 1 anchors_preset = 15 @@ -58,8 +54,4 @@ bbcode_enabled = true layout_mode = 2 text = "Back" -[node name="SceneTransition" parent="." instance=ExtResource("4_fbbdb")] -visible = false -layout_mode = 1 - [connection signal="pressed" from="Panel/MarginContainer/VBoxContainer/back" to="." method="_on_back_pressed"] diff --git a/client/menu/error_menu.gd b/client/menu/error_menu.gd index 9938ee9d..087261e5 100644 --- a/client/menu/error_menu.gd +++ b/client/menu/error_menu.gd @@ -1,7 +1,8 @@ extends Control func _ready(): + Global.focus_first_button(self) $Panel/contents/mesage.text = Global.error_message func _on_return_pressed(): - $SceneTransition.transition_to("res://menu/main_menu.tscn") + $SceneTransition.transition_to("res://menu/menu_manager.tscn") diff --git a/client/menu/error_menu.tscn b/client/menu/error_menu.tscn index 0b86cceb..ea01ddc3 100644 --- a/client/menu/error_menu.tscn +++ b/client/menu/error_menu.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=3 uid="uid://cimgn07lbcs4v"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_cabdu"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_cabdu"] [ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://menu/menu_background.tscn" id="2_5fxol"] [ext_resource type="Script" path="res://menu/error_menu.gd" id="2_dbe41"] [ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://menu/scene_transition.tscn" id="4_1nbt3"] diff --git a/client/menu/ingame_menu.gd b/client/menu/ingame_menu.gd index 21bfa8ac..4752c382 100644 --- a/client/menu/ingame_menu.gd +++ b/client/menu/ingame_menu.gd @@ -1,9 +1,20 @@ extends Control @onready var anim = $AnimationPlayer +@onready var options = $Side/Margin/Options + +func act(): + show() + anim.play("activate") + Global.focus_first_button(options) + +func deact(): + anim.play_backwards("activate") + await anim.animation_finished + hide() func _on_main_menu_pressed(): - get_parent().transition_to("res://menu/main_menu.tscn") + get_parent().transition_to("res://menu/menu_manager.tscn") func _on_quit_pressed(): get_parent().quit() diff --git a/client/menu/ingame_menu.tscn b/client/menu/ingame_menu.tscn index cf35a7e7..47b7cb54 100644 --- a/client/menu/ingame_menu.tscn +++ b/client/menu/ingame_menu.tscn @@ -1,16 +1,16 @@ [gd_scene load_steps=10 format=3 uid="uid://lxlgtjm8hw7v"] [ext_resource type="Script" path="res://menu/ingame_menu.gd" id="1_gd1i3"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_lb056"] [ext_resource type="Shader" path="res://menu/blur_mix.gdshader" id="1_o42mc"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_tm331"] -[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/font-sansita-swashed.woff2" id="2_4u0ox"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/theme/font-sansita-swashed.woff2" id="4_27kbu"] [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/path = NodePath("Side:position:x") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -24,7 +24,7 @@ resource_name = "activate" tracks/0/type = "bezier" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("side:position:x") +tracks/0/path = NodePath("Side:position:x") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -46,7 +46,7 @@ shader_parameter/mix_amount = 0.3 shader_parameter/color_over = null [sub_resource type="FontVariation" id="FontVariation_ud3l8"] -base_font = ExtResource("2_4u0ox") +base_font = ExtResource("4_27kbu") variation_embolden = 0.5 [node name="IngameMenu" type="Control"] @@ -56,7 +56,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -theme = ExtResource("1_tm331") +theme = ExtResource("1_lb056") script = ExtResource("1_gd1i3") [node name="AnimationPlayer" type="AnimationPlayer" parent="."] @@ -65,26 +65,27 @@ libraries = { } speed_scale = 8.0 -[node name="side" type="PanelContainer" parent="."] +[node name="Side" type="PanelContainer" parent="."] material = SubResource("ShaderMaterial_o2vtr") layout_mode = 1 anchors_preset = 9 anchor_bottom = 1.0 offset_left = -400.0 offset_right = -90.0 +offset_bottom = 1296.0 grow_vertical = 2 -[node name="margin" type="MarginContainer" parent="side"] +[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 -[node name="options" type="VBoxContainer" parent="side/margin"] +[node name="Options" type="VBoxContainer" parent="Side/Margin"] layout_mode = 2 -[node name="title" type="Label" parent="side/margin/options"] +[node name="Title" type="Label" parent="Side/Margin/Options"] layout_mode = 2 auto_translate = false theme_override_colors/font_outline_color = Color(0.566408, 0.208917, 0.266045, 1) @@ -93,25 +94,25 @@ theme_override_fonts/font = SubResource("FontVariation_ud3l8") theme_override_font_sizes/font_size = 48 text = "Undercooked" -[node name="spacer" type="Control" parent="side/margin/options"] +[node name="Spacer" type="Control" parent="Side/Margin/Options"] custom_minimum_size = Vector2(0, 10) layout_mode = 2 -[node name="reconnect" type="Button" parent="side/margin/options"] +[node name="Reconnect" type="Button" parent="Side/Margin/Options"] layout_mode = 2 text = "Reconnect" alignment = 0 -[node name="main_menu" type="Button" parent="side/margin/options"] +[node name="MainMenu" type="Button" parent="Side/Margin/Options"] layout_mode = 2 text = "Main Menu" alignment = 0 -[node name="quit" type="Button" parent="side/margin/options"] +[node name="Quit" type="Button" parent="Side/Margin/Options"] layout_mode = 2 text = "Quit" alignment = 0 -[connection signal="pressed" from="side/margin/options/reconnect" to="." method="_on_reconnect_pressed"] -[connection signal="pressed" from="side/margin/options/main_menu" to="." method="_on_main_menu_pressed"] -[connection signal="pressed" from="side/margin/options/quit" to="." method="_on_quit_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Reconnect" to="." method="_on_reconnect_pressed"] +[connection signal="pressed" from="Side/Margin/Options/MainMenu" to="." method="_on_main_menu_pressed"] +[connection signal="pressed" from="Side/Margin/Options/Quit" to="." method="_on_quit_pressed"] diff --git a/client/menu/main_menu.gd b/client/menu/main_menu.gd index bd4cdcb0..28629e0d 100644 --- a/client/menu/main_menu.gd +++ b/client/menu/main_menu.gd @@ -16,25 +16,24 @@ # extends Control -@onready var transition = $SceneTransition -@onready var quick_connect = $side/margin/options/quick_connect +@onready var menu_manager: MenuManager = get_parent() + @onready var quit_button = $side/margin/options/quit @onready var connect_uri = $side/margin/options/connect/uri func _ready(): - quick_connect.grab_focus() if OS.has_feature("web"): quit_button.hide() connect_uri.text = Global.profile["last_server_url"] func _on_quit_pressed(): - transition.quit() + menu_manager.transition.quit() func _on_credits_pressed(): - transition.transition_to("res://menu/credits_menu.tscn") + menu_manager.goto("credits") func _on_connect_pressed(): - var url = $side/margin/options/connect/uri.text + var url = connect_uri.text Global.profile["last_server_url"] = url Global.save_profile() connect_to(url) @@ -52,10 +51,10 @@ func _on_quick_connect_pressed(): func connect_to(url): print("Connecting to %s" % url) Global.server_url = url - transition.transition_to("res://game.tscn") + menu_manager.transition.transition_to("res://game.tscn") func _on_change_character_pressed(): - transition.transition_to("res://menu/character_menu.tscn") + menu_manager.transition.transition_to("res://menu/character_menu.tscn") func _on_settings_pressed(): - transition.transition_to("res://menu/settings_menu.tscn") + menu_manager.goto("settings") diff --git a/client/menu/main_menu.tscn b/client/menu/main_menu.tscn index 0deeb748..76b55a1a 100644 --- a/client/menu/main_menu.tscn +++ b/client/menu/main_menu.tscn @@ -1,11 +1,9 @@ -[gd_scene load_steps=9 format=3 uid="uid://dbj8508whxgwv"] +[gd_scene load_steps=8 format=3 uid="uid://dbj8508whxgwv"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_nlcpo"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_nlcpo"] [ext_resource type="Script" path="res://menu/main_menu.gd" id="2_qot2j"] [ext_resource type="Shader" path="res://menu/blur_mix.gdshader" id="4_050xu"] -[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/font-sansita-swashed.woff2" id="4_mfs30"] -[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://menu/menu_background.tscn" id="4_ydj5p"] -[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://menu/scene_transition.tscn" id="5_651nk"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/theme/font-sansita-swashed.woff2" id="4_mfs30"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_irdo3"] shader = ExtResource("4_050xu") @@ -13,6 +11,8 @@ shader_parameter/blur_amount = 3.5 shader_parameter/mix_amount = 0.3 shader_parameter/color_over = null +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cm1nk"] + [sub_resource type="FontVariation" id="FontVariation_htgmg"] base_font = ExtResource("4_mfs30") variation_embolden = 0.5 @@ -27,8 +27,6 @@ grow_vertical = 2 theme = ExtResource("1_nlcpo") script = ExtResource("2_qot2j") -[node name="MenuBackground" parent="." instance=ExtResource("4_ydj5p")] - [node name="side" type="PanelContainer" parent="."] material = SubResource("ShaderMaterial_irdo3") layout_mode = 1 @@ -36,6 +34,7 @@ anchors_preset = 9 anchor_bottom = 1.0 offset_right = 340.0 grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_cm1nk") [node name="margin" type="MarginContainer" parent="side"] layout_mode = 2 @@ -98,10 +97,6 @@ layout_mode = 2 text = "Quit" alignment = 0 -[node name="SceneTransition" parent="." instance=ExtResource("5_651nk")] -visible = false -layout_mode = 1 - [connection signal="pressed" from="side/margin/options/quick_connect" to="." method="_on_quick_connect_pressed"] [connection signal="pressed" from="side/margin/options/connect/connect" to="." method="_on_connect_pressed"] [connection signal="pressed" from="side/margin/options/change_character" to="." method="_on_change_character_pressed"] diff --git a/client/menu/menu_manager.gd b/client/menu/menu_manager.gd new file mode 100644 index 00000000..1285a7e6 --- /dev/null +++ b/client/menu/menu_manager.gd @@ -0,0 +1,36 @@ +extends Control +class_name MenuManager + +@onready var menus = { + "main": $MainMenu, + "credits": $CreditsMenu, + "settings": $SettingsMenu +} +@onready var transition = $SceneTransition + +var menu_stack = ["main"] + +func _ready(): + Global.focus_first_button(menus[menu_stack.back()]) + +func goto(menu_name: String): + show_menu(menu_name) + menu_stack.push_back(menu_name) + print("Go to called. Stack: " + str(menu_stack)) + +func goBack(): + menu_stack.pop_back() + if menu_stack.is_empty(): + Global.showError("Menu stack empty") + show_menu(menu_stack.back()) + print("Go back called. Stack: " + str(menu_stack)) + +func show_menu(menu_name: String): + for k in menus.keys(): + if k == menu_name: + menus[k].show() + if menus[k].has_method("prepare"): + menus[k].prepare() # Optionally run some code + Global.focus_first_button(menus[k]) + else: + menus[k].hide() diff --git a/client/menu/menu_manager.tscn b/client/menu/menu_manager.tscn new file mode 100644 index 00000000..6b2d7b33 --- /dev/null +++ b/client/menu/menu_manager.tscn @@ -0,0 +1,38 @@ +[gd_scene load_steps=7 format=3 uid="uid://cd52sr1cmo8oj"] + +[ext_resource type="Script" path="res://menu/menu_manager.gd" id="1_c0rjm"] +[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://menu/menu_background.tscn" id="2_nf7b6"] +[ext_resource type="PackedScene" uid="uid://dbj8508whxgwv" path="res://menu/main_menu.tscn" id="3_ccpur"] +[ext_resource type="PackedScene" uid="uid://7mqbxa054bjv" path="res://menu/credits_menu.tscn" id="4_xhcd8"] +[ext_resource type="PackedScene" uid="uid://8ic77jmadadj" path="res://menu/settings_menu.tscn" id="5_lifj8"] +[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://menu/scene_transition.tscn" id="6_p4u45"] + +[node name="MenuManager" 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_c0rjm") + +[node name="MenuBackground" parent="." instance=ExtResource("2_nf7b6")] + +[node name="MainMenu" parent="." instance=ExtResource("3_ccpur")] +layout_mode = 1 + +[node name="CreditsMenu" parent="." instance=ExtResource("4_xhcd8")] +visible = false +layout_mode = 1 + +[node name="SettingsMenu" parent="." instance=ExtResource("5_lifj8")] +visible = false +layout_mode = 1 + +[node name="SceneTransition" parent="." instance=ExtResource("6_p4u45")] +layout_mode = 0 +anchors_preset = 0 +anchor_right = 0.0 +anchor_bottom = 0.0 +grow_horizontal = 1 +grow_vertical = 1 diff --git a/client/menu/scene_transition.gd b/client/menu/scene_transition.gd index 8d9f38cf..87a1ec1b 100644 --- a/client/menu/scene_transition.gd +++ b/client/menu/scene_transition.gd @@ -45,9 +45,6 @@ func out(): func _process(_delta): if ingame: if not menu.visible and Input.is_action_just_pressed("pause"): - menu.visible = true - menu.anim.play("activate") + menu.act() elif menu.visible and Input.is_action_just_pressed("pause"): - menu.anim.play_backwards("activate") - await menu.anim.animation_finished - menu.visible = false + menu.deact() diff --git a/client/menu/settings_menu.gd b/client/menu/settings_menu.gd index f7abd9e6..47aa90be 100644 --- a/client/menu/settings_menu.gd +++ b/client/menu/settings_menu.gd @@ -16,6 +16,7 @@ extends Control @onready var options: VBoxContainer = $outer_gap/panel/inner_gap/options +@onready var menu_manager: MenuManager = get_parent() var settings: Dictionary @@ -23,7 +24,8 @@ func _on_back_pressed(): for k in settings.keys(): Global.settings[k]["value"] = settings[k].get_value() Global.save_settings() - $SceneTransition.transition_to("res://menu/main_menu.tscn") + menu_manager.goBack() + func _ready(): for k in Global.settings.keys(): diff --git a/client/menu/settings_menu.tscn b/client/menu/settings_menu.tscn index 18a32759..6ead9b8b 100644 --- a/client/menu/settings_menu.tscn +++ b/client/menu/settings_menu.tscn @@ -1,9 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://8ic77jmadadj"] +[gd_scene load_steps=3 format=3 uid="uid://8ic77jmadadj"] -[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme.tres" id="1_foq3a"] -[ext_resource type="PackedScene" uid="uid://l4vm07dtda4j" path="res://menu/menu_background.tscn" id="1_wi8ti"] +[ext_resource type="Theme" uid="uid://b0qmvo504e457" path="res://menu/theme/theme.tres" id="1_foq3a"] [ext_resource type="Script" path="res://menu/settings_menu.gd" id="2_3hgm8"] -[ext_resource type="PackedScene" uid="uid://bg2d78ycorcqk" path="res://menu/scene_transition.tscn" id="2_t0one"] [node name="SettingsMenu" type="Control"] layout_mode = 3 @@ -15,8 +13,6 @@ grow_vertical = 2 theme = ExtResource("1_foq3a") script = ExtResource("2_3hgm8") -[node name="MenuBackground" parent="." instance=ExtResource("1_wi8ti")] - [node name="outer_gap" type="MarginContainer" parent="."] layout_mode = 1 anchors_preset = 15 @@ -58,8 +54,4 @@ layout_mode = 2 size_flags_vertical = 8 text = "Back to Main Menu" -[node name="SceneTransition" parent="." instance=ExtResource("2_t0one")] -visible = false -layout_mode = 1 - [connection signal="pressed" from="outer_gap/panel/inner_gap/back" to="." method="_on_back_pressed"] diff --git a/client/menu/theme/focus_style.tres b/client/menu/theme/focus_style.tres new file mode 100644 index 00000000..a01843fe --- /dev/null +++ b/client/menu/theme/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/menu/font-josefin-sans.woff2 b/client/menu/theme/font-josefin-sans.woff2 Binary files differindex dce2708f..dce2708f 100644 --- a/client/menu/font-josefin-sans.woff2 +++ b/client/menu/theme/font-josefin-sans.woff2 diff --git a/client/menu/font-josefin-sans.woff2.import b/client/menu/theme/font-josefin-sans.woff2.import index 9bf40c47..5ecd872c 100644 --- a/client/menu/font-josefin-sans.woff2.import +++ b/client/menu/theme/font-josefin-sans.woff2.import @@ -3,12 +3,12 @@ importer="font_data_dynamic" type="FontFile" uid="uid://5ixo6b3bd3km" -path="res://.godot/imported/font-josefin-sans.woff2-8195d19f9e478a66f9d2ca31db663e15.fontdata" +path="res://.godot/imported/font-josefin-sans.woff2-e2c3f263d98e1132cfe6af3f4f0a3454.fontdata" [deps] -source_file="res://menu/font-josefin-sans.woff2" -dest_files=["res://.godot/imported/font-josefin-sans.woff2-8195d19f9e478a66f9d2ca31db663e15.fontdata"] +source_file="res://menu/theme/font-josefin-sans.woff2" +dest_files=["res://.godot/imported/font-josefin-sans.woff2-e2c3f263d98e1132cfe6af3f4f0a3454.fontdata"] [params] diff --git a/client/menu/font-sansita-swashed.woff2 b/client/menu/theme/font-sansita-swashed.woff2 Binary files differindex 5c665fb0..5c665fb0 100644 --- a/client/menu/font-sansita-swashed.woff2 +++ b/client/menu/theme/font-sansita-swashed.woff2 diff --git a/client/menu/font-sansita-swashed.woff2.import b/client/menu/theme/font-sansita-swashed.woff2.import index 54056a3c..faf840fa 100644 --- a/client/menu/font-sansita-swashed.woff2.import +++ b/client/menu/theme/font-sansita-swashed.woff2.import @@ -3,12 +3,12 @@ importer="font_data_dynamic" type="FontFile" uid="uid://bo4vh5xkpvrh1" -path="res://.godot/imported/font-sansita-swashed.woff2-259623c6db3c7be991207ff769c643a5.fontdata" +path="res://.godot/imported/font-sansita-swashed.woff2-323b4a2ee0671aba6e17a6f073f706f3.fontdata" [deps] -source_file="res://menu/font-sansita-swashed.woff2" -dest_files=["res://.godot/imported/font-sansita-swashed.woff2-259623c6db3c7be991207ff769c643a5.fontdata"] +source_file="res://menu/theme/font-sansita-swashed.woff2" +dest_files=["res://.godot/imported/font-sansita-swashed.woff2-323b4a2ee0671aba6e17a6f073f706f3.fontdata"] [params] diff --git a/client/menu/theme.tres b/client/menu/theme/theme.tres index c2ec3b12..96cdbb19 100644 --- a/client/menu/theme.tres +++ b/client/menu/theme/theme.tres @@ -1,10 +1,11 @@ -[gd_resource type="Theme" load_steps=8 format=3 uid="uid://b0qmvo504e457"] +[gd_resource type="Theme" load_steps=9 format=3 uid="uid://b0qmvo504e457"] -[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://menu/font-josefin-sans.woff2" id="1_go7fi"] -[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/font-sansita-swashed.woff2" id="1_tneco"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://menu/theme/font-josefin-sans.woff2" id="1_f8qb0"] +[ext_resource type="StyleBox" uid="uid://b86kbd3pfkd5w" path="res://menu/theme/focus_style.tres" id="2_brg2c"] +[ext_resource type="FontFile" uid="uid://bo4vh5xkpvrh1" path="res://menu/theme/font-sansita-swashed.woff2" id="3_8u6ww"] [sub_resource type="FontVariation" id="FontVariation_lyo8w"] -base_font = ExtResource("1_go7fi") +base_font = ExtResource("1_f8qb0") variation_embolden = 1.25 spacing_top = 5 @@ -39,25 +40,25 @@ grow_end = 0.0 thickness = 3 [sub_resource type="FontVariation" id="FontVariation_ff4nr"] -base_font = ExtResource("1_tneco") +base_font = ExtResource("3_8u6ww") variation_embolden = 0.7 [resource] Button/font_sizes/font_size = 18 Button/fonts/font = SubResource("FontVariation_lyo8w") Button/styles/disabled = SubResource("StyleBoxFlat_25x32") -Button/styles/focus = SubResource("StyleBoxFlat_25x32") +Button/styles/focus = ExtResource("2_brg2c") Button/styles/hover = SubResource("StyleBoxFlat_2fl8q") Button/styles/normal = SubResource("StyleBoxFlat_25x32") Button/styles/pressed = SubResource("StyleBoxFlat_25x32") HSeparator/styles/separator = SubResource("StyleBoxLine_emtvk") Label/font_sizes/font_size = 16 -Label/fonts/font = ExtResource("1_tneco") -LineEdit/styles/focus = SubResource("StyleBoxFlat_25x32") +Label/fonts/font = ExtResource("3_8u6ww") +LineEdit/styles/focus = ExtResource("2_brg2c") LineEdit/styles/normal = SubResource("StyleBoxFlat_25x32") LineEdit/styles/read_only = SubResource("StyleBoxFlat_25x32") RichTextLabel/fonts/bold_font = SubResource("FontVariation_ff4nr") RichTextLabel/fonts/bold_italics_font = null RichTextLabel/fonts/italics_font = null RichTextLabel/fonts/mono_font = null -RichTextLabel/fonts/normal_font = ExtResource("1_tneco") +RichTextLabel/fonts/normal_font = ExtResource("3_8u6ww") diff --git a/client/player/chat_message.tscn b/client/player/chat_message.tscn index 1ac82368..816c9c4f 100644 --- a/client/player/chat_message.tscn +++ b/client/player/chat_message.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://5rcfoyuiwuya"] -[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://menu/font-josefin-sans.woff2" id="1_3ximm"] +[ext_resource type="FontFile" uid="uid://5ixo6b3bd3km" path="res://menu/theme/font-josefin-sans.woff2" id="1_3ximm"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dpele"] bg_color = Color(1, 1, 1, 1) diff --git a/client/project.godot b/client/project.godot index e7a93c3a..e6c1caaf 100644 --- a/client/project.godot +++ b/client/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="undercooked" -run/main_scene="res://menu/main_menu.tscn" +run/main_scene="res://menu/menu_manager.tscn" config/features=PackedStringArray("4.2", "Forward Plus") boot_splash/bg_color=Color(0.282353, 0.141176, 0.141176, 1) boot_splash/image="res://icon.png" @@ -23,6 +23,14 @@ Global="*res://global.gd" [input] +ui_accept={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null) +] +} forward={ "deadzone": 0.1, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index 7f32b094..e6f999e6 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -20,39 +20,27 @@ mod pathfinding; use crate::{ data::Gamedata, - game::Game, - protocol::{DemandIndex, ItemIndex, Message, PacketC, PacketS, PlayerID}, - state::State, + game::Tile, + protocol::{DemandIndex, Message, PacketS, PlayerID}, }; use anyhow::{anyhow, Result}; use fake::{faker, Fake}; use glam::{IVec2, Vec2}; -use log::{debug, error, warn}; +use log::debug; use movement::MovementBase; use pathfinding::{find_path, Path}; use rand::{random, thread_rng}; use std::{ collections::{HashMap, HashSet}, sync::Arc, - time::Duration, -}; -use tokio::{ - sync::{broadcast, RwLock}, - time::interval, }; -struct CustomerManager { - disabled: bool, +pub struct DemandState { + data: Arc<Gamedata>, walkable: HashSet<IVec2>, chairs: HashMap<IVec2, bool>, - items: HashMap<IVec2, ItemIndex>, - customers: HashMap<PlayerID, Customer>, customer_id_counter: PlayerID, - demand: DemandState, -} - -struct DemandState { - data: Gamedata, + customers: HashMap<PlayerID, Customer>, } enum CustomerState { @@ -76,119 +64,41 @@ enum CustomerState { }, } -struct Customer { +pub struct Customer { movement: MovementBase, state: CustomerState, } -pub async fn customer(gstate: Arc<RwLock<State>>, mut grx: broadcast::Receiver<PacketC>) { - let mut state = CustomerManager { - disabled: true, - customer_id_counter: PlayerID(0), - walkable: Default::default(), - chairs: Default::default(), - items: Default::default(), - customers: Default::default(), - demand: DemandState { - data: Gamedata::default(), - }, - }; - let initial = gstate.write().await.game.prime_client(); - for packet in initial { - state.packet(packet); - } - - let mut interval = interval(Duration::from_millis(40)); - let mut packets_out = Vec::new(); - loop { - tokio::select! { - packet = grx.recv() => { - let packet = match packet { - Ok(p) => p, - Err(e) => { - warn!("{e}"); - continue; - } - }; - match packet { - PacketC::PutItem { .. } - | PacketC::TakeItem { .. } - | PacketC::SetTileItem { .. } => { - let g = gstate.read().await; - update_items(&mut state, &g.game) - }, - _ => () - } - state.packet(packet); - } - _ = interval.tick() => { - if !state.disabled { - if let Err(e) = state.tick(&mut packets_out, 0.04) { - warn!("error caught: {e}") - } - for (player,packet) in packets_out.drain(..) { - if let Err(e) = gstate.write().await.packet_in(player, packet).await { - error!("customer misbehaved: {e}") - } - } - } - } - } - } -} - -// TODO very inefficient, please do that incrementally -fn update_items(state: &mut CustomerManager, game: &Game) { - state.items.clear(); - for (&pos, tile) in game.tiles() { - if let Some(item) = &tile.item { - state.items.insert(pos, item.kind); +impl DemandState { + pub fn new(data: Arc<Gamedata>, map: &HashMap<IVec2, Tile>) -> Self { + let chair = data.get_tile_by_name("chair"); + Self { + walkable: map + .iter() + .filter(|(_, v)| !data.is_tile_colliding(v.kind)) + .map(|(e, _)| *e) + .collect(), + chairs: map + .iter() + .filter(|(_, v)| Some(v.kind) == chair) + .map(|(e, _)| (*e, true)) + .collect(), + customer_id_counter: PlayerID(0), + customers: Default::default(), + data, } } } impl DemandState { - pub fn target_customer_count(&self) -> usize { - // TODO insert sofa magic formula - 5 - } - pub fn generate_demand(&self) -> DemandIndex { - // TODO insert sofa magic formula - DemandIndex(random::<usize>() % self.data.demands.len()) - } -} - -impl CustomerManager { - pub fn packet(&mut self, packet: PacketC) { - match packet { - PacketC::Data { data } => { - self.disabled = data.demands.is_empty(); - self.demand.data = data; - } - PacketC::RemovePlayer { id } => { - self.customers.remove(&id); - } - PacketC::UpdateMap { - tile: pos, kind, .. - } => { - if let Some(kind) = kind { - let tilename = self.demand.data.tile_name(kind); - if !self.demand.data.is_tile_colliding(kind) { - self.walkable.insert(pos); - } - if tilename == "chair" { - self.chairs.insert(pos, true); - } - } else { - self.chairs.remove(&pos); - self.walkable.remove(&pos); - } - } - _ => (), - } - } - pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) -> Result<()> { - if self.customers.len() < self.demand.target_customer_count() { + pub fn tick( + &mut self, + packets_out: &mut Vec<(PlayerID, PacketS)>, + tiles: &mut HashMap<IVec2, Tile>, + data: &Gamedata, + dt: f32, + ) -> Result<()> { + if self.customers.len() < 5 { self.customer_id_counter.0 -= 1; let id = self.customer_id_counter; packets_out.push(( @@ -198,14 +108,15 @@ impl CustomerManager { character: -2, }, )); - let chair = select_chair(&mut self.chairs).ok_or(anyhow!("no free chair found"))?; - let to = self.demand.data.customer_spawn.as_ivec2(); - let path = find_path(&self.walkable, to, chair).ok_or(anyhow!("no path to {to}"))?; + let chair = self.select_chair().ok_or(anyhow!("no free chair found"))?; + let from = data.customer_spawn.as_ivec2(); + let path = find_path(&self.walkable, from, chair) + .ok_or(anyhow!("no path from {from} to {chair}"))?; self.customers.insert( id, Customer { movement: MovementBase { - position: self.demand.data.customer_spawn, + position: data.customer_spawn, facing: Vec2::X, vel: Vec2::ZERO, }, @@ -220,11 +131,11 @@ impl CustomerManager { debug!("{id:?} entering"); packets_out.push((id, path.execute_tick(&mut p.movement, &self.walkable, dt))); if path.is_done() { - let demand = self.demand.generate_demand(); + let demand = DemandIndex(random::<usize>() % self.data.demands.len()); packets_out.push(( id, PacketS::Communicate { - message: Some(Message::Item(self.demand.data.demand(demand).from)), + message: Some(Message::Item(data.demand(demand).from)), }, )); p.state = CustomerState::Waiting { @@ -246,18 +157,27 @@ impl CustomerManager { let path = find_path( &self.walkable, p.movement.position.as_ivec2(), - self.demand.data.customer_spawn.as_ivec2(), + data.customer_spawn.as_ivec2(), ) .expect("no path to exit"); *self.chairs.get_mut(&chair).unwrap() = true; p.state = CustomerState::Exiting { path } } else { - let demand_data = &self.demand.data.demand(*demand); + let demand_data = &data.demand(*demand); let demand_pos = [IVec2::NEG_X, IVec2::NEG_Y, IVec2::X, IVec2::Y] .into_iter() .find_map(|off| { let pos = *chair + off; - if self.items.get(&pos) == Some(&demand_data.from) { + if tiles + .get(&pos) + .map(|t| { + t.item + .as_ref() + .map(|i| i.kind == demand_data.from) + .unwrap_or_default() + }) + .unwrap_or_default() + { Some(pos) } else { None @@ -284,7 +204,7 @@ impl CustomerManager { chair, } => { debug!("{id:?} eating"); - let demand = self.demand.data.demand(*demand); + let demand = data.demand(*demand); *progress += dt / demand.duration; if *progress >= 1. { packets_out.push(( @@ -299,7 +219,7 @@ impl CustomerManager { let path = find_path( &self.walkable, p.movement.position.as_ivec2(), - self.demand.data.customer_spawn.as_ivec2(), + data.customer_spawn.as_ivec2(), ) .ok_or(anyhow!("no path to exit"))?; *self.chairs.get_mut(&chair).unwrap() = true; @@ -321,14 +241,15 @@ impl CustomerManager { } Ok(()) } -} -pub fn select_chair(chairs: &mut HashMap<IVec2, bool>) -> Option<IVec2> { - use rand::seq::IteratorRandom; - let (chosen, free) = chairs - .iter_mut() - .filter(|(_p, free)| **free) - .choose(&mut thread_rng())?; - *free = false; - Some(*chosen) + pub fn select_chair(&mut self) -> Option<IVec2> { + use rand::seq::IteratorRandom; + let (chosen, free) = self + .chairs + .iter_mut() + .filter(|(_p, free)| **free) + .choose(&mut thread_rng())?; + *free = false; + Some(*chosen) + } } diff --git a/server/src/customer/pathfinding.rs b/server/src/customer/pathfinding.rs index 5354407f..5056975e 100644 --- a/server/src/customer/pathfinding.rs +++ b/server/src/customer/pathfinding.rs @@ -1,19 +1,19 @@ /* Undercooked - a game about cooking Copyright 2024 metamuffin - + 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/>. - + */ use super::movement::MovementBase; use crate::protocol::PacketS; @@ -29,22 +29,22 @@ pub struct Path(Vec<Vec2>); impl Path { pub fn execute_tick( &mut self, - customer: &mut MovementBase, + player: &mut MovementBase, walkable: &HashSet<IVec2>, dt: f32, ) -> PacketS { if let Some(next) = self.0.last().copied() { debug!("next {next}"); - if next.distance(customer.position) < if self.0.len() == 1 { 0.1 } else { 0.6 } { + if next.distance(player.position) < if self.0.len() == 1 { 0.1 } else { 0.6 } { self.0.pop(); } - customer.update( + player.update( &walkable, - (next - customer.position).normalize_or_zero() * 0.5, + (next - player.position).normalize_or_zero() * 0.5, dt, ) } else { - customer.update(&walkable, Vec2::ZERO, dt) + player.update(&walkable, Vec2::ZERO, dt) } } pub fn is_done(&self) -> bool { @@ -52,7 +52,7 @@ impl Path { } } -pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Path> { +pub fn find_path(walkable: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Path> { #[derive(Debug, PartialEq, Eq)] struct Open(i32, IVec2, IVec2); impl PartialOrd for Open { @@ -84,7 +84,7 @@ pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Path> { } for d in [IVec2::NEG_X, IVec2::NEG_Y, IVec2::X, IVec2::Y] { let n = p + d; - if map.contains(&n) { + if walkable.contains(&n) { open.push(Open(-d.distance_squared(to), n, p)); } } diff --git a/server/src/game.rs b/server/src/game.rs index defaf7bf..595816e1 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -16,14 +16,14 @@ */ use crate::{ - customer::movement::PLAYER_SPEED_LIMIT, + customer::{movement::PLAYER_SPEED_LIMIT, DemandState}, data::Gamedata, interaction::{interact, tick_tile, InteractEffect, TickEffect}, protocol::{ItemIndex, Message, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex}, }; use anyhow::{anyhow, bail, Result}; use glam::{IVec2, Vec2}; -use log::info; +use log::{info, warn}; use std::{ collections::{HashMap, VecDeque}, ops::Deref, @@ -64,6 +64,7 @@ pub struct Game { tiles: HashMap<IVec2, Tile>, players: HashMap<PlayerID, Player>, packet_out: VecDeque<PacketC>, + demand: Option<DemandState>, } impl Game { @@ -73,6 +74,7 @@ impl Game { packet_out: Default::default(), players: Default::default(), tiles: Default::default(), + demand: None, } } @@ -87,6 +89,7 @@ impl Game { neighbors: [None, None, None, None], }) } + self.demand = None; } pub fn load(&mut self, gamedata: Gamedata) { let players = self @@ -99,6 +102,7 @@ impl Game { self.unload(); self.data = gamedata.into(); + for (&p, (tile, item)) in &self.data.initial_map { self.tiles.insert( p, @@ -126,6 +130,10 @@ impl Game { ); } + if !self.data.demands.is_empty() { + self.demand = Some(DemandState::new(self.data.clone(), &self.tiles)) + } + self.packet_out.extend(self.prime_client()); } @@ -375,6 +383,18 @@ impl Game { } pub fn tick(&mut self, dt: f32) { + if let Some(demand) = &mut self.demand { + let mut packet_out = Vec::new(); + if let Err(err) = demand.tick(&mut packet_out, &mut self.tiles, &self.data, dt) { + warn!("demand tick {err}"); + } + for (player, packet) in packet_out { + if let Err(err) = self.packet_in(player, packet) { + warn!("demand packet {err}"); + } + } + } + for (&pos, tile) in &mut self.tiles { if let Some(effect) = tick_tile(dt, &self.data, tile) { match effect { diff --git a/server/src/main.rs b/server/src/main.rs index b3e6334d..c294478e 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -27,7 +27,6 @@ use tokio::{ }; use tokio_tungstenite::tungstenite::Message; use undercooked::{ - customer::customer, protocol::{PacketC, PacketS, PlayerID}, state::State, }; @@ -53,8 +52,6 @@ async fn main() -> Result<()> { }); } - spawn(customer(state.clone(), rx.resubscribe())); - for id in (1..).map(PlayerID) { let (sock, addr) = ws_listener.accept().await?; let Ok(sock) = tokio_tungstenite::accept_async(sock).await else { diff --git a/server/src/protocol.rs b/server/src/protocol.rs index 262fad8d..daa5c8af 100644 --- a/server/src/protocol.rs +++ b/server/src/protocol.rs @@ -130,6 +130,10 @@ pub enum PacketC { player: PlayerID, message: Option<Message>, }, + Score { + demands_failed: usize, + demands_complete: usize, + }, Error { message: String, }, diff --git a/test-client/protocol.ts b/test-client/protocol.ts index 9a78f263..41ab518d 100644 --- a/test-client/protocol.ts +++ b/test-client/protocol.ts @@ -48,6 +48,7 @@ export type PacketC = | { type: "set_active", tile: Vec2, progress?: number, warn: boolean } // A tile is doing something. progress goes from 0 to 1, then null when finished | { type: "update_map", tile: Vec2, kind: TileIndex | null, neighbors: [TileIndex | null] } // A map tile was changed | { type: "communicate", player: PlayerID, message?: Message } // A player wants to communicate something, message is null when cleared + | { type: "score", demands_failed: number, demands_completed: number, } // Supplies information for score OSD | { type: "error", message?: Message } // Your client did something wrong. export type Message = |