xiandie/scene/entity/interactable.gd

123 lines
3.4 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@tool
extends Sprite2D
signal interacted(success: bool)
@export var unmatched_sign_texture: Texture2D
@export var matched_sign_texture: Texture2D
@export var texture_before: Texture2D
@export var texture_after: Texture2D
@export var one_shot := true
@export var interacted_times := 0
var prop_key := ""
@onready var sfx_invalid = $SfxInvalid as Sfx
@onready var sfx_success = $SfxSuccess as Sfx
@onready var sign_mark = %Sign as Sign
@onready var area2d = %Area2D as Area2D
static var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
var items: PackedStringArray
func _reload_items() -> void:
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]
func _ready() -> void:
if Engine.is_editor_hint():
_reload_items()
notify_property_list_changed()
return
if interacted_times and texture_after:
texture = texture_after
else:
texture = texture_before
area2d.body_entered.connect(_reset)
area2d.body_exited.connect(_on_cancel)
sign_mark.interacted.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
sign_mark.base_scale = sign_mark.scale
func _reset(_body = null) -> void:
var key = SceneManager.get_current_prop(false)
if key:
_set_sign_texture_to_prop(key)
var prop_hud = SceneManager.get_prop_hud() as PropHud
if not prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop):
prop_hud.current_item_changed.connect(_set_sign_texture_to_prop)
# 根据当前 prop调整 sign 所显示的 texture
func _set_sign_texture_to_prop(key):
if prop_key == key:
sign_mark.sprite2d.texture = matched_sign_texture
else:
sign_mark.sprite2d.texture = unmatched_sign_texture
# if prop_hud.cached_inventory_textures.has(key):
# var prop_texture = prop_hud.cached_inventory_textures[key]
# sign_mark.draw_shadow = true
# else:
# sign_mark.sprite2d.texture = deaulte_sign_texture
# sign_mark.draw_shadow = false
# sign_mark.queue_redraw()
func _on_cancel(_body = null) -> void:
# disconnect signal
var prop_hud = SceneManager.get_prop_hud() as PropHud
if prop_hud and prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop):
prop_hud.current_item_changed.disconnect(_set_sign_texture_to_prop)
func _on_interacted() -> void:
if one_shot and interacted_times:
return
var key = SceneManager.get_current_prop(false)
if key != prop_key:
sfx_invalid.play()
sign_mark.invalid_shake()
# SceneManager.on_toggle_invalid_prop()
return
sfx_success.play()
if one_shot:
SceneManager.disable_prop_item(prop_key)
interacted_times += 1
if texture_after:
texture = texture_after
interacted.emit()
EventManager.prop_interacted(name, prop_key, interacted_times)
# print("%s interacted with %s. total times: %s" % [name, prop_key, interacted_times])
func _get_property_list() -> Array[Dictionary]:
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