@tool class_name Note2D extends Sprite2D signal read_note @export var enabled := true: set(val): enabled = val if is_node_ready(): sign_mark.enabled = val @export_enum("os", "ballon") var mode = "os" @export_enum("items", "c01", "c02", "c03", "c04", "c05", "c06") var dialogue := "items": set(val): dialogue = val match dialogue: "items": dialogue_res = dialogue_items "c01": dialogue_res = dialogue_c01 "c02": dialogue_res = dialogue_c02 if is_node_ready() and Engine.is_editor_hint(): notify_property_list_changed() var note_key := "" @export_enum("none", "notes", "c01", "c02", "c03", "c04", "c05", "c06") var title_filter := "none": set(val): title_filter = val if is_node_ready() and Engine.is_editor_hint(): notify_property_list_changed() @onready var sign_mark = %Sign as Sign @onready var area2d = %Area2D as Area2D var dialogue_items = preload("res://asset/dialogue/item_description.dialogue") var dialogue_c01 = preload("res://asset/dialogue/c01.dialogue") var dialogue_c02 = preload("res://asset/dialogue/c02.dialogue") var dialogue_res = dialogue_items var interacting = false var mutex = Mutex.new() func _ready() -> void: if Engine.is_editor_hint(): return area2d.body_entered.connect(_reset) area2d.body_exited.connect(_on_cancel) sign_mark.interacted.connect(_on_interacted) sign_mark.cancel.connect(_on_cancel) sign_mark.enabled = enabled func _on_interacted() -> void: if interacting: return if not note_key: printerr("Note key is not set") return %Sfx.play() var _res = dialogue_res var title = note_key # items 条目特殊处理,不使用标题 if dialogue == "items": title = "start" var content = tr(note_key) var text = "~ " + title + "\n" + content + "\n=> END" _res = DialogueManager.create_resource_from_text(text) as DialogueResource match mode: "os": _show_os(_res, title) "ballon": _show_balloon(_res, title) read_note.emit() func _show_os(res, title): var lines = [] var current_line = await res.get_next_dialogue_line(title) while current_line: lines.append(current_line) if current_line.next_id != "end": current_line = await res.get_next_dialogue_line(current_line.next_id) else: break SceneManager.pop_os(lines) SceneManager.freeze_player(1.0, PlayerAnimationConfig.ACTION_LOOKUP_WALL) func _show_balloon(res, title): # SceneManager.focus_node(self) DialogueManager.show_dialogue_balloon(res, title) # TODO note viewing animation SceneManager.freeze_player(0) interacting = true DialogueManager.dialogue_ended.connect(_on_ballon_ended, CONNECT_ONE_SHOT) # var player = SceneManager.get_player() # DialogueManager.show_dialogue_balloon_scene(player, dialogue_res, note_key) func _on_ballon_ended(_res): interacting = false SceneManager.release_player() # SceneManager.focus_player_and_reset_zoom() func _set(property: StringName, value: Variant) -> bool: if property == "note_key": note_key = value return true return false func _get(property: StringName) -> Variant: if property == "note_key": return note_key elif property == "dialogue_res": return dialogue_res return null func _get_property_list() -> Array[Dictionary]: # only show notes_ properties in editor var titles = "" var title_arr = [] if dialogue == "items": var id = dialogue_items.titles["Notes"] var current_line = dialogue_items.lines[id] while current_line: if current_line.has("translation_key"): title_arr.append(current_line.translation_key) if not current_line.has("next_id") or current_line.next_id == "end": break current_line = dialogue_items.lines[current_line.next_id] else: title_arr = dialogue_res.get_ordered_titles() if Engine.is_editor_hint() and title_filter and title_filter != "none": var filted_titles = title_arr.filter(_filter_property) titles = ",".join(filted_titles) else: titles = ",".join(title_arr) return [ { "name": "note_key", "type": TYPE_STRING, "hint": PROPERTY_HINT_ENUM_SUGGESTION, "hint_string": titles } ] func _filter_property(property: StringName) -> bool: return property.find(title_filter) >= 0 func _on_cancel(_body = null): interacting = false func _reset(_body): interacting = false