1
0
forked from joey/godottest
Joey Eamigh 9989fab018
addons?
2025-10-10 14:07:23 -04:00

96 lines
3.0 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
@icon("../../icons/selector_reactive.svg")
class_name SelectorReactiveComposite extends Composite
## Selector Reactive nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`.
## If a child returns `RUNNING` it will restart.
# Track where we last succeeded so we detect true branch changes
var previous_success_or_running_index: int = -1
var ready_to_interrupt_all: bool = false
func tick(actor: Node, blackboard: Blackboard) -> int:
var children := get_children()
var children_count = children.size()
var processed_count = 0
for i in range(children.size()):
var c = children[i]
if c != running_child:
c.before_run(actor, blackboard)
var response: int = c._safe_tick(actor, blackboard)
processed_count += 1
if can_send_message(blackboard):
BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response, blackboard.get_debug_data())
if c is ConditionLeaf:
blackboard.set_value("last_condition", c, str(actor.get_instance_id()))
blackboard.set_value("last_condition_status", response, str(actor.get_instance_id()))
match response:
SUCCESS:
# clean up the one that just succeeded
if running_child != null:
if running_child != c:
running_child.interrupt(actor, blackboard)
_cleanup_running(running_child, actor, blackboard)
c.after_run(actor, blackboard)
_interrupt_children(actor, blackboard, i, previous_success_or_running_index)
previous_success_or_running_index = i
ready_to_interrupt_all = false
return SUCCESS
FAILURE:
c.after_run(actor, blackboard)
RUNNING:
if c != running_child:
if running_child != null:
running_child.interrupt(actor, blackboard)
running_child = c
if c is ActionLeaf:
blackboard.set_value("running_action", c, str(actor.get_instance_id()))
_interrupt_children(actor, blackboard, i, previous_success_or_running_index)
previous_success_or_running_index = i
ready_to_interrupt_all = false
return RUNNING
# all failed → reset our successtracker
ready_to_interrupt_all = (processed_count == children_count)
return FAILURE
func after_run(actor: Node, blackboard: Blackboard) -> void:
super(actor, blackboard)
func interrupt(actor: Node, blackboard: Blackboard) -> void:
if ready_to_interrupt_all:
# If all children failed, interrupt all children
var children = get_children()
if children.size() > 0:
_interrupt_children(actor, blackboard, -1, children.size() - 1)
ready_to_interrupt_all = false
else:
# Use the normal interrupt logic for partial processing
_interrupt_children(actor, blackboard, -1, previous_success_or_running_index)
if running_child != null:
running_child.interrupt(actor, blackboard)
_cleanup_running(running_child, actor, blackboard)
previous_success_or_running_index = -1
super(actor, blackboard)
func get_class_name() -> Array[StringName]:
var classes := super()
classes.push_back(&"SelectorReactiveComposite")
return classes