xiandie/scene/entity/npc.gd
2025-06-07 00:19:37 +08:00

102 lines
2.4 KiB
GDScript

@tool
class_name Npc2D extends AnimatedSprite2D
signal interacted
@export var height := 60.0:
set(val):
height = val
if is_node_ready():
speaking_sign.position.y = -height
@onready var speaking_animation = %SpeakingAnimationPlayer
@onready var speaking_sign = %SpeakingSign2D as Node2D
@onready var sign_mark = %Sign as Sign
@onready var area2d = %Area2D as Area2D
var dialogue_title := ""
var dialogue_res = preload("res://asset/dialogue/npc.dialogue")
func _ready() -> void:
if Engine.is_editor_hint():
speaking_sign.visible = true
return
speaking_sign.visible = false
speaking_sign.position.y = -height
if animation:
play()
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_stop)
sign_mark.toggle_active.connect(_on_toggle_active)
sign_mark.enabled = visible
visibility_changed.connect(_on_visibility_changed)
func _on_visibility_changed() -> void:
sign_mark.enabled = visible
func _on_toggle_active(activated: bool) -> void:
if activated:
_speaking()
else:
_stop()
func _on_interacted() -> void:
# %Sfx.play()
# _speaking()
# play dialogue
if dialogue_title:
interacted.emit()
# # 适配匿名效果
# if anonymous and not dialogue_title.ends_with(anonymous_title_suffix):
# dialogue_title += anonymous_title_suffix
# elif not anonymous and dialogue_title.ends_with(anonymous_title_suffix):
# dialogue_title = dialogue_title.substr(
# 0, dialogue_title.length() - anonymous_title_suffix.length()
# )
DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title)
SceneManager.freeze_player(0)
DialogueManager.dialogue_ended.connect(_dialog_end, CONNECT_ONE_SHOT)
func _dialog_end(_res):
SceneManager.release_player()
func _speaking() -> void:
speaking_animation.play("speaking")
func _stop() -> void:
speaking_animation.play("RESET")
func _get(property: StringName) -> Variant:
if property == "dialogue_title":
return dialogue_title
return null
func _set(property: StringName, value: Variant) -> bool:
if property == "dialogue_title":
dialogue_title = value
return true
return false
func _get_property_list() -> Array[Dictionary]:
var hint_str = ""
if Engine.is_editor_hint():
hint_str = ",".join(dialogue_res.get_ordered_titles())
return [
{
"name": "dialogue_title",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": hint_str
}
]