102 lines
2.4 KiB
GDScript
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
|
|
}
|
|
]
|