使用 InspectorBalloon 展示 prop 信息,避免 dialog 冲突

This commit is contained in:
cakipaul 2025-07-27 23:19:28 +08:00
parent 637132f878
commit a07f78e1d0
6 changed files with 186 additions and 22 deletions

View File

@ -34,6 +34,10 @@ func _load_item_buttons() -> void:
# prop keys
var inventory = hud.inventory
for prop_key in inventory.important_items:
if not hud.items_dict.has(prop_key):
printerr("Important item not found in items_dict: ", prop_key)
continue
hud.items_description_dict.has(prop_key)
var button = preload("uid://wxd25ec3cqyy").instantiate()
button.text = tr(prop_key)
button.pressed.connect(_display_item.bind(prop_key, button))

View File

@ -0,0 +1,89 @@
class_name InspectorBalloon
extends MarginContainer
signal quitted(is_manually: bool)
@export var prop_title_to_content_wait_time := 3.0
@export var auto_quit_time := 5.0
@onready var character_label = %CharacterLabel as RichTextLabel
@onready var content_label = %ContentLabel as RichTextLabel
enum { DISPLAYING_NONE, DISPLAYING_TITLE, DISPLAYING_CONTENT }
var _display_mutex := Mutex.new()
var _displaying_status := DISPLAYING_NONE
var _pending_content := ""
var _balloon_tween: Tween
func _ready() -> void:
character_label.text = ""
content_label.text = ""
func show_prop_balloon(obtain_str: String, prop_title: String, content: String) -> void:
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
_balloon_tween = create_tween()
show()
_pending_content = content
# 如果有获得的物品名称,则显示标题,否则直接显示内容
if not obtain_str.is_empty():
obtain_str = "[color=orange]" + obtain_str + "[/color]"
_displaying_status = DISPLAYING_TITLE
else:
_display_content()
_display_mutex.unlock()
return
character_label.show()
character_label.text = obtain_str
content_label.text = prop_title
if not _pending_content.is_empty():
_balloon_tween.tween_interval(prop_title_to_content_wait_time)
_balloon_tween.tween_callback(_display_content)
else:
_balloon_tween.tween_interval(auto_quit_time)
_balloon_tween.tween_callback(_finished.bind(false))
_display_mutex.unlock()
func _display_content() -> void:
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
_balloon_tween = create_tween()
_displaying_status = DISPLAYING_CONTENT
character_label.hide()
content_label.text = _pending_content
_pending_content = ""
_balloon_tween.tween_interval(auto_quit_time)
_balloon_tween.tween_callback(_finished.bind(false))
_display_mutex.unlock()
func _finished(manually: bool) -> void:
_display_mutex.lock()
character_label.text = ""
content_label.text = ""
_displaying_status = DISPLAYING_NONE
hide()
quitted.emit(manually)
_display_mutex.unlock()
func _input(event: InputEvent) -> void:
_display_mutex.lock()
if _displaying_status == DISPLAYING_NONE:
_display_mutex.unlock()
return
if event.is_action_pressed("interact") or event.is_action_pressed("cancel"):
get_viewport().set_input_as_handled()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
if not _pending_content.is_empty() and _displaying_status == DISPLAYING_TITLE:
_display_content()
else:
_finished(true)
_display_mutex.unlock()

View File

@ -0,0 +1 @@
uid://dhjjskfl8r5nk

View File

@ -0,0 +1,76 @@
[gd_scene load_steps=4 format=3 uid="uid://dufshurokh0ws"]
[ext_resource type="Theme" uid="uid://dlrwa60futc45" path="res://config/balloon_theme.tres" id="1_wqjpu"]
[ext_resource type="Script" uid="uid://dhjjskfl8r5nk" path="res://scene/ux/inspector_balloon.gd" id="2_d4kw8"]
[ext_resource type="PackedScene" uid="uid://ckvgyvclnwggo" path="res://addons/dialogue_manager/dialogue_label.tscn" id="2_kla48"]
[node name="InspectorBalloon" type="MarginContainer"]
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -35.5
offset_top = -69.0
offset_right = 35.5
grow_horizontal = 2
grow_vertical = 0
focus_mode = 2
mouse_filter = 2
theme = ExtResource("1_wqjpu")
theme_override_constants/margin_bottom = 38
script = ExtResource("2_d4kw8")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
mouse_filter = 2
[node name="Panel" type="MarginContainer" parent="VBoxContainer"]
clip_children = 2
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
mouse_filter = 2
theme_override_constants/margin_left = 0
theme_override_constants/margin_top = 0
theme_override_constants/margin_right = 0
theme_override_constants/margin_bottom = 5
[node name="Container" type="HBoxContainer" parent="VBoxContainer/Panel"]
layout_direction = 1
layout_mode = 2
mouse_filter = 2
alignment = 1
[node name="CharacterLabel" type="RichTextLabel" parent="VBoxContainer/Panel/Container"]
unique_name_in_owner = true
clip_contents = false
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 0
mouse_filter = 2
theme_override_colors/font_shadow_color = Color(0.305882, 0.305882, 0.305882, 0.388235)
theme_override_constants/shadow_offset_y = 1
theme_override_constants/shadow_offset_x = 1
bbcode_enabled = true
text = "c"
fit_content = true
scroll_active = false
autowrap_mode = 0
[node name="ContentLabel" parent="VBoxContainer/Panel/Container" instance=ExtResource("2_kla48")]
unique_name_in_owner = true
clip_contents = false
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 0
mouse_filter = 2
theme_override_colors/font_shadow_color = Color(0.306923, 0.306923, 0.306923, 0.388235)
theme_override_constants/shadow_offset_y = 1
theme_override_constants/shadow_offset_x = 1
text = "l"
autowrap_mode = 0
seconds_per_step = 0.005
seconds_per_pause_step = 0.1

