132 lines
3.3 KiB
GDScript
132 lines
3.3 KiB
GDScript
@tool
|
|
class_name Pickable2D extends Node2D
|
|
|
|
signal triggered
|
|
|
|
@export var enabled := true:
|
|
set(val):
|
|
enabled = val
|
|
if is_node_ready():
|
|
_check_sign_display()
|
|
# 除了 picked 必然隐藏,其他情况下跟随 enabled 状态
|
|
@export var visible_follow_enabled := true
|
|
|
|
var prop_key := ""
|
|
|
|
@onready var sfx = $Sfx as Sfx
|
|
@onready var sign_mark := %Sign as Sign
|
|
@onready var area := %Area2D as Area2D
|
|
var ground_archive: GroundArchive
|
|
var picked: bool:
|
|
set(val):
|
|
picked = val
|
|
if not Engine.is_editor_hint() and ground_archive:
|
|
ground_archive.set_pair(name, "picked", picked)
|
|
|
|
|
|
func reset() -> void:
|
|
if picked:
|
|
picked = false
|
|
_check_sign_display()
|
|
|
|
|
|
# 渐渐浮现
|
|
func enable_with_ease(duration := 1.0):
|
|
enabled = true
|
|
if not picked:
|
|
var tween = create_tween()
|
|
tween.tween_property(self, "modulate:a", 1.0, duration).from(0.0)
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready() -> void:
|
|
if Engine.is_editor_hint():
|
|
var animation_player = _get_animation_player()
|
|
# 更新 hook_animation 的可选项
|
|
if animation_player:
|
|
animation_player.animation_libraries_updated.connect(notify_property_list_changed)
|
|
return
|
|
# setup default value
|
|
ground_archive = ArchiveManager.archive.ground_archive()
|
|
picked = ground_archive.get_value(name, "picked", false)
|
|
sign_mark.enabled = enabled
|
|
_check_sign_display()
|
|
if picked:
|
|
if GlobalConfig.DEBUG:
|
|
print("Prop has picked, name=", name, " key=", prop_key)
|
|
sign_mark.interacted.connect(_interacted)
|
|
|
|
|
|
func _check_sign_display():
|
|
if picked:
|
|
visible = false
|
|
elif visible_follow_enabled:
|
|
visible = enabled
|
|
sign_mark.enabled = visible and enabled
|
|
|
|
|
|
func _get_animation_player() -> AnimationPlayer:
|
|
var node = get_parent()
|
|
while node and not node is Ground2D:
|
|
node = node.get_parent()
|
|
if node is Ground2D:
|
|
return node.get_node("AnimationPlayer") as AnimationPlayer
|
|
return null
|
|
|
|
|
|
var trigger_mutex = Mutex.new()
|
|
|
|
|
|
func _interacted():
|
|
if not enabled or picked:
|
|
return
|
|
# 确保只有一个线程进入该逻辑,因为有时 player 碰撞和首次进入 tree 都会触发该方法
|
|
if not trigger_mutex.try_lock():
|
|
print("pickable trigger mutex lock fail, name=", name)
|
|
return
|
|
print("pickable trigger mutex locked, name=", name)
|
|
picked = true
|
|
trigger_mutex.unlock()
|
|
SceneManager.enable_prop_item(prop_key)
|
|
triggered.emit()
|
|
if GlobalConfig.DEBUG:
|
|
print("pickable triggered! name=", name)
|
|
_check_sign_display()
|
|
|
|
|
|
static var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
|
|
|
|
|
|
func _get_property_list() -> Array[Dictionary]:
|
|
var items = []
|
|
if Engine.is_editor_hint():
|
|
var id = item_config_res.titles["PropItems"]
|
|
var current_line = item_config_res.lines[id]
|
|
while current_line:
|
|
if current_line.has("translation_key"):
|
|
items.append(current_line.translation_key)
|
|
if not current_line.has("next_id") or current_line.next_id == "end":
|
|
break
|
|
current_line = item_config_res.lines[current_line.next_id]
|
|
return [
|
|
{
|
|
"name": "prop_key",
|
|
"type": TYPE_STRING,
|
|
"hint": PROPERTY_HINT_ENUM_SUGGESTION,
|
|
"hint_string": ",".join(items),
|
|
}
|
|
]
|
|
|
|
|
|
func _get(property: StringName) -> Variant:
|
|
if property == "prop_key":
|
|
return prop_key
|
|
return null
|
|
|
|
|
|
func _set(property: StringName, value: Variant) -> bool:
|
|
if property == "prop_key":
|
|
prop_key = value
|
|
return true
|
|
return false
|