aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/global.gd10
-rw-r--r--client/map/tiles/bark.tres1
-rw-r--r--client/map/tiles/leaves.tres1
-rw-r--r--client/menu/character_menu.gd3
-rw-r--r--client/menu/character_menu.tscn2
-rw-r--r--client/menu/credits_menu.gd7
-rw-r--r--client/menu/credits_menu.tscn12
-rw-r--r--client/menu/error_menu.gd3
-rw-r--r--client/menu/error_menu.tscn2
-rw-r--r--client/menu/ingame_menu.gd13
-rw-r--r--client/menu/ingame_menu.tscn35
-rw-r--r--client/menu/main_menu.gd17
-rw-r--r--client/menu/main_menu.tscn17
-rw-r--r--client/menu/menu_manager.gd36
-rw-r--r--client/menu/menu_manager.tscn38
-rw-r--r--client/menu/scene_transition.gd7
-rw-r--r--client/menu/settings_menu.gd4
-rw-r--r--client/menu/settings_menu.tscn12
-rw-r--r--client/menu/theme/focus_style.tres17
-rw-r--r--client/menu/theme/font-josefin-sans.woff2 (renamed from client/menu/font-josefin-sans.woff2)bin47448 -> 47448 bytes
-rw-r--r--client/menu/theme/font-josefin-sans.woff2.import (renamed from client/menu/font-josefin-sans.woff2.import)6
-rw-r--r--client/menu/theme/font-sansita-swashed.woff2 (renamed from client/menu/font-sansita-swashed.woff2)bin92808 -> 92808 bytes
-rw-r--r--client/menu/theme/font-sansita-swashed.woff2.import (renamed from client/menu/font-sansita-swashed.woff2.import)6
-rw-r--r--client/menu/theme/theme.tres (renamed from client/menu/theme.tres)19
-rw-r--r--client/player/chat_message.tscn2
-rw-r--r--client/project.godot10
-rw-r--r--server/src/customer/mod.rs205
-rw-r--r--server/src/customer/pathfinding.rs22
-rw-r--r--server/src/game.rs24
-rw-r--r--server/src/main.rs3
-rw-r--r--server/src/protocol.rs4
-rw-r--r--test-client/protocol.ts1
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
index dce2708f..dce2708f 100644
--- a/client/menu/font-josefin-sans.woff2
+++ b/client/menu/theme/font-josefin-sans.woff2
Binary files differ
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
index 5c665fb0..5c665fb0 100644
--- a/client/menu/font-sansita-swashed.woff2
+++ b/client/menu/theme/font-sansita-swashed.woff2
Binary files differ
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 =