151 lines
4.2 KiB
GDScript
151 lines
4.2 KiB
GDScript
@tool
|
||
class_name Interactable2D extends Sprite2D
|
||
|
||
signal interacted
|
||
|
||
@export var enabled := true:
|
||
set(val):
|
||
enabled = val
|
||
if is_node_ready():
|
||
sign_mark.enabled = val
|
||
@export var unmatched_sign_texture: Texture2D
|
||
@export var matched_sign_texture: Texture2D
|
||
@export var one_shot := true
|
||
@export var diable_prop_after_interacted := false
|
||
@export var interacted_texture: Texture2D
|
||
|
||
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
|
||
|
||
var ground_archive: GroundArchive
|
||
var interacted_times: int:
|
||
set(val):
|
||
interacted_times = val
|
||
ground_archive.set_pair(name, "interacted_times", val)
|
||
|
||
static var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
|
||
var items: PackedStringArray
|
||
|
||
|
||
func _ready() -> void:
|
||
if Engine.is_editor_hint():
|
||
_reload_items()
|
||
return
|
||
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
|
||
sign_mark.enabled = enabled
|
||
# setup default value
|
||
ground_archive = ArchiveManager.archive.ground_archive()
|
||
interacted_times = ground_archive.get_value(name, "interacted_times", 0)
|
||
if interacted_times and interacted_texture:
|
||
texture = interacted_texture
|
||
_check_sign_display()
|
||
|
||
|
||
func _check_sign_display():
|
||
if not enabled or (one_shot and interacted_times):
|
||
sign_mark.enabled = false
|
||
|
||
|
||
func _reload_items() -> void:
|
||
items.clear()
|
||
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]
|
||
notify_property_list_changed()
|
||
|
||
|
||
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 not prop_key or 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)
|
||
|
||
|
||
var interact_mutex = Mutex.new()
|
||
|
||
|
||
func _on_interacted() -> void:
|
||
interact_mutex.lock()
|
||
if one_shot and interacted_times:
|
||
interact_mutex.unlock()
|
||
return
|
||
var key = SceneManager.get_current_prop(false)
|
||
if prop_key and key != prop_key:
|
||
sfx_invalid.play()
|
||
sign_mark.invalid_shake()
|
||
# SceneManager.on_toggle_invalid_prop()
|
||
interact_mutex.unlock()
|
||
return
|
||
sfx_success.play()
|
||
if diable_prop_after_interacted and prop_key:
|
||
SceneManager.disable_prop_item(prop_key)
|
||
interacted_times += 1
|
||
if interacted_texture:
|
||
texture = interacted_texture
|
||
interacted.emit()
|
||
EventManager.prop_interacted(name, prop_key, interacted_times)
|
||
# print("%s interacted with %s. total times: %s" % [name, prop_key, interacted_times])
|
||
interact_mutex.unlock()
|
||
_check_sign_display()
|
||
|
||
|
||
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
|