109 lines
3.5 KiB
GDScript
109 lines
3.5 KiB
GDScript
@tool
|
|
class_name EventBinder extends Node
|
|
|
|
@export_group("Updater", "updater")
|
|
@export var updater_event := &""
|
|
@export_enum("enabler", "disabler", "shower", "hider") var updater_mode := "enabler"
|
|
# 仅对 canvas item 生效; <=0 时无 ease
|
|
@export var updater_ease_duration := 1.0
|
|
@export_enum("include", "exclude") var updater_stage_mode := "include"
|
|
@export var updater_stages: Array[int] = [1]
|
|
|
|
@export_group("Trigger", "trigger")
|
|
@export var trigger_event := &""
|
|
@export_tool_button("AutoDetectMode") var trigger_auto_detect_mode := _auto_detect_mode
|
|
@export_enum("none", "interacted", "triggered", "played") var trigger_mode := "none"
|
|
@export_range(0, 10000, 1) var trigger_stage := 1
|
|
@export var trigger_set_stage_if_greater := true
|
|
|
|
var _local_enable_event_stage := 0
|
|
|
|
|
|
func _ready() -> void:
|
|
if Engine.is_editor_hint():
|
|
return
|
|
var parent = get_parent()
|
|
if not updater_event.is_empty():
|
|
if not parent:
|
|
printerr("[EventBinder] bind_enable is true but parent is null. path: %s" % get_path())
|
|
return
|
|
_local_enable_event_stage = EventManager.get_stage(updater_event)
|
|
_update_binding_state(_local_enable_event_stage)
|
|
EventManager.stage_updated.connect(_on_global_stage_updated)
|
|
if not trigger_event.is_empty():
|
|
# connect trigger_mode signal
|
|
if trigger_mode == "interacted":
|
|
parent.interacted.connect(_on_happened)
|
|
elif trigger_mode == "triggered":
|
|
parent.triggered.connect(_on_happened)
|
|
elif trigger_mode == "played":
|
|
parent.played.connect(_on_happened)
|
|
|
|
|
|
func _on_happened() -> void:
|
|
if trigger_set_stage_if_greater:
|
|
var updated = EventManager.set_stage_if_greater(trigger_event, trigger_stage)
|
|
if not updated:
|
|
print(
|
|
(
|
|
"[EventBinder] _on_happened not updated, event: %s, stage: %s"
|
|
% [trigger_event, EventManager.get_stage(trigger_event)]
|
|
)
|
|
)
|
|
else:
|
|
EventManager.set_stage(trigger_event, trigger_stage)
|
|
|
|
|
|
func _on_global_stage_updated(e: StringName, s: int):
|
|
if e == updater_event:
|
|
_local_enable_event_stage = s
|
|
_update_binding_state(s)
|
|
|
|
|
|
func _update_binding_state(stage: int):
|
|
var parent = get_parent()
|
|
if not parent:
|
|
printerr("[EventBinder] _update_updater_visibility parent is null. path: %s" % get_path())
|
|
return
|
|
# check stage in updater_stages
|
|
var updater_status = false
|
|
if updater_stage_mode == "exclude":
|
|
updater_status = not stage in updater_stages
|
|
elif updater_stage_mode == "include":
|
|
updater_status = stage in updater_stages
|
|
# check updater_mode
|
|
if updater_mode == "enabler":
|
|
parent.enabled = updater_status
|
|
elif updater_mode == "disabler":
|
|
parent.enabled = not updater_status
|
|
elif updater_mode == "shower":
|
|
_toggle_parent_visibility_with_ease(parent, updater_status)
|
|
elif updater_mode == "hider":
|
|
_toggle_parent_visibility_with_ease(parent, not updater_status)
|
|
|
|
|
|
func _toggle_parent_visibility_with_ease(parent, show: bool):
|
|
if parent is CanvasItem:
|
|
parent.visible = true
|
|
parent.modulate.a = 0.0 if show else 1.0
|
|
var target_a = 1.0 if show else 0.0
|
|
var tween = create_tween()
|
|
tween.tween_property(parent, "modulate:a", target_a, updater_ease_duration)
|
|
if not show:
|
|
tween.tween_callback(parent.hide)
|
|
|
|
|
|
func _auto_detect_mode():
|
|
# TODO 统一interacted played picked
|
|
var parent = get_parent()
|
|
if not parent:
|
|
printerr("[EventBinder] _auto_detect_mode parent is null. path: %s" % get_path())
|
|
if parent.has_signal("interacted"):
|
|
trigger_mode = "interacted"
|
|
elif parent.has_signal("triggered"):
|
|
trigger_mode = "triggered"
|
|
elif parent.has_signal("played"):
|
|
trigger_mode = "played"
|
|
else:
|
|
printerr("[EventBinder] _auto_detect_mode cannot detect trigger mode. path:", get_path())
|