增加获得重要物品直接可检阅的功能

This commit is contained in:
cakipaul 2025-07-28 19:36:36 +08:00
parent 02d99ac811
commit b6ede0c4e6
8 changed files with 83 additions and 94 deletions

View File

@ -44,7 +44,6 @@ ui_boxcat_press_s,按住 S 躲藏,,,,,Hold S to hide
input_拼凑信件,点击选择信件碎片方向键移动E 旋碎片转Q 退出,,,,,"Click to select letter fragments, arrow keys to move, E to rotate, Q to exit" input_拼凑信件,点击选择信件碎片方向键移动E 旋碎片转Q 退出,,,,,"Click to select letter fragments, arrow keys to move, E to rotate, Q to exit"
input_书架游戏,点击书本可选中或交换Q 退出,,,,,"Click books to select or swap, Q to exit" input_书架游戏,点击书本可选中或交换Q 退出,,,,,"Click books to select or swap, Q to exit"
ui_获得道具,获得道具,,,,,Item Obtained ui_获得道具,获得道具,,,,,Item Obtained
ui_获得重要物品,重要物品,,,,,Important Item
ui_退出,退出,,,,,Exit ui_退出,退出,,,,,Exit
ui_阅读,阅读,,,,,Read ui_阅读,阅读,,,,,Read
ui_检阅,检阅,,,,,Examine ui_检阅,检阅,,,,,Examine

1 keys zh_CN _character _notes _tags zh_SH en
44 input_拼凑信件 点击选择信件碎片,方向键移动,E 旋碎片转,Q 退出 Click to select letter fragments, arrow keys to move, E to rotate, Q to exit
45 input_书架游戏 点击书本可选中或交换,Q 退出 Click books to select or swap, Q to exit
46 ui_获得道具 获得道具 Item Obtained
ui_获得重要物品 重要物品 Important Item
47 ui_退出 退出 Exit
48 ui_阅读 阅读 Read
49 ui_检阅 检阅 Examine

View File

@ -26,7 +26,6 @@
返回[ID:setting_返回] 返回[ID:setting_返回]
确认[ID:setting_确认] 确认[ID:setting_确认]
线索[ID:bag_tab_笔记] 线索[ID:bag_tab_笔记]
物件[ID:bag_tab_物品] 物件[ID:bag_tab_物品]
记忆[ID:bag_tab_记忆] 记忆[ID:bag_tab_记忆]

View File

@ -12,8 +12,6 @@ func _ready() -> void:
%UILayer.layer = GlobalConfig.CANVAS_LAYER_UI %UILayer.layer = GlobalConfig.CANVAS_LAYER_UI
%ColorRectTop.visible = true %ColorRectTop.visible = true
%ColorRectBottom.visible = true %ColorRectBottom.visible = true
# focus_mode = Control.FOCUS_CLICK
# settings.exited.connect(grab_focus)
var debug_button_last_press_msec := 0 var debug_button_last_press_msec := 0

View File

@ -37,7 +37,6 @@ func _load_item_buttons() -> void:
if not hud.items_dict.has(prop_key): if not hud.items_dict.has(prop_key):
printerr("Important item not found in items_dict: ", prop_key) printerr("Important item not found in items_dict: ", prop_key)
continue continue
hud.items_description_dict.has(prop_key)
var button = preload("uid://wxd25ec3cqyy").instantiate() var button = preload("uid://wxd25ec3cqyy").instantiate()
button.text = tr(prop_key) button.text = tr(prop_key)
button.pressed.connect(_display_item.bind(prop_key, button)) button.pressed.connect(_display_item.bind(prop_key, button))
@ -63,7 +62,7 @@ func _display_item(prop_key, button = null):
button.icon = null button.icon = null
# prop keys # prop keys
var item_data = hud.items_dict[prop_key] var item_data = hud.items_dict[prop_key]
var content = hud.items_description_dict[prop_key] var content = hud.get_item_description(prop_key)
content_text_edit.text = content content_text_edit.text = content
texture_rect.texture = load(item_data.texture_path) texture_rect.texture = load(item_data.texture_path)

View File

