D5/UI/popup/dialogue.gd
jkboy 34b7633f1e 优化资金检测;
添加是否有项目正在研发,不能重复启动新项目;
2025-05-16 19:34:10 +08:00

154 lines
6.0 KiB
GDScript

extends UIPage
# 预加载 TypewriterLogic 类 (请替换为你的实际路径!)
const _TypewriterLogic = preload("res://UI/class/TypewriterLogic.gd")
@export var dialogues: Array
@export var default_npc_name = '秘书'
@onready var npc_icon: TextureRect = $Part_2/npc_icon
var npc_icon_png_folder = "res://Entity/NPC/art/"
var typing_speed: float = 20.0 # 每秒显示的字符数
var label_node_path: NodePath = "Part_2/Part_3/Label" # Label节点的路径
# --- 基础变量 ---
var node_name: String
var dialogue_queue = []
var current_dialogue_index = -1 # Initialize to -1, so first advance makes it 0
# --- 节点和模块引用 ---
var label: Label = null
var typewriter: TypewriterLogic = null
func _ready() -> void:
super._ready()
node_name = str(self.name)
print(node_name + ": _ready executed.")
label = get_node_or_null(label_node_path)
if label == null:
printerr(node_name + ": Failed to find Label node at path: ", label_node_path)
else:
print(node_name + ": Label found. Creating TypewriterLogic instance.")
typewriter = _TypewriterLogic.new(label, typing_speed)
if typewriter != null:
if not typewriter.is_connected("finished", Callable(self, "_on_dialogue_typing_finished")):
typewriter.finished.connect(Callable(self, "_on_dialogue_typing_finished"))
print(node_name + ": TypewriterLogic instance created and signal connected.")
else:
printerr(node_name + ": Failed to create TypewriterLogic instance.")
func _on_page_activated():
super._on_page_activated()
if GameState.get_value("dialogue_npc"):
var npc_name = GameState.get_value("dialogue_npc")
npc_icon.texture = load(npc_icon_png_folder+npc_name+'.png')
GameState.set_value("dialogue_npc",null)
else:
npc_icon.texture = load(npc_icon_png_folder+default_npc_name+'.png')
print(node_name + ": Page activated.")
_start(dialogues)
func _on_page_deactivated():
super._on_page_deactivated()
print(node_name + ": Page deactivated.")
if typewriter != null:
typewriter.stop_typing()
set_process_input(false)
func _start(p_dialogues) -> void:
print(node_name + ": _start function called.")
if p_dialogues is String:
dialogue_queue = [p_dialogues]
elif p_dialogues is Array:
dialogue_queue = p_dialogues.duplicate()
else:
printerr(node_name + ": Invalid dialogues data type.")
dialogue_queue = []
current_dialogue_index = -1 # Reset index
# Advance to the first dialogue automatically when starting
_advance_dialogue_or_finish()
set_process_input(true)
# Renamed and repurposed: Tries to show next dialogue or finishes the page
func _advance_dialogue_or_finish() -> void:
current_dialogue_index += 1
print(node_name + ": Attempting to advance. New index: ", current_dialogue_index)
if current_dialogue_index < dialogue_queue.size():
_show_current_dialogue_line()
else:
# All dialogues in this page's queue are finished
print(node_name + ": Dialogue queue for this page finished. Calling go_next().")
self.hide()
go_next() # This will eventually call _close_dialogue and hide the page
# Renamed to reflect it shows a single line
func _show_current_dialogue_line() -> void:
if not (current_dialogue_index >= 0 and current_dialogue_index < dialogue_queue.size()):
printerr(node_name + ": Invalid current_dialogue_index: ", current_dialogue_index)
return
if typewriter == null:
printerr(node_name + ": TypewriterLogic instance is null. Cannot display text with effect.")
if label != null:
label.text = dialogue_queue[current_dialogue_index]
label.visible_characters = label.text.length()
# Manually call finished if no typewriter, as there's no typing to finish
_on_dialogue_typing_finished()
return
var full_text = dialogue_queue[current_dialogue_index]
print(node_name + ": Requesting typewriter to start typing: '", full_text, "'")
typewriter.start_typing(full_text)
func _close_dialogue(): # This is typically called by go_next() via UIPage's hide_page -> _on_page_deactivated
print(node_name + ": Closing dialogue. Stopping typewriter if active.")
if typewriter != null:
typewriter.stop_typing()
set_process_input(false)
print(node_name + ": Dialogue UI processing stopped.")
func _on_dialogue_typing_finished():
print(node_name + ": Received 'finished' signal from TypewriterLogic for line: '", dialogue_queue[current_dialogue_index] if current_dialogue_index < dialogue_queue.size() and current_dialogue_index >=0 else "N/A" , "'")
# Current line finished typing. Ready for next input.
# You could show a "continue" prompt icon here if desired.
pass
func _input(event: InputEvent) -> void:
if not visible: # Only process if page is visible
return
var relevant_click = false
if event is InputEventMouseButton and event.is_pressed():
if event.button_index == MOUSE_BUTTON_LEFT or event.button_index == MOUSE_BUTTON_RIGHT:
relevant_click = true
if relevant_click:
get_viewport().set_input_as_handled() # Consume the click event early
print(node_name + ": Relevant mouse click detected (Left or Right).")
# Behavior 1: If typewriter is currently typing, skip to the end of the current line.
# Requires TypewriterLogic to have is_typing() and skip_to_end() methods.
if typewriter != null and typewriter.is_typing():
print(node_name + ": Typewriter is typing. Calling skip_typing().")
typewriter.skip_typing() # This should make it emit 'finished' signal
return # Wait for next click to advance dialogue
# Behavior 2: If typewriter is NOT typing (or no typewriter), advance to the next dialogue or finish.
print(node_name + ": Typewriter not typing or no typewriter. Advancing dialogue or finishing.")
_advance_dialogue_or_finish()
return
# If not a relevant click for dialogue, pass to super class (e.g., for other UI interactions)
# Note: If you want right-click to *only* advance dialogue and not trigger parent's go_back,
# this structure is correct because we consume the event.
# If UIPage's _input handles other specific mouse buttons (e.g. middle mouse) or other event types,
# they will still be processed if not handled above.
if not relevant_click: # Only call super if we didn't handle it
super._input(event)