aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/game.gd13
-rw-r--r--client/global.gd6
-rw-r--r--client/gui/components/message/renderer.gd12
-rw-r--r--client/gui/components/message/renderer.tscn3
-rw-r--r--client/gui/menus/book/book.gd9
-rw-r--r--client/gui/menus/book/diagram.gd2
-rw-r--r--client/gui/overlays/popup_message/font_variation.tres10
-rw-r--r--client/gui/overlays/popup_message/popup_message.gd7
-rw-r--r--client/gui/overlays/popup_message/server_message.gd53
-rw-r--r--client/gui/overlays/popup_message/server_message.tscn35
-rw-r--r--client/message_parser.gd35
11 files changed, 121 insertions, 64 deletions
diff --git a/client/game.gd b/client/game.gd
index 87a3ce2e..b4221fd3 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -236,8 +236,7 @@ func handle_packet(p):
var timeout_remaining: float = p.timeout.remaining if p.timeout != null else 5.
var pinned: bool = p.timeout.pinned if p.timeout != null and "pinned" in p.timeout else false
if p.message != null:
- var m = MessageParser.new(p.message)
- m.parse(self)
+ var m = MessageParser.new(p.message, self)
match m.kind:
MessageParser.Kind.ITEM:
var item_name: String = m.result
@@ -358,12 +357,10 @@ func handle_packet(p):
"book":
menu.submenu("res://gui/menus/book/book.tscn", BookMenu.BookData.new(self, p.data))
"server_message":
- var m := MessageParser.new(p.message)
- m.parse(self)
if p.error:
- overlay_popup_message.display_server_msg(tr("c.error.server").format([m.result]))
+ overlay_popup_message.display_server_msg(tr("c.error.server").format([MessageParser.new(p.message, self).result]))
else:
- overlay_popup_message.display_server_msg(m.result)
+ overlay_popup_message.display_server_msg(MessageParser.new(p.message, self).result)
"server_hint":
if p.player != my_player_id: return
@@ -375,13 +372,13 @@ func handle_packet(p):
if message == null:
overlay_popup_message.clear_server_msg()
else:
- overlay_popup_message.display_server_msg(MessageParser.new(message).parse(self), false)
+ overlay_popup_message.display_server_msg(MessageParser.new(message, self).result, false)
else:
# Positional hint message
if message == null:
overlay_popup_message.clear_server_msg(position_)
else:
- overlay_popup_message.display_server_msg_positional(MessageParser.new(message).parse(self), position_, false)
+ overlay_popup_message.display_server_msg_positional(MessageParser.new(message, self).result, position_, false)
"environment":
$Environment.update(p.effects)
"redirect":
diff --git a/client/global.gd b/client/global.gd
index 4fe3d52e..bcf44998 100644
--- a/client/global.gd
+++ b/client/global.gd
@@ -114,12 +114,6 @@ func find_menu(node: Node) -> Menu:
if node is Menu: return node
else: return find_menu(node.get_parent())
-# TODO: move function into MessageParser
-func get_message_str(m: Dictionary) -> String:
- if "text" in m: return m.text
- if "translation" in m: return tr(m.translation.id).format(m.translation.params.map(get_message_str))
- return "[unsupported message type]"
-
func language_list():
var a = TranslationServer.get_loaded_locales()
a.sort()
diff --git a/client/gui/components/message/renderer.gd b/client/gui/components/message/renderer.gd
index 32437c8c..9520caca 100644
--- a/client/gui/components/message/renderer.gd
+++ b/client/gui/components/message/renderer.gd
@@ -21,9 +21,6 @@ enum Mode {
TILES
}
-@onready var camera = $SubViewport/Node3D/Camera3D
-@onready var base = $SubViewport/Node3D
-
var current_object: Node3D = null
var mode: Mode
@@ -31,11 +28,12 @@ func setup_object(object_name: String):
if current_object: current_object.queue_free()
match mode:
Mode.ITEMS:
- current_object = ItemFactory.produce(object_name, base)
+ current_object = ItemFactory.produce(object_name, $SubViewport/Node3D/Base)
+ current_object.rotation.y = 0.25 * PI
+ $SubViewport/Node3D/Camera3D.size = 1.
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)
+ $SubViewport/Node3D/Camera3D.size = 2.
+ $SubViewport/Node3D/Base.add_child(current_object)
diff --git a/client/gui/components/message/renderer.tscn b/client/gui/components/message/renderer.tscn
index 4561843f..57797eb5 100644
--- a/client/gui/components/message/renderer.tscn
+++ b/client/gui/components/message/renderer.tscn
@@ -38,3 +38,6 @@ 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)
+
+[node name="Base" type="Node3D" parent="SubViewport/Node3D"]
+transform = Transform3D(0.70710677, 0, 0.70710677, 0, 1, 0, -0.70710677, 0, 0.70710677, 0, 0, 0)
diff --git a/client/gui/menus/book/book.gd b/client/gui/menus/book/book.gd
index f6d95c8a..768259ad 100644
--- a/client/gui/menus/book/book.gd
+++ b/client/gui/menus/book/book.gd
@@ -53,17 +53,16 @@ func build_page() -> void:
var p: Dictionary = pages[current_page]
match p.page_type:
"contents":
- var title := build_title(MessageParser.new(p["title"]).parse(book_data.game))
+ var title := build_title(MessageParser.new(p["title"], book_data.game).result)
var vbox := VBoxContainer.new()
vbox.add_child(title)
for i: Array in p.table:
- var m := MessageParser.new(i[0])
- m.parse(book_data.game)
+ var m := MessageParser.new(i[0], book_data.game)
vbox.add_child(build_contents_entry(m.result, i[1]))
second.add_child(vbox)
"recipe":
- var title := build_title(MessageParser.new(p["title"]).parse(book_data.game))
- var par := build_paragraph(MessageParser.new(p["description"]).parse(book_data.game))
+ var title := build_title(MessageParser.new(p["title"], book_data.game).result)
+ var par := build_paragraph(MessageParser.new(p["description"], book_data.game).result)
var vbox := VBoxContainer.new()
vbox.add_child(title)
vbox.add_child(par)
diff --git a/client/gui/menus/book/diagram.gd b/client/gui/menus/book/diagram.gd
index 65209c64..a57bcfc9 100644
--- a/client/gui/menus/book/diagram.gd
+++ b/client/gui/menus/book/diagram.gd
@@ -33,7 +33,7 @@ class DiagramNode:
func _init(raw: Dictionary, game: Game):
position = Vector2(raw["position"][0], raw["position"][1])
- label = MessageParser.new(raw["label"])
+ label = MessageParser.new(raw["label"], game)
style = raw["style"]
label.parse(game)
diff --git a/client/gui/overlays/popup_message/font_variation.tres b/client/gui/overlays/popup_message/font_variation.tres
new file mode 100644
index 00000000..ad394ae7
--- /dev/null
+++ b/client/gui/overlays/popup_message/font_variation.tres
@@ -0,0 +1,10 @@
+[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://c4g6ucr5piwy1"]
+
+[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="1_gewoj"]
+
+[resource]
+resource_local_to_scene = true
+base_font = ExtResource("1_gewoj")
+variation_opentype = {
+2003265652: 400
+}
diff --git a/client/gui/overlays/popup_message/popup_message.gd b/client/gui/overlays/popup_message/popup_message.gd
index 47ad6088..dd4c67bf 100644
--- a/client/gui/overlays/popup_message/popup_message.gd
+++ b/client/gui/overlays/popup_message/popup_message.gd
@@ -22,7 +22,6 @@ var positional_messages = {}
@onready var positional_messages_node: Control = $Positional
@onready var server_msg = $Static/VBox/ServerMessage
-@onready var server_msg_label: Label = $Static/VBox/ServerMessage/CenterContainer/Label
@onready var server_msg_timer: Timer = $ServerMessage
@onready var game: Game = $"../../Game" # TODO
@@ -45,9 +44,9 @@ func _process(_delta: float):
msg.last_size = msg.node.size
msg.node.position = -0.5 * msg.last_size
-func display_server_msg(msg: String, auto_remove := true):
+func display_server_msg(msg, auto_remove := true):
server_msg.show()
- server_msg_label.text = msg
+ server_msg.set_text(msg)
if auto_remove:
server_msg_timer.start()
@@ -55,7 +54,7 @@ func display_server_msg(msg: String, auto_remove := true):
func _on_server_timeout() -> void:
clear_server_msg()
-func display_server_msg_positional(text: String, pos: Vector2, use_monospace: bool):
+func display_server_msg_positional(text, pos: Vector2, use_monospace: bool):
var msg := PositionalMessage.new()
msg.node = SERVER_MESSAGE_SCENE.instantiate()
msg.node_2d = Node2D.new()
diff --git a/client/gui/overlays/popup_message/server_message.gd b/client/gui/overlays/popup_message/server_message.gd
index 76ff9361..ad3c5ed3 100644
--- a/client/gui/overlays/popup_message/server_message.gd
+++ b/client/gui/overlays/popup_message/server_message.gd
@@ -18,11 +18,54 @@ class_name ServerMessage
const DEFAULT_FONT = preload("res://gui/resources/fonts/font-josefin-sans.woff2")
const MONOSPACE_FONT = preload("res://gui/resources/fonts/font-azaret-mono.woff2")
+const RENDERER = preload("res://gui/components/message/renderer.tscn")
-@onready var label: Label = $CenterContainer/Label
+@onready var flow: VFlowContainer = $CenterContainer/VFlowContainer
-func set_text(text: String, use_monospace := true):
- label.text = text
- var font: FontVariation = label.get_theme_font("font")
+func set_text(text, use_monospace := true):
+ for c: Node in flow.get_children():
+ c.queue_free()
+ if text is String:
+ flow.add_child(build_label(text, use_monospace))
+ elif text is Array:
+ for e: MessageParser in text:
+ var c: Control = build_message(e, use_monospace)
+ c.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ c.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ flow.add_child(c)
+
+static func font_size(use_monospace: bool):
+ return 16 if use_monospace else 20
+
+func build_label(text: String, use_monospace: bool) -> Label:
+ var label = Label.new()
+ var font: FontVariation = preload("res://gui/overlays/popup_message/font_variation.tres")
+ var sb := StyleBoxEmpty.new()
font.base_font = MONOSPACE_FONT if use_monospace else DEFAULT_FONT
- label.add_theme_font_size_override("font_size", 16 if use_monospace else 20)
+ label.add_theme_font_size_override("font_size", font_size(use_monospace))
+ label.add_theme_font_override("font", font)
+ label.add_theme_color_override("font_color", Color.BLACK)
+ label.add_theme_stylebox_override("normal", sb)
+ label.autowrap_mode = TextServer.AUTOWRAP_OFF
+ label.text = text
+ label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ label.update_minimum_size()
+ return label
+
+func build_message(m: MessageParser, use_monospace: bool) -> Control:
+ match m.kind:
+ MessageParser.Kind.ITEM:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2i.ONE * font_size(use_monospace) * 2
+ r.mode = Renderer.Mode.ITEMS
+ r.setup_object(m.result)
+ return r
+ MessageParser.Kind.TILE:
+ var r: Renderer = RENDERER.instantiate()
+ r.get_node("SubViewport").size = Vector2i.ONE * font_size(use_monospace) * 2
+ r.mode = Renderer.Mode.TILES
+ r.setup_object(m.result)
+ return r
+ MessageParser.Kind.TEXT:
+ return build_label(m.result, use_monospace)
+ return null
diff --git a/client/gui/overlays/popup_message/server_message.tscn b/client/gui/overlays/popup_message/server_message.tscn
index 255c5e56..40feada1 100644
--- a/client/gui/overlays/popup_message/server_message.tscn
+++ b/client/gui/overlays/popup_message/server_message.tscn
@@ -1,8 +1,7 @@
-[gd_scene load_steps=8 format=3 uid="uid://dq61p3a8og2b6"]
+[gd_scene load_steps=5 format=3 uid="uid://dq61p3a8og2b6"]
[ext_resource type="Shader" uid="uid://cwldxegcj55if" path="res://gui/resources/shaders/blur_mix.gdshader" id="1_qv8ew"]
[ext_resource type="Script" uid="uid://dfgwh7x7sqc21" path="res://gui/overlays/popup_message/server_message.gd" id="2_csqo8"]
-[ext_resource type="FontFile" uid="uid://bk704sc5gkrb3" path="res://gui/resources/fonts/font-azaret-mono.woff2" id="3_dw20j"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_q3bbd"]
shader = ExtResource("1_qv8ew")
@@ -19,35 +18,27 @@ corner_radius_top_right = 16
corner_radius_bottom_right = 16
corner_radius_bottom_left = 16
-[sub_resource type="FontVariation" id="FontVariation_qfltj"]
-resource_local_to_scene = true
-base_font = ExtResource("3_dw20j")
-variation_opentype = {
-2003265652: 400
-}
-
-[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3rgop"]
-content_margin_left = 32.0
-content_margin_top = 8.0
-content_margin_right = 32.0
-content_margin_bottom = 8.0
-
[node name="ServerMessage" type="PanelContainer"]
material = SubResource("ShaderMaterial_q3bbd")
+offset_right = 210.0
+offset_bottom = 35.0
size_flags_horizontal = 4
size_flags_vertical = 0
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_vq4dg")
script = ExtResource("2_csqo8")
-[node name="CenterContainer" type="CenterContainer" parent="."]
+[node name="CenterContainer" type="MarginContainer" parent="."]
layout_mode = 2
mouse_filter = 2
+theme_override_constants/margin_left = 32
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_right = 32
+theme_override_constants/margin_bottom = 8
-[node name="Label" type="Label" parent="CenterContainer"]
+[node name="VFlowContainer" type="VFlowContainer" parent="CenterContainer"]
+layout_direction = 1
layout_mode = 2
-theme_override_colors/font_color = Color(0, 0, 0, 1)
-theme_override_fonts/font = SubResource("FontVariation_qfltj")
-theme_override_font_sizes/font_size = 16
-theme_override_styles/normal = SubResource("StyleBoxEmpty_3rgop")
-text = "Server message"
+theme_override_constants/h_separation = 0
+theme_override_constants/v_separation = 0
+last_wrap_alignment = 2
diff --git a/client/message_parser.gd b/client/message_parser.gd
index 64be0411..d9c08f88 100644
--- a/client/message_parser.gd
+++ b/client/message_parser.gd
@@ -18,7 +18,8 @@ extends Object
var raw: Dictionary
var kind := Kind.UNKNOWN
-var result = null
+var result
+var game: Game
enum Kind {
ITEM,
@@ -28,21 +29,43 @@ enum Kind {
UNKNOWN
}
-func _init(raw_: Dictionary) -> void:
+func _init(raw_: Dictionary, game_: Game) -> void:
raw = raw_
-
-func parse(game: Game) -> String:
+ game = game_
if "text" in raw:
kind = Kind.TEXT
result = raw["text"]
elif "translation" in raw:
kind = Kind.TRANSLATION
# TODO: move function here
- result = Global.get_message_str(raw)
+ var params: Array = raw.translation.params.map(MessageParser.new.bind(game))
+ var unformatted := tr(raw.translation.id)
+ result = split_translation(unformatted, 0, params)
+ if result.size() == 1 && result[0].kind == Kind.TEXT:
+ kind = Kind.TEXT
+ result = result[0].result
elif "tile" in raw:
kind = Kind.TILE
result = game.tile_names[raw["tile"]]
elif "item" in raw:
kind = Kind.ITEM
result = game.item_names[raw["item"]]
- return result
+
+func split_translation(msgstr: String, idx: int, params: Array) -> Array:
+ if msgstr.contains("{%d}" % idx):
+ var s := msgstr.split("{%d}" % idx, true, 1)
+ var l := split_translation(s[0], idx + 1, params)
+ if params[idx].kind == Kind.TRANSLATION:
+ l.append_array(params[idx].result)
+ else:
+ l.push_back(params[idx])
+ var r := split_translation(s[1], idx + 1, params)
+ l.append_array(r)
+ var res := [l.front()]
+ for e: MessageParser in l.slice(1):
+ if res.back().kind == Kind.TEXT and e.kind == Kind.TEXT:
+ res.back().result = "%s%s" % [res.back().result, e.result]
+ else:
+ res.push_back(e)
+ return res
+ else: return [] if msgstr.is_empty() else [MessageParser.new({"text": msgstr}, game)]