behaviour-nodes-module/control_nodes.cpp
2026-03-13 10:38:52 +01:00

121 lines
3.4 KiB
C++

#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<BehaviourNode>(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<BehaviourNode>(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 {
set_status(get_child_behaviours().get(0)->get_status() == Fail
? Success
: Running);
}
}
BehaviourNode *BehaviourRepeatUntilFail::get_next() {
return get_status() == Running
? get_child_behaviours().get(0)
: cast_to<BehaviourNode>(get_parent());
}