2025-06-30 14:48:28 +00:00
|
|
|
|
extends Control
|
|
|
|
|
|
|
|
|
|
signal os_finished
|
|
|
|
|
|
|
|
|
|
@onready var os_pausing_timer = %OSTimer as Timer
|
|
|
|
|
@onready var os_label = %OSLabel as DialogueLabel
|
|
|
|
|
@onready var os_contaner = %PanelContainer as PanelContainer
|
|
|
|
|
|
|
|
|
|
var os_tween: Tween
|
|
|
|
|
# 保证每次 pop_os 后都会有一次 os_finished 信号
|
|
|
|
|
var os_finish_emit_lock := Mutex.new()
|
|
|
|
|
var os_finished_not_emitted := false
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
if Engine.is_editor_hint():
|
|
|
|
|
# 显示 os 效果
|
|
|
|
|
os_contaner.modulate.a = 1.0
|
|
|
|
|
os_label.text = "os 测试文本"
|
|
|
|
|
return
|
|
|
|
|
os_contaner.modulate.a = 0.0
|
|
|
|
|
os_label.text = ""
|
|
|
|
|
os_pausing_timer.timeout.connect(_on_os_line_timeout)
|
|
|
|
|
|
|
|
|
|
|
2025-07-01 17:18:25 +00:00
|
|
|
|
func pop_os(lines := []) -> void:
|
2025-06-30 14:48:28 +00:00
|
|
|
|
if os_tween:
|
|
|
|
|
os_tween.kill()
|
|
|
|
|
os_finish_emit_lock.lock()
|
|
|
|
|
if os_finished_not_emitted:
|
|
|
|
|
os_finished.emit()
|
|
|
|
|
os_finished_not_emitted = true
|
|
|
|
|
os_finish_emit_lock.unlock()
|
2025-07-01 17:18:25 +00:00
|
|
|
|
SceneManager.lock_player()
|
|
|
|
|
# os_finished 必然发送,防止 tween 被 kill,保证一定 unlock
|
|
|
|
|
if os_finished.is_connected(SceneManager.unlock_player):
|
|
|
|
|
SceneManager.unlock_player()
|
|
|
|
|
else:
|
2025-06-30 14:48:28 +00:00
|
|
|
|
os_finished.connect(SceneManager.unlock_player, CONNECT_ONE_SHOT)
|
|
|
|
|
os_tween = create_tween()
|
|
|
|
|
os_label.text = ""
|
|
|
|
|
os_tween.tween_property(os_contaner, "modulate:a", 1.0, 0.2)
|
|
|
|
|
for line in lines:
|
|
|
|
|
# os_pausing_timer 启动最小时长 0.01 秒
|
|
|
|
|
var duration = max(GlobalConfigManager.config.os_wait_time, 0.01)
|
|
|
|
|
os_tween.tween_callback(_os_load_line.bind(line, duration))
|
|
|
|
|
os_tween.tween_property(os_contaner, "modulate:a", 0.0, 0.2)
|
|
|
|
|
os_tween.tween_callback(func():
|
|
|
|
|
os_finish_emit_lock.lock()
|
|
|
|
|
if os_finished_not_emitted:
|
|
|
|
|
os_finished_not_emitted = false
|
|
|
|
|
os_finished.emit()
|
|
|
|
|
os_finish_emit_lock.unlock()
|
|
|
|
|
)
|
|
|
|
|
# os 结束
|
|
|
|
|
await os_finished
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _os_load_line(line: DialogueLine, duration: float):
|
|
|
|
|
os_label.dialogue_line = line
|
|
|
|
|
os_label.type_out()
|
|
|
|
|
if os_label.finished_typing.is_connected(os_pausing_timer.start):
|
|
|
|
|
os_label.finished_typing.disconnect(os_pausing_timer.start)
|
|
|
|
|
os_label.finished_typing.connect(os_pausing_timer.start.bind(duration), CONNECT_ONE_SHOT)
|
|
|
|
|
os_tween.pause()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_os_line_timeout(naturally := true):
|
|
|
|
|
if not naturally:
|
|
|
|
|
if os_label.is_typing:
|
|
|
|
|
os_label.skip_typing()
|
|
|
|
|
return
|
2025-07-01 17:18:25 +00:00
|
|
|
|
if os_tween and os_tween.is_valid():
|
2025-06-30 14:48:28 +00:00
|
|
|
|
os_tween.play()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
|
|
|
if event.is_action_pressed("interact"):
|
|
|
|
|
if os_pausing_timer and os_pausing_timer.time_left > 0:
|
|
|
|
|
get_viewport().set_input_as_handled()
|
|
|
|
|
_on_os_line_timeout(false)
|