#include "control_nodes.h" #include "behaviour_nodes/behaviour_node.h" PackedStringArray BehaviourSequence::get_configuration_warnings() const { PackedStringArray warnings{ super_type::get_configuration_warnings() }; if (get_child_behaviours().is_empty()) { warnings.push_back("Sequence cannot have zero children"); } return warnings; } void BehaviourSequence::execute() { if (get_child_behaviours().is_empty()) { set_status(Fail); ERR_FAIL_EDMSG("BehaviourSequence executed with no children."); } else if (get_status() == Running && this->current >= 0 && this->current < get_child_behaviours().size()) { switch (get_child_behaviours().get(this->current)->get_status()) { case Running: set_status(Running); break; case Fail: set_status(Fail); break; case Success: ++this->current; set_status(this->current >= get_child_behaviours().size() ? Success : Running); break; } } else { set_status(Running); this->current = 0; } } BehaviourNode *BehaviourSequence::get_next() { return get_status() == Running ? get_child_behaviours().get(this->current) : cast_to(get_parent()); } PackedStringArray BehaviourSelector::get_configuration_warnings() const { PackedStringArray warnings{ super_type::get_configuration_warnings() }; if (get_child_behaviours().is_empty()) { warnings.push_back("Selector cannot have zero children"); } return warnings; } void BehaviourSelector::execute() { if (get_child_behaviours().is_empty()) { set_status(Fail); ERR_FAIL_EDMSG("BehaviourSelector execution with no children."); } else if (get_status() == Running && this->current >= 0 && this->current < get_child_behaviours().size()) { switch (get_child_behaviours().get(this->current)->get_status()) { case Running: set_status(Running); break; case Fail: ++this->current; set_status(this->current >= get_child_behaviours().size() ? Fail : Running); break; case Success: set_status(Success); break; } } else { set_status(Running); this->current = 0; } } BehaviourNode *BehaviourSelector::get_next() { return get_status() == Running ? get_child_behaviours().get(this->current) : cast_to(get_parent()); } PackedStringArray BehaviourRepeater::get_configuration_warnings() const { PackedStringArray warnings{ super_type::get_configuration_warnings() }; if (get_child_behaviours().size() != 1) { warnings.push_back(vformat("Repeater should have exactly one BehaviourNode child, has %d", get_child_behaviours().size())); } return warnings; } void BehaviourRepeater::execute() { set_status(Running); } BehaviourNode *BehaviourRepeater::get_next() { return get_child_behaviours().get(0); } PackedStringArray BehaviourRepeatUntilFail::get_configuration_warnings() const { PackedStringArray warnings{ super_type::get_configuration_warnings() }; if (get_child_behaviours().size() != 1) { warnings.push_back("RepeatUntilFailure should have exactly one BehaviourNode child"); } return warnings; } void BehaviourRepeatUntilFail::execute() { if (get_child_behaviours().is_empty()) { set_status(Fail); ERR_FAIL_EDMSG("BehaviourRepeatUntilFail execution with no child"); } else if (get_status() == Running) { set_status(get_child_behaviours().get(0)->get_status() == Fail ? Success : Running); } else { set_status(Running); } } BehaviourNode *BehaviourRepeatUntilFail::get_next() { return get_status() == Running ? get_child_behaviours().get(0) : cast_to(get_parent()); }