Initial project sync
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
class_name TimePhaseAdapter
|
||||
extends Node
|
||||
|
||||
## Swaps this actor's time-phase Effects when the world phase changes.
|
||||
## Only ever talks to EffectContainer.add_effect / remove_effect; never
|
||||
## touches stats, state axes or animations directly. Actors without a
|
||||
## profile are simply unaffected by phase switches.
|
||||
|
||||
@export var profile: Resource
|
||||
@export var effect_container_path := NodePath("../EffectContainer")
|
||||
|
||||
@onready var effect_container: Node = get_node_or_null(effect_container_path)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for bus: Node in _event_buses():
|
||||
if bus.has_signal("time_phase_changed") and not bus.is_connected("time_phase_changed", _on_time_phase_changed):
|
||||
bus.connect("time_phase_changed", _on_time_phase_changed)
|
||||
apply_time_phase(_current_time_phase())
|
||||
|
||||
|
||||
func apply_time_phase(time_phase: StringName) -> void:
|
||||
if profile == null or effect_container == null:
|
||||
return
|
||||
for definition: Resource in _profile_effects(&"past") + _profile_effects(&"future"):
|
||||
if definition != null and effect_container.has_method("remove_effect"):
|
||||
effect_container.call("remove_effect", StringName(str(definition.get("id"))))
|
||||
for definition: Resource in _profile_effects(time_phase):
|
||||
if definition != null and effect_container.has_method("add_effect"):
|
||||
effect_container.call("add_effect", definition, &"time_phase")
|
||||
|
||||
|
||||
func visual_key() -> StringName:
|
||||
if profile != null and profile.has_method("visual_key_for_time_phase"):
|
||||
return profile.call("visual_key_for_time_phase", _current_time_phase())
|
||||
return _current_time_phase()
|
||||
|
||||
|
||||
func _on_time_phase_changed(_previous: StringName, current: StringName, _reason: StringName) -> void:
|
||||
apply_time_phase(current)
|
||||
|
||||
|
||||
func _profile_effects(time_phase: StringName) -> Array[Resource]:
|
||||
var result: Array[Resource] = []
|
||||
if profile == null:
|
||||
return result
|
||||
var effects = profile.call("effects_for_time_phase", time_phase) if profile.has_method("effects_for_time_phase") else null
|
||||
if effects is Array:
|
||||
for definition: Variant in effects:
|
||||
if definition is Resource:
|
||||
result.append(definition)
|
||||
return result
|
||||
|
||||
|
||||
func _current_time_phase() -> StringName:
|
||||
var manager := _time_phase_manager_or_null()
|
||||
if manager != null:
|
||||
return StringName(str(manager.get("current_time_phase")))
|
||||
return &"past"
|
||||
|
||||
|
||||
func _time_phase_manager_or_null() -> Node:
|
||||
if not is_inside_tree():
|
||||
return null
|
||||
return _last_root_child_matching(func(child: Node) -> bool:
|
||||
return child.has_method("set_time_phase") and child.get("current_time_phase") != null
|
||||
)
|
||||
|
||||
|
||||
func _event_buses() -> Array[Node]:
|
||||
var buses: Array[Node] = []
|
||||
if not is_inside_tree():
|
||||
return buses
|
||||
for child: Node in get_tree().root.get_children():
|
||||
if child.has_signal("time_phase_changed"):
|
||||
buses.append(child)
|
||||
return buses
|
||||
|
||||
|
||||
func _last_root_child_matching(predicate: Callable) -> Node:
|
||||
var children := get_tree().root.get_children()
|
||||
for index: int in range(children.size() - 1, -1, -1):
|
||||
var child: Node = children[index]
|
||||
if bool(predicate.call(child)):
|
||||
return child
|
||||
return null
|
||||
Reference in New Issue
Block a user