@ -29,14 +29,8 @@ func show_prop_balloon(obtain_str: String, prop_title: String, content: String)
_balloon_tween = create_tween() _balloon_tween = create_tween()
show() show()
_pending_content = content _pending_content = content
# 如果有获得的物品名称,则显示标题,否则直接显示内容 obtain_str = "[color=orange]" + obtain_str + "[/color]"
if not obtain_str.is_empty(): _displaying_status = DISPLAYING_TITLE
obtain_str = "[color=orange]" + obtain_str + "[/color]"
_displaying_status = DISPLAYING_TITLE
else:
_display_content()
_display_mutex.unlock()
return
character_label.show() character_label.show()
character_label.text = obtain_str character_label.text = obtain_str
content_label.text = prop_title content_label.text = prop_title
@ -53,16 +47,22 @@ func _display_content() -> void:
_display_mutex.lock() _display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running(): if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill() _balloon_tween.kill()
_balloon_tween = create_tween() show()
_displaying_status = DISPLAYING_CONTENT _displaying_status = DISPLAYING_CONTENT
character_label.hide() character_label.hide()
content_label.text = _pending_content content_label.text = _pending_content
_pending_content = "" _pending_content = ""
_balloon_tween = create_tween()
_balloon_tween.tween_interval(auto_quit_time) _balloon_tween.tween_interval(auto_quit_time)
_balloon_tween.tween_callback(_finished.bind(false)) _balloon_tween.tween_callback(_finished.bind(false))
_display_mutex.unlock() _display_mutex.unlock()
func show_prop_content(content: String) -> void:
_pending_content = content
_display_content()
func _finished(manually: bool) -> void: func _finished(manually: bool) -> void:
_display_mutex.lock() _display_mutex.lock()
character_label.text = "" character_label.text = ""
@ -74,16 +74,31 @@ func _finished(manually: bool) -> void:
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
_display_mutex.lock()
if _displaying_status == DISPLAYING_NONE: if _displaying_status == DISPLAYING_NONE:
_display_mutex.unlock()
return return
if event.is_action_pressed("interact") or event.is_action_pressed("cancel"): if event.is_action_pressed("interact") or event.is_action_pressed("cancel"):
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running(): if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill() _balloon_tween.kill()
if not _pending_content.is_empty() and _displaying_status == DISPLAYING_TITLE: if _displaying_status == DISPLAYING_TITLE:
_display_content() if not _pending_content.is_empty():
else: _display_content()
else:
# 如果没有文本,直接退出
_finished(true)
elif _displaying_status == DISPLAYING_CONTENT:
_finished(true) _finished(true)
_display_mutex.unlock() _display_mutex.unlock()
# 不释放 quitted 结束 balloon
func kill_without_signal() -> void:
_display_mutex.lock()
if _balloon_tween and _balloon_tween.is_running():
_balloon_tween.kill()
character_label.text = ""
content_label.text = ""
_displaying_status = DISPLAYING_NONE
hide()
_display_mutex.unlock()

View File

