aboutsummaryrefslogtreecommitdiff
path: root/client/gui
diff options
context:
space:
mode:
authornokoe <nokoe@mailbox.org>2025-10-09 23:50:01 +0200
committernokoe <nokoe@mailbox.org>2025-10-09 23:50:55 +0200
commit5879059a6757d471218eac3508ba3d28fcce8604 (patch)
tree33979305fc773bf1a3c5707bfd18a8434d44405e /client/gui
parent0dc7bc9f3cf8088b670d5444fc4e0ce58a7ec1cc (diff)
downloadhurrycurry-5879059a6757d471218eac3508ba3d28fcce8604.tar
hurrycurry-5879059a6757d471218eac3508ba3d28fcce8604.tar.bz2
hurrycurry-5879059a6757d471218eac3508ba3d28fcce8604.tar.zst
add book
Diffstat (limited to 'client/gui')
-rw-r--r--client/gui/components/message/renderer.gd41
-rw-r--r--client/gui/components/message/renderer.gd.uid1
-rw-r--r--client/gui/components/message/renderer.tscn40
-rw-r--r--client/gui/menus/book/book.gd76
-rw-r--r--client/gui/menus/book/book.gd.uid1
-rw-r--r--client/gui/menus/book/book.tscn28
-rw-r--r--client/gui/menus/book/diagram.gd96
-rw-r--r--client/gui/menus/book/diagram.gd.uid1
8 files changed, 284 insertions, 0 deletions
diff --git a/client/gui/components/message/renderer.gd b/client/gui/components/message/renderer.gd
new file mode 100644
index 00000000..32437c8c
--- /dev/null
+++ b/client/gui/components/message/renderer.gd
@@ -0,0 +1,41 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2025 Hurry Curry! contributors
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, version 3 of the License only.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+class_name Renderer
+extends SubViewportContainer
+
+enum Mode {
+ ITEMS,
+ TILES
+}
+
+@onready var camera = $SubViewport/Node3D/Camera3D
+@onready var base = $SubViewport/Node3D
+
+var current_object: Node3D = null
+var mode: Mode
+
+func setup_object(object_name: String):
+ if current_object: current_object.queue_free()
+ match mode:
+ Mode.ITEMS:
+ current_object = ItemFactory.produce(object_name, base)
+ Mode.TILES:
+ var tf = TileFactory.new()
+ current_object = tf.produce(object_name, Vector2i(0, 0), ["counter", "floor", "counter", null])
+ current_object.rotation_degrees.y = 45.
+ current_object.translate(Vector3(-0.5, 0.0, -0.5))
+ camera.size = 2.
+ base.add_child(current_object)
diff --git a/client/gui/components/message/renderer.gd.uid b/client/gui/components/message/renderer.gd.uid
new file mode 100644
index 00000000..333f8bb2
--- /dev/null
+++ b/client/gui/components/message/renderer.gd.uid
@@ -0,0 +1 @@
+uid://bv6faf7woy4yo
diff --git a/client/gui/components/message/renderer.tscn b/client/gui/components/message/renderer.tscn
new file mode 100644
index 00000000..4561843f
--- /dev/null
+++ b/client/gui/components/message/renderer.tscn
@@ -0,0 +1,40 @@
+[gd_scene load_steps=4 format=3 uid="uid://hdgsa0yfhnfw"]
+
+[ext_resource type="Script" uid="uid://bv6faf7woy4yo" path="res://gui/components/message/renderer.gd" id="1_3x5y3"]
+
+[sub_resource type="BoxMesh" id="BoxMesh_pcjn7"]
+
+[sub_resource type="Environment" id="Environment_vdkpo"]
+background_mode = 1
+background_color = Color(0, 0, 0, 0)
+ambient_light_source = 2
+ambient_light_color = Color(1, 1, 1, 1)
+
+[node name="Renderer" type="SubViewportContainer"]
+offset_right = 512.0
+offset_bottom = 512.0
+script = ExtResource("1_3x5y3")
+
+[node name="SubViewport" type="SubViewport" parent="."]
+own_world_3d = true
+transparent_bg = true
+handle_input_locally = false
+render_target_update_mode = 4
+
+[node name="Node3D" type="Node3D" parent="SubViewport"]
+
+[node name="DebugPlaceholder" type="MeshInstance3D" parent="SubViewport/Node3D"]
+visible = false
+mesh = SubResource("BoxMesh_pcjn7")
+skeleton = NodePath("../../../..")
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="SubViewport/Node3D"]
+environment = SubResource("Environment_vdkpo")
+
+[node name="Camera3D" type="Camera3D" parent="SubViewport/Node3D"]
+transform = Transform3D(1, 0, 0, 0, 0.8660254, 0.5, 0, -0.5, 0.8660254, 0, 2, 3)
+projection = 1
+far = 30.0
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="SubViewport/Node3D"]
+transform = Transform3D(0.7071067, 0.49999997, -0.4999999, 0, 0.70710677, 0.7071067, 0.7071067, -0.49999997, 0.4999999, 0, 0, 0)
diff --git a/client/gui/menus/book/book.gd b/client/gui/menus/book/book.gd
new file mode 100644
index 00000000..7b0bcec5
--- /dev/null
+++ b/client/gui/menus/book/book.gd
@@ -0,0 +1,76 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2025 Hurry Curry! contributors
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, version 3 of the License only.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+class_name BookMenu
+extends Menu
+
+const MARGIN: int = 75
+const PAGE_WIDTH: float = 500.
+const ASPECT_RATIO: float = sqrt(2)
+
+var labels := {}
+
+class BookData:
+ var game: Game
+ var data: Dictionary
+
+ func _init(game_, data_) -> void:
+ game = game_
+ data = data_
+
+var book_data: BookData
+
+func _ready():
+ super()
+ book_data = data
+ build_book(book_data.data)
+
+func build_book(d: Dictionary) -> void:
+ var pages: Array = d.pages
+ for p: Dictionary in pages:
+ var page := Page.new()
+ match p.page_type:
+ "contents":
+ pass
+ "recipe":
+ var title_string: String = MessageParser.new(p["title"]).parse(book_data.game)
+ var title = Label.new()
+ title.text = title_string
+ page.left.add_child(title)
+ page.right.add_child(Diagram.new(p["diagram"], book_data.game))
+ _: push_error("%s not known" % p.page_type)
+ $ScrollContainer/VBoxContainer.add_child(page)
+ return Control.new()
+
+class Page:
+ extends HBoxContainer
+ var left: Control
+ var right: Control
+ var title: bool = false:
+ set(val):
+ left.visible = !val
+
+ func single_page() -> Control:
+ var node = PanelContainer.new()
+ node.name = "Page"
+ node.add_theme_stylebox_override("panel", preload("res://gui/resources/style/paper_panel_style.tres"))
+ node.set_custom_minimum_size(Vector2(PAGE_WIDTH, PAGE_WIDTH * ASPECT_RATIO))
+ return node
+
+ func _init():
+ left = single_page()
+ right = single_page()
+ add_child(left)
+ add_child(right)
diff --git a/client/gui/menus/book/book.gd.uid b/client/gui/menus/book/book.gd.uid
new file mode 100644
index 00000000..9bda6bc4
--- /dev/null
+++ b/client/gui/menus/book/book.gd.uid
@@ -0,0 +1 @@
+uid://d1jive3atu4k7
diff --git a/client/gui/menus/book/book.tscn b/client/gui/menus/book/book.tscn
new file mode 100644
index 00000000..1e037843
--- /dev/null
+++ b/client/gui/menus/book/book.tscn
@@ -0,0 +1,28 @@
+[gd_scene load_steps=3 format=3 uid="uid://bdggwo8un3mys"]
+
+[ext_resource type="Script" uid="uid://d1jive3atu4k7" path="res://gui/menus/book/book.gd" id="1_gyisx"]
+[ext_resource type="Script" uid="uid://bd7bylb2t2m0" path="res://gui/components/touch_scroll_container.gd" id="2_0d0p0"]
+
+[node name="Book" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1_gyisx")
+support_anim = false
+
+[node name="ScrollContainer" type="ScrollContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("2_0d0p0")
+
+[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 6
+size_flags_vertical = 4
diff --git a/client/gui/menus/book/diagram.gd b/client/gui/menus/book/diagram.gd
new file mode 100644
index 00000000..4a8c4dc4
--- /dev/null
+++ b/client/gui/menus/book/diagram.gd
@@ -0,0 +1,96 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2025 Hurry Curry! contributors
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, version 3 of the License only.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+class_name Diagram
+extends Control
+
+const RENDERER := preload("res://gui/components/message/renderer.tscn")
+const SIZE: float = 64.;
+const HSIZE: float = SIZE / 2.;
+
+var raw: Dictionary
+var nodes: Array#[DiagramNode]
+var edges: Array#[DiagramEdge]
+
+class DiagramNode:
+ var position: Vector2
+ var label: MessageParser
+ var style: String
+
+ func _init(raw: Dictionary, game: Game):
+ position = Vector2(raw["position"][0], raw["position"][1])
+ label = MessageParser.new(raw["label"])
+ style = raw["style"]
+ label.parse(game)
+
+class DiagramEdge:
+ var src: int
+ var dst: int
+
+ func _init(raw: Dictionary):
+ src = raw["src"]
+ dst = raw["dst"]
+
+func _init(raw_: Dictionary, game: Game) -> void:
+ raw = raw_
+ nodes = raw["nodes"].map(func(r): return DiagramNode.new(r, game))
+ edges = raw["edges"].map(func(r): return DiagramEdge.new(r))
+
+func _ready() -> void:
+ for n: DiagramNode in nodes:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2i(SIZE, SIZE)
+ add_child(r)
+ r.position = n.position - Vector2(HSIZE, HSIZE)
+ match n.label.kind:
+ MessageParser.Kind.ITEM: r.mode = Renderer.Mode.ITEMS
+ MessageParser.Kind.TILE: r.mode = Renderer.Mode.TILES
+ r.setup_object(n.label.result)
+
+func _draw() -> void:
+ for n: DiagramNode in nodes:
+ match n.style:
+ "intermediate_product":
+ draw_circle(n.position, HSIZE, Color("#555"), true, -1., true)
+ "final_product":
+ draw_circle(n.position, HSIZE, Color("#333"), true, -1., true)
+ "process_active":
+ draw_rect(Rect2(n.position - Vector2(HSIZE, HSIZE), Vector2(SIZE, SIZE)), Color("#47c42b"))
+ "process_passive":
+ draw_rect(Rect2(n.position - Vector2(HSIZE, HSIZE), Vector2(SIZE, SIZE)), Color("#c4a32b"))
+ "process_instant":
+ draw_rect(Rect2(n.position - Vector2(HSIZE, HSIZE), Vector2(SIZE, SIZE)), Color("#5452d8"))
+
+ for e: DiagramEdge in edges:
+ var src_node: DiagramNode = nodes[e.src]
+ var dst_node: DiagramNode = nodes[e.dst]
+ var src := node_edge_connect_pos(src_node, dst_node)
+ var dst := node_edge_connect_pos(dst_node, src_node)
+
+ var dir = (src - dst).normalized();
+ var tip0 = dst;
+ var tip1 = dst + dir.rotated(0.2 * PI) * 10.;
+ var tip2 = dst + dir.rotated(-0.2 * PI) * 10.;
+ dst += dir * 5.
+
+ draw_colored_polygon([tip0, tip1, tip2], Color.BLACK)
+ draw_line(src, dst, Color.BLACK, 2., true)
+
+func node_edge_connect_pos(src: DiagramNode, dst: DiagramNode) -> Vector2:
+ var dir = (dst.position - src.position).normalized()
+ if src.style == "intermediate_product" or src.style == "final_product":
+ return src.position + dir * HSIZE
+ else:
+ return src.position + dir / abs(dir.y) * HSIZE
diff --git a/client/gui/menus/book/diagram.gd.uid b/client/gui/menus/book/diagram.gd.uid
new file mode 100644
index 00000000..debd91e5
--- /dev/null
+++ b/client/gui/menus/book/diagram.gd.uid
@@ -0,0 +1 @@
+uid://jqmllc8hafx0