xiandie/scene/entity/note.gd

177 lines
4.9 KiB
GDScript

@tool
class_name Note2D extends Sprite2D
signal read_note
signal sign_mark_offset_updated
# sign_mark 节点在 ready 时会直接读取
@export var sign_mark_offset := Vector2.ZERO:
set(val):
sign_mark_offset = val
sign_mark_offset_updated.emit(val)
@export var enabled := true:
set(val):
enabled = val
if is_node_ready():
_visibility_changed()
@export var collision_width_and_x := Vector2(20.0, 0):
set(val):
collision_width_and_x = val
if is_node_ready():
var shape = area2d.get_node("CollisionShape2D").shape
shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
@export var action := 4 #3为none; 4为lookup_wall; 之后为其他动作,请参考 PlayerAnimationConfig
@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
"c03":
dialogue_res = dialogue_c03
"c04":
dialogue_res = dialogue_c04
"c05":
dialogue_res = dialogue_c05
"c06":
dialogue_res = dialogue_c06
if is_node_ready() and Engine.is_editor_hint():
notify_property_list_changed()
var note_key := ""
@export_enum("c01", "c02", "c03", "c04", "c05", "c06") var title_filter := "c01":
set(val):
title_filter = val
if is_node_ready() and Engine.is_editor_hint():
notify_property_list_changed()
@export var note_sign_texture: Texture2D
@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_c03 = preload("res://asset/dialogue/c03.dialogue")
var dialogue_c04 = preload("res://asset/dialogue/c04.dialogue")
var dialogue_c05 = preload("res://asset/dialogue/c05.dialogue")
var dialogue_c06 = preload("res://asset/dialogue/c06.dialogue")
var dialogue_res = dialogue_items
var mutex = Mutex.new()
var ground_archive: GroundArchive
# 尝试互动的次数
var icount: int:
set(val):
icount = val
ground_archive.set_pair(name, "icount", val)
if icount >= 1 and sign_mark:
sign_mark.sprite2d.texture = note_sign_texture
func _ready() -> void:
var shape = area2d.get_node("CollisionShape2D").shape
shape.size.x = collision_width_and_x.x
area2d.position.x = collision_width_and_x.y
if Engine.is_editor_hint():
notify_property_list_changed()
return
sign_mark.interacted.connect(_on_interacted)
# setup default value
ground_archive = ArchiveManager.archive.ground_archive()
icount = ground_archive.get_value(name, "icount", 0)
visibility_changed.connect(_visibility_changed)
func _visibility_changed():
sign_mark.enabled = enabled and is_visible_in_tree()
func _on_interacted() -> void:
if not note_key:
printerr("Note key is not set")
return
icount += 1
%Sfx.play()
match mode:
"os":
_show_os()
"ballon":
var _res = dialogue_res
var title = note_key
# items 条目特殊处理,不使用标题
if dialogue == "items":
title = "start"
var content = tr(note_key).replace("<br>", "\n")
var text = "~ " + title + "\n" + content + "\n=> END"
_res = DialogueManager.create_resource_from_text(text) as DialogueResource
_show_balloon(_res, title)
read_note.emit()
func _show_os():
SceneManager.pop_os_with_str(note_key)
SceneManager.player_action(action)
func _show_balloon(res, title):
# SceneManager.focus_node(self)
DialogueManager.show_dialogue_balloon(res, title)
# note viewing animation
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.lock_player(0, action)
await DialogueManager.dialogue_ended
if GlobalConfig.DEBUG:
print("[" + name + "] call lock")
SceneManager.unlock_player()
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 = ""
if Engine.is_editor_hint():
var title_arr = []
if dialogue == "items":
var title = "Notes_" + title_filter
var id = dialogue_items.titles[title]
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()
titles = ",".join(title_arr)
return [
{
"name": "note_key",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
"hint_string": titles
}
]