@ -63,7 +63,6 @@ const HUD_FADE_DURATION = 0.3
var prop_containers: Array[CenterContainer] = [] var prop_containers: Array[CenterContainer] = []
var items_dict := {} var items_dict := {}
var items_description_dict = {}
# 从配置文件加载 prop items # 从配置文件加载 prop items
var item_config_res = preload("res://asset/dialogue/item_description.dialogue") var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
var path_prefix = "res://asset/art/prop/" var path_prefix = "res://asset/art/prop/"
@ -166,13 +165,16 @@ func _load_items_config_to_dict(title: String):
item.inspect_path = path_prefix + inspect_path item.inspect_path = path_prefix + inspect_path
items_dict[item.key] = item items_dict[item.key] = item
items_description_dict[item.key] = tr(item.key + "_说明").replace("{br}", "\n")
if not current_line.has("next_id") or current_line.next_id == "end": if not current_line.has("next_id") or current_line.next_id == "end":
break break
current_line = item_config_res.lines.get(current_line.next_id) current_line = item_config_res.lines.get(current_line.next_id)
func get_item_description(prop_key: String) -> String:
return tr(prop_key + "_说明").replace("{br}", "\n")
func _reload_cache_and_realign_display() -> void: func _reload_cache_and_realign_display() -> void:
if ArchiveManager.archive: if ArchiveManager.archive:
inventory = ArchiveManager.archive.prop_inventory inventory = ArchiveManager.archive.prop_inventory
@ -554,7 +556,7 @@ func enable_important_item(prop_key: String, display_inspector: bool) -> void:
if display_inspector: if display_inspector:
sfx_inspect.play() sfx_inspect.play()
inspect_item(prop_key, true, true) inspect_item(prop_key, false, true)
func enable_prop_item(prop_key: String, inspect := true) -> void: func enable_prop_item(prop_key: String, inspect := true) -> void:
@ -584,12 +586,10 @@ func inspect_item(prop_key: String, display_obtained := true, as_important_item
var item = items_dict[prop_key] var item = items_dict[prop_key]
var texture: Texture2D = null var texture: Texture2D = null
var is_inspect_texture = false
# 检查是否有独立的 inspect 图片 # 检查是否有独立的 inspect 图片
if item.inspect_path: if item.inspect_path:
texture = load(item.inspect_path) as Texture2D texture = load(item.inspect_path) as Texture2D
is_inspect_texture = true
else: else:
texture = cached_inventory_textures.get(prop_key) texture = cached_inventory_textures.get(prop_key)
if not texture and item.texture_path: if not texture and item.texture_path:
@ -600,10 +600,16 @@ func inspect_item(prop_key: String, display_obtained := true, as_important_item
if not texture: if not texture:
printerr("prophud inspect_item invalid texture for key:", prop_key) printerr("prophud inspect_item invalid texture for key:", prop_key)
return return
if as_important_item:
inspector.pop_prop_inspection( var content = get_item_description(prop_key)
prop_key, texture, not is_inspect_texture, display_obtained, as_important_item var wide = len(content) > 150
) inspector.pop_standard_inspection(
texture, null, content, false, wide
)
else:
inspector.pop_prop_inspection(
prop_key, texture, display_obtained
)
func disable_prop_item(prop_key: String) -> void: func disable_prop_item(prop_key: String) -> void:

View File

@ -3,18 +3,15 @@ class_name PropInspector extends CanvasLayer
enum { enum {
STATUS_HIDDEN, STATUS_HIDDEN,
STATUS_HIDDING,
STATUS_INSPECTING_PROP, STATUS_INSPECTING_PROP,
STATUS_INSPECTING_COVER, STATUS_INSPECTING_COVER,
STATUS_INSPECTING_NOTES STATUS_INSPECTING_NOTES
} }
# must be connected to
signal quit_and_hidden signal quit_and_hidden
@onready var notes_bg = %NotesBG as TextureRect @onready var notes_bg = %NotesBG as TextureRect
@onready var prop_bg = %PropBG as TextureRect @onready var prop_bg = %PropBG as TextureRect
@onready var origin_texture = %OriginPropTexture as TextureRect
@onready var full_texture = %FullTexture as TextureRect @onready var full_texture = %FullTexture as TextureRect
@onready var scroll_container = %ScrollContainer as ScrollContainer @onready var scroll_container = %ScrollContainer as ScrollContainer
@onready var content_label = %ContentLabel as Label @onready var content_label = %ContentLabel as Label
@ -38,7 +35,6 @@ func _ready() -> void:
return return
visible = false visible = false
layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR
origin_texture.modulate.a = 0.0
prop_bg.modulate.a = 0.0 prop_bg.modulate.a = 0.0
full_texture.modulate.a = 0.0 full_texture.modulate.a = 0.0
content_label.modulate.a = 0.0 content_label.modulate.a = 0.0
@ -49,28 +45,31 @@ func _ready() -> void:
func _on_inspector_balloon_quitted(_is_manually: bool): func _on_inspector_balloon_quitted(_is_manually: bool):
_hide() _hide()
var hiding_tween: Tween
func _hide(): func _hide():
if status == STATUS_HIDDING:
return
if status == STATUS_HIDDEN: if status == STATUS_HIDDEN:
return return
status = STATUS_HIDDING status = STATUS_HIDDEN
var tween = create_tween() # 延迟完善 hide 的过程
tween.tween_property(origin_texture, "modulate:a", 0.0, 0.3) if hiding_tween and hiding_tween.is_running():
tween.parallel().tween_property(full_texture, "modulate:a", 0.0, 0.3) hiding_tween.kill()
tween.parallel().tween_property(content_label, "modulate:a", 0.0, 0.15) quit_and_hidden.emit()
hiding_tween = create_tween()
hiding_tween.parallel().tween_property(full_texture, "modulate:a", 0.0, 0.3)
hiding_tween.parallel().tween_property(content_label, "modulate:a", 0.0, 0.15)
if blinking_tween and blinking_tween.is_running(): if blinking_tween and blinking_tween.is_running():
blinking_tween.stop() blinking_tween.kill()
tween.parallel().tween_property(tip_label, "modulate:a", 0.0, 0.15) hiding_tween.parallel().tween_property(tip_label, "modulate:a", 0.0, 0.15)
tween.tween_callback(_post_hide) hiding_tween.tween_callback(_post_hide)
func _post_hide(): func _post_hide():
status = STATUS_HIDDEN # hiding_tween 被 kill 的时候需要调用 _post_hide 或 quit_and_hidden.emit()
quit_and_hidden.emit()
scroll_container.mouse_filter = Control.MOUSE_FILTER_IGNORE scroll_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
locking = false locking = false
origin_texture.texture = null prop_bg.visible = false
full_texture.texture = null full_texture.texture = null
texture_cover = null texture_cover = null
texture_notes = null texture_notes = null
@ -78,7 +77,6 @@ func _post_hide():
tip_label.text = tip_cover tip_label.text = tip_cover
notes_bg.visible = false notes_bg.visible = false
visible = false visible = false
quit_and_hidden.emit()
func _blink_label(init := true): func _blink_label(init := true):
@ -97,18 +95,21 @@ func _blink_label(init := true):
func pop_standard_inspection( func pop_standard_inspection(
cover_texture, notes_texture, inspection_note, centered := false, wide := false cover_texture, notes_texture, inspection_note, centered := false, wide := false
): ):
if centered: if status == STATUS_INSPECTING_PROP:
content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER inspector_balloon.kill_without_signal()
else: if hiding_tween and hiding_tween.is_running():
content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT hiding_tween.kill()
if status != STATUS_HIDDEN: _post_hide()
_hide()
locking = true locking = true
status = STATUS_INSPECTING_COVER status = STATUS_INSPECTING_COVER
visible = true visible = true
full_texture.texture = cover_texture full_texture.texture = cover_texture
texture_cover = cover_texture texture_cover = cover_texture
texture_notes = notes_texture texture_notes = notes_texture
if centered:
content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
else:
content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
if wide: if wide:
content_label.custom_minimum_size.x = 250 content_label.custom_minimum_size.x = 250
else: else:
@ -138,46 +139,36 @@ var locking = false:
func pop_prop_inspection( func pop_prop_inspection(
prop_key: String, prop_key: String,
cover_texture: Texture2D, cover_texture: Texture2D,
use_default_bg: bool, display_obtained: bool
display_obtained: bool,
as_important_item: bool
): ):
if not cover_texture: if not cover_texture:
push_error("PropInspector: cover_texture is not set") push_error("PropInspector: cover_texture is not set")
return return
# STATUS_INSPECTING_PROP 状态下不 hide跳过重复 lock if hiding_tween and hiding_tween.is_running():
if status != STATUS_HIDDEN and status != STATUS_INSPECTING_PROP: hiding_tween.kill()
_hide() _post_hide()
locking = true locking = true
status = STATUS_INSPECTING_PROP status = STATUS_INSPECTING_PROP
visible = true visible = true
var tween = create_tween() var tween = create_tween()
if use_default_bg: prop_bg.visible = true
prop_bg.visible = true full_texture.texture = cover_texture
origin_texture.texture = cover_texture tween.tween_property(full_texture, "modulate:a", 1.0, 0.15)
full_texture.texture = null
tween.tween_property(origin_texture, "modulate:a", 1.0, 0.15)
tween.tween_property(prop_bg, "modulate:a", 1.0, 0.15)
else:
origin_texture.texture = null
full_texture.texture = cover_texture
tween.tween_property(full_texture, "modulate:a", 1.0, 0.15)
content_label.text = "" content_label.text = ""
tip_label.text = "" tip_label.text = ""
# 显示道具获得提示 # 显示道具获得提示
if prop_key: if prop_key:
var prop_title = tr(prop_key) var prop_title = tr(prop_key)
var obtain_str = ""
if display_obtained:
obtain_str = tr("ui_获得道具")
if as_important_item:
obtain_str = tr("ui_获得重要物品")
# 道具的一句话说明 # 道具的一句话说明
var original_word_lines = tr(prop_key + "_说明").replace("{br}", "\n").split("\n") var original_word_lines = tr(prop_key + "_说明").replace("{br}", "\n").split("\n")
# 缩略只要第一行 # 缩略只要第一行
var content = original_word_lines[0] + ("..." if len(original_word_lines) > 1 else "") var content = original_word_lines[0] + ("..." if len(original_word_lines) > 1 else "")
inspector_balloon.show_prop_balloon(obtain_str, prop_title, content) if display_obtained:
var obtain_str = tr("ui_获得道具")
inspector_balloon.show_prop_balloon(obtain_str, prop_title, content)
else:
inspector_balloon.show_prop_content(content)
func _show_prop_words(line_id: String): func _show_prop_words(line_id: String):

View File

@ -26,25 +26,6 @@ size_flags_horizontal = 4
mouse_filter = 2 mouse_filter = 2
texture = ExtResource("2_j83lq") texture = ExtResource("2_j83lq")
[node name="CenterContainer" type="CenterContainer" parent="."]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="OriginPropTexture" type="TextureRect" parent="CenterContainer"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
[node name="FullTexture" type="TextureRect" parent="."] [node name="FullTexture" type="TextureRect" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
modulate = Color(1, 1, 1, 0) modulate = Color(1, 1, 1, 0)
@ -62,6 +43,7 @@ grow_vertical = 2
size_flags_vertical = 4 size_flags_vertical = 4
mouse_filter = 2 mouse_filter = 2
texture = ExtResource("2_wr575") texture = ExtResource("2_wr575")
stretch_mode = 3
[node name="NotesBG" type="TextureRect" parent="."] [node name="NotesBG" type="TextureRect" parent="."]
unique_name_in_owner = true unique_name_in_owner = true