View File

@ -19,6 +19,8 @@ signal quit_and_hidden
@onready var scroll_container = %ScrollContainer as ScrollContainer
@onready var content_label = %ContentLabel as Label
@onready var tip_label = %TipLabel as Label
@onready var inspector_balloon = %InspectorBalloon as InspectorBalloon
var tip_cover = "Q: " + tr("ui_退出") + " " + "E: " + tr("ui_阅读")
var tip_notes = "Q: " + tr("ui_退出") + " " + "E: " + tr("ui_收起")
@ -41,6 +43,11 @@ func _ready() -> void:
full_texture.modulate.a = 0.0
content_label.modulate.a = 0.0
tip_label.modulate.a = 0.0
inspector_balloon.quitted.connect(_on_inspector_balloon_quitted)
func _on_inspector_balloon_quitted(_is_manually: bool):
_hide()
func _hide():
@ -127,8 +134,6 @@ var locking = false:
SceneManager.unlock_player()
_lock_mutex.unlock()
var balloon
func pop_prop_inspection(
prop_key: String,
@ -163,31 +168,16 @@ func pop_prop_inspection(
# 显示道具获得提示
if prop_key:
var prop_title = tr(prop_key)
var text = "~ title\n"
var obtain_str = ""
if display_obtained:
var obtain_str = tr("ui_获得道具")
obtain_str = tr("ui_获得道具")
if as_important_item:
obtain_str = tr("ui_获得重要物品")
text += obtain_str + ": " + prop_title + "[#item]\n"
# 道具的一句话说明
var original_word_lines = tr(prop_key + "_说明").replace("{br}", "\n").split("\n")
# 缩略只要第一行
text += original_word_lines[0] + ("..." if len(original_word_lines) > 1 else "")
text += "\n=> END"
var current_prop_res = DialogueManager.create_resource_from_text(text)
# 手动跳过的同时显示下一句
if is_instance_valid(balloon):
balloon.queue_free()
else:
DialogueManager.dialogue_ended.connect(
_on_inspecting_prop_words_ended, CONNECT_ONE_SHOT
)
balloon = preload("res://scene/dialog/balloon.tscn").instantiate()
DialogueManager.show_dialogue_balloon_scene(balloon, current_prop_res, "title")
func _on_inspecting_prop_words_ended(_res):
_hide()
var content = original_word_lines[0] + ("..." if len(original_word_lines) > 1 else "")
inspector_balloon.show_prop_balloon(obtain_str, prop_title, content)
func _show_prop_words(line_id: String):

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=5 format=3 uid="uid://cekhj65axie0p"]
[gd_scene load_steps=6 format=3 uid="uid://cekhj65axie0p"]
[ext_resource type="Script" uid="uid://1xdb7s1nigv8" path="res://scene/ux/prop_inspector.gd" id="1_2wpwe"]
[ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/遮罩/inspect背景遮罩.png" id="2_j83lq"]
[ext_resource type="Texture2D" uid="uid://cvgw2mxrlr6io" path="res://asset/art/scene/c02/旧版/s02_走道/ux_进门鼠疫海报yz.png" id="2_wr575"]
[ext_resource type="FontVariation" uid="uid://1ryw42kej6lv" path="res://config/font_ui.tres" id="4_opug5"]
[ext_resource type="PackedScene" uid="uid://dufshurokh0ws" path="res://scene/ux/inspector_balloon.tscn" id="5_p8nxc"]
[node name="PropInspector" type="CanvasLayer"]
process_mode = 3
@ -133,3 +134,6 @@ theme_override_fonts/font = ExtResource("4_opug5")
text = "Q: Exit E: Read"
horizontal_alignment = 1
vertical_alignment = 1
[node name="InspectorBalloon" parent="." instance=ExtResource("5_p8nxc")]
unique_name_in_owner = true