Add `agent` parameter to `BTPlayer` to propagate upon `BehaviorTree` initialization, and add `scene_root` property to `BTTask`
`scene_root` is useful to resolve exported NodePath properties in `BTTask` instances (and for BBNode parameters).
This commit is contained in:
parent
75e8e68da4
commit
5dff2e537b
|
@ -71,10 +71,10 @@ void BehaviorTree::copy_other(const Ref<BehaviorTree> &p_other) {
|
|||
root_task = p_other->get_root_task();
|
||||
}
|
||||
|
||||
Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const {
|
||||
Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const {
|
||||
ERR_FAIL_COND_V_MSG(root_task == nullptr, memnew(BTTask), "Trying to instance a behavior tree with no valid root task.");
|
||||
Ref<BTTask> inst = root_task->clone();
|
||||
inst->initialize(p_agent, p_blackboard);
|
||||
inst->initialize(p_agent, p_blackboard, p_scene_root);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
Ref<BehaviorTree> clone() const;
|
||||
void copy_other(const Ref<BehaviorTree> &p_other);
|
||||
Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const;
|
||||
Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const;
|
||||
|
||||
BehaviorTree();
|
||||
~BehaviorTree();
|
||||
|
|
|
@ -50,9 +50,13 @@ void BTPlayer::_load_tree() {
|
|||
}
|
||||
#endif
|
||||
tree_instance.unref();
|
||||
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Needs a valid behavior tree.");
|
||||
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Behavior tree has no valid root task.");
|
||||
tree_instance = behavior_tree->instantiate(get_owner(), blackboard);
|
||||
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree.");
|
||||
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task.");
|
||||
Node *agent_node = GET_NODE(this, agent);
|
||||
ERR_FAIL_NULL_MSG(agent_node, vformat("BTPlayer: Initialization failed - can't get agent by provided path '%s'.", agent));
|
||||
Node *scene_root = get_owner();
|
||||
ERR_FAIL_NULL_MSG(scene_root, "BTPlayer: Initialization failed - can't get scene root (make sure the BTPlayer.owner is set).");
|
||||
tree_instance = behavior_tree->instantiate(agent_node, blackboard, scene_root);
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (IS_DEBUGGER_ACTIVE()) {
|
||||
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
||||
|
@ -228,6 +232,8 @@ void BTPlayer::_notification(int p_notification) {
|
|||
void BTPlayer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_behavior_tree", "behavior_tree"), &BTPlayer::set_behavior_tree);
|
||||
ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTPlayer::get_behavior_tree);
|
||||
ClassDB::bind_method(D_METHOD("set_agent", "agent"), &BTPlayer::set_agent);
|
||||
ClassDB::bind_method(D_METHOD("get_agent"), &BTPlayer::get_agent);
|
||||
ClassDB::bind_method(D_METHOD("set_update_mode", "update_mode"), &BTPlayer::set_update_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_update_mode"), &BTPlayer::get_update_mode);
|
||||
ClassDB::bind_method(D_METHOD("set_active", "active"), &BTPlayer::set_active);
|
||||
|
@ -245,6 +251,7 @@ void BTPlayer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_tree_instance"), &BTPlayer::get_tree_instance);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent"), "set_agent", "get_agent");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,Manual"), "set_update_mode", "get_update_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "get_active");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_NONE, "Blackboard", 0), "set_blackboard", "get_blackboard");
|
||||
|
@ -266,6 +273,7 @@ void BTPlayer::_bind_methods() {
|
|||
|
||||
BTPlayer::BTPlayer() {
|
||||
blackboard = Ref<Blackboard>(memnew(Blackboard));
|
||||
agent = LW_NAME(node_pp);
|
||||
}
|
||||
|
||||
BTPlayer::~BTPlayer() {
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
private:
|
||||
Ref<BehaviorTree> behavior_tree;
|
||||
NodePath agent;
|
||||
Ref<BlackboardPlan> blackboard_plan;
|
||||
UpdateMode update_mode = UpdateMode::PHYSICS;
|
||||
bool active = true;
|
||||
|
@ -57,6 +58,9 @@ public:
|
|||
void set_behavior_tree(const Ref<BehaviorTree> &p_tree);
|
||||
Ref<BehaviorTree> get_behavior_tree() const { return behavior_tree; };
|
||||
|
||||
void set_agent(const NodePath &p_agent) { agent = p_agent; }
|
||||
NodePath get_agent() const { return agent; }
|
||||
|
||||
void set_blackboard_plan(const Ref<BlackboardPlan> &p_plan);
|
||||
Ref<BlackboardPlan> get_blackboard_plan() const { return blackboard_plan; }
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ void BTState::_setup() {
|
|||
LimboState::_setup();
|
||||
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
||||
// TODO: BBNode relies on agent to be scene owner, so if the user provides anything else, the behavior tree can break.
|
||||
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard());
|
||||
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), get_owner());
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||
|
|
|
@ -159,13 +159,15 @@ void BTTask::set_custom_name(const String &p_name) {
|
|||
}
|
||||
};
|
||||
|
||||
void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
|
||||
ERR_FAIL_COND(p_agent == nullptr);
|
||||
ERR_FAIL_COND(p_blackboard == nullptr);
|
||||
void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
||||
ERR_FAIL_NULL(p_agent);
|
||||
ERR_FAIL_NULL(p_blackboard);
|
||||
ERR_FAIL_NULL(p_scene_root);
|
||||
data.agent = p_agent;
|
||||
data.blackboard = p_blackboard;
|
||||
data.scene_root = p_scene_root;
|
||||
for (int i = 0; i < data.children.size(); i++) {
|
||||
get_child(i)->initialize(p_agent, p_blackboard);
|
||||
get_child(i)->initialize(p_agent, p_blackboard, p_scene_root);
|
||||
}
|
||||
|
||||
VCALL_OR_NATIVE(_setup);
|
||||
|
@ -399,6 +401,7 @@ void BTTask::_bind_methods() {
|
|||
// Properties, setters and getters.
|
||||
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
|
||||
ClassDB::bind_method(D_METHOD("set_agent", "agent"), &BTTask::set_agent);
|
||||
ClassDB::bind_method(D_METHOD("get_scene_root"), &BTTask::get_scene_root);
|
||||
ClassDB::bind_method(D_METHOD("_get_children"), &BTTask::_get_children);
|
||||
ClassDB::bind_method(D_METHOD("_set_children", "children"), &BTTask::_set_children);
|
||||
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTTask::get_blackboard);
|
||||
|
@ -410,6 +413,7 @@ void BTTask::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_name"), "set_custom_name", "get_custom_name");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_agent", "get_agent");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene_root", PROPERTY_HINT_NODE_TYPE, "Node", PROPERTY_USAGE_NONE), "", "get_scene_root");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", PROPERTY_USAGE_NONE), "", "get_blackboard");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_children", "_get_children");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "status", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "", "get_status");
|
||||
|
|
|
@ -75,6 +75,7 @@ private:
|
|||
int index = -1;
|
||||
String custom_name;
|
||||
Node *agent = nullptr;
|
||||
Node *scene_root = nullptr;
|
||||
Ref<Blackboard> blackboard;
|
||||
BTTask *parent = nullptr;
|
||||
Vector<Ref<BTTask>> children;
|
||||
|
@ -116,6 +117,8 @@ public:
|
|||
_FORCE_INLINE_ Node *get_agent() const { return data.agent; }
|
||||
void set_agent(Node *p_agent) { data.agent = p_agent; }
|
||||
|
||||
_FORCE_INLINE_ Node *get_scene_root() const { return data.scene_root; }
|
||||
|
||||
void set_display_collapsed(bool p_display_collapsed);
|
||||
bool is_displayed_collapsed() const;
|
||||
|
||||
|
@ -126,7 +129,7 @@ public:
|
|||
Ref<BTTask> get_root() const;
|
||||
|
||||
virtual Ref<BTTask> clone() const;
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard);
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root);
|
||||
virtual PackedStringArray get_configuration_warnings(); // ! Native version.
|
||||
|
||||
Status execute(double p_delta);
|
||||
|
|
|
@ -20,7 +20,7 @@ void BTNewScope::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
|||
emit_changed();
|
||||
}
|
||||
|
||||
void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
|
||||
void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
||||
ERR_FAIL_COND(p_agent == nullptr);
|
||||
ERR_FAIL_COND(p_blackboard == nullptr);
|
||||
|
||||
|
@ -33,7 +33,7 @@ void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard)
|
|||
|
||||
bb->set_parent(p_blackboard);
|
||||
|
||||
BTDecorator::initialize(p_agent, bb);
|
||||
BTDecorator::initialize(p_agent, bb, p_scene_root);
|
||||
}
|
||||
|
||||
BT::Status BTNewScope::_tick(double p_delta) {
|
||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
|||
virtual Status _tick(double p_delta) override;
|
||||
|
||||
public:
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) override;
|
||||
};
|
||||
|
||||
#endif // BT_NEW_SCOPE_H
|
||||
|
|
|
@ -44,14 +44,14 @@ String BTSubtree::_generate_name() {
|
|||
return vformat("Subtree %s", s);
|
||||
}
|
||||
|
||||
void BTSubtree::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
|
||||
void BTSubtree::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
||||
ERR_FAIL_COND_MSG(!subtree.is_valid(), "Subtree is not assigned.");
|
||||
ERR_FAIL_COND_MSG(!subtree->get_root_task().is_valid(), "Subtree root task is not valid.");
|
||||
ERR_FAIL_COND_MSG(get_child_count() != 0, "Subtree task shouldn't have children during initialization.");
|
||||
|
||||
add_child(subtree->get_root_task()->clone());
|
||||
|
||||
BTNewScope::initialize(p_agent, p_blackboard);
|
||||
BTNewScope::initialize(p_agent, p_blackboard, p_scene_root);
|
||||
}
|
||||
|
||||
BT::Status BTSubtree::_tick(double p_delta) {
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
void set_subtree(const Ref<BehaviorTree> &p_value);
|
||||
Ref<BehaviorTree> get_subtree() const { return subtree; }
|
||||
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
|
||||
virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) override;
|
||||
virtual PackedStringArray get_configuration_warnings() override;
|
||||
|
||||
BTSubtree() = default;
|
||||
|
|
|
@ -51,13 +51,13 @@ TEST_CASE("[SceneTree][LimboAI] BTAwaitAnimation") {
|
|||
SUBCASE("When AnimationPlayer doesn't exist") {
|
||||
player_param->set_saved_value(NodePath("./NotFound"));
|
||||
ERR_PRINT_OFF;
|
||||
awa->initialize(dummy, bb);
|
||||
awa->initialize(dummy, bb, dummy);
|
||||
CHECK(awa->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("When AnimationPlayer exists") {
|
||||
player_param->set_saved_value(player->get_path());
|
||||
awa->initialize(dummy, bb);
|
||||
awa->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When AnimationPlayer is not playing") {
|
||||
REQUIRE_FALSE(player->is_playing());
|
||||
|
|
|
@ -47,7 +47,7 @@ TEST_CASE("[Modules][LimboAI] BTCallMethod") {
|
|||
node_param->set_variable("object");
|
||||
cm->set_method("callback");
|
||||
|
||||
cm->initialize(dummy, bb);
|
||||
cm->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When method is empty") {
|
||||
cm->set_method("");
|
||||
|
|
|
@ -39,7 +39,7 @@ TEST_CASE("[Modules][LimboAI] BTCheckAgentProperty") {
|
|||
Ref<BTCheckAgentProperty> cap = memnew(BTCheckAgentProperty);
|
||||
Node *agent = memnew(Node);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
cap->initialize(agent, bb);
|
||||
cap->initialize(agent, bb, agent);
|
||||
StringName agent_name = "SimpleNode";
|
||||
agent->set_name(agent_name);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ TEST_CASE("[Modules][LimboAI] BTCheckTrigger") {
|
|||
Node *dummy = memnew(Node);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
|
||||
ct->initialize(dummy, bb);
|
||||
ct->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("Empty") {
|
||||
ERR_PRINT_OFF;
|
||||
|
|
|
@ -36,7 +36,7 @@ TEST_CASE("[Modules][LimboAI] BTCheckVar") {
|
|||
Ref<BTCheckVar> cv = memnew(BTCheckVar);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
Node *dummy = memnew(Node);
|
||||
cv->initialize(dummy, bb);
|
||||
cv->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("Check with empty variable and value") {
|
||||
cv->set_variable("");
|
||||
|
|
|
@ -47,7 +47,7 @@ TEST_CASE("[Modules][LimboAI] BTEvaluateExpression") {
|
|||
node_param->set_variable("object");
|
||||
ee->set_expression_string("callback()");
|
||||
|
||||
ee->initialize(dummy, bb);
|
||||
ee->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When expression string is empty") {
|
||||
ee->set_expression_string("");
|
||||
|
|
|
@ -23,7 +23,7 @@ TEST_CASE("[Modules][LimboAI] BTForEach") {
|
|||
Ref<BTForEach> fe = memnew(BTForEach);
|
||||
Node *dummy = memnew(Node);
|
||||
Ref<Blackboard> blackboard = memnew(Blackboard);
|
||||
fe->initialize(dummy, blackboard);
|
||||
fe->initialize(dummy, blackboard, dummy);
|
||||
|
||||
Array arr;
|
||||
arr.append("apple");
|
||||
|
|
|
@ -26,7 +26,7 @@ TEST_CASE("[Modules][LimboAI] BTNewScope") {
|
|||
|
||||
SUBCASE("When empty") {
|
||||
ERR_PRINT_OFF;
|
||||
ns->initialize(dummy, parent_bb);
|
||||
ns->initialize(dummy, parent_bb, dummy);
|
||||
CHECK(ns->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ TEST_CASE("[Modules][LimboAI] BTNewScope") {
|
|||
REQUIRE(parent_bb->has_var("vegetable"));
|
||||
REQUIRE(parent_bb->get_var("vegetable", "wetgoop") == "carrot");
|
||||
|
||||
parent->initialize(dummy, parent_bb);
|
||||
parent->initialize(dummy, parent_bb, dummy);
|
||||
|
||||
CHECK(ns->get_blackboard() != parent->get_blackboard());
|
||||
CHECK(ns->get_blackboard() == child->get_blackboard());
|
||||
|
|
|
@ -48,13 +48,13 @@ TEST_CASE("[SceneTree][LimboAI] BTPauseAnimation") {
|
|||
SUBCASE("When AnimationPlayer doesn't exist") {
|
||||
player_param->set_saved_value(NodePath("./NotFound"));
|
||||
ERR_PRINT_OFF;
|
||||
pa->initialize(dummy, bb);
|
||||
pa->initialize(dummy, bb, dummy);
|
||||
CHECK(pa->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("When AnimationPlayer exists") {
|
||||
player_param->set_saved_value(player->get_path());
|
||||
pa->initialize(dummy, bb);
|
||||
pa->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When AnimationPlayer is not playing") {
|
||||
REQUIRE_FALSE(player->is_playing());
|
||||
|
|
|
@ -49,13 +49,13 @@ TEST_CASE("[SceneTree][LimboAI] BTPlayAnimation") {
|
|||
SUBCASE("When AnimationPlayer doesn't exist") {
|
||||
player_param->set_saved_value(NodePath("./NotFound"));
|
||||
ERR_PRINT_OFF;
|
||||
pa->initialize(dummy, bb);
|
||||
pa->initialize(dummy, bb, dummy);
|
||||
CHECK(pa->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("When AnimationPlayer exists") {
|
||||
player_param->set_saved_value(player->get_path());
|
||||
pa->initialize(dummy, bb);
|
||||
pa->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When not waiting to finish") {
|
||||
pa->set_await_completion(0.0);
|
||||
|
|
|
@ -28,7 +28,7 @@ TEST_CASE("[Modules][LimboAI] BTSetAgentProperty") {
|
|||
Ref<BTSetAgentProperty> sap = memnew(BTSetAgentProperty);
|
||||
Node *agent = memnew(Node);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
sap->initialize(agent, bb);
|
||||
sap->initialize(agent, bb, agent);
|
||||
|
||||
sap->set_property("process_priority"); // * property that will be set by the task
|
||||
Ref<BBVariant> value = memnew(BBVariant);
|
||||
|
|
|
@ -29,7 +29,7 @@ TEST_CASE("[Modules][LimboAI] BTSetVar") {
|
|||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
Node *dummy = memnew(Node);
|
||||
|
||||
sv->initialize(dummy, bb);
|
||||
sv->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When variable is not set") {
|
||||
ERR_PRINT_OFF;
|
||||
|
|
|
@ -48,13 +48,13 @@ TEST_CASE("[SceneTree][LimboAI] BTStopAnimation") {
|
|||
SUBCASE("When AnimationPlayer doesn't exist") {
|
||||
player_param->set_saved_value(NodePath("./NotFound"));
|
||||
ERR_PRINT_OFF;
|
||||
sa->initialize(dummy, bb);
|
||||
sa->initialize(dummy, bb, dummy);
|
||||
CHECK(sa->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("When AnimationPlayer exists") {
|
||||
player_param->set_saved_value(player->get_path());
|
||||
sa->initialize(dummy, bb);
|
||||
sa->initialize(dummy, bb, dummy);
|
||||
|
||||
SUBCASE("When AnimationPlayer is not playing") {
|
||||
REQUIRE_FALSE(player->is_playing());
|
||||
|
|
|
@ -29,7 +29,7 @@ TEST_CASE("[Modules][LimboAI] BTSubtree") {
|
|||
|
||||
SUBCASE("When empty") {
|
||||
ERR_PRINT_OFF;
|
||||
st->initialize(dummy, bb);
|
||||
st->initialize(dummy, bb, dummy);
|
||||
CHECK(st->execute(0.01666) == BTTask::FAILURE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ TEST_CASE("[Modules][LimboAI] BTSubtree") {
|
|||
st->set_subtree(bt);
|
||||
|
||||
CHECK(st->get_child_count() == 0);
|
||||
st->initialize(dummy, bb);
|
||||
st->initialize(dummy, bb, dummy);
|
||||
CHECK(st->get_child_count() == 1);
|
||||
CHECK(st->get_child(0) != task);
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ TEST_CASE("[Modules][LimboAI] BTTask") {
|
|||
Node *dummy = memnew(Node);
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
SUBCASE("With valid parameters") {
|
||||
task->initialize(dummy, bb);
|
||||
task->initialize(dummy, bb, dummy);
|
||||
CHECK(task->get_agent() == dummy);
|
||||
CHECK(task->get_blackboard() == bb);
|
||||
CHECK(child1->get_agent() == dummy);
|
||||
|
@ -174,12 +174,17 @@ TEST_CASE("[Modules][LimboAI] BTTask") {
|
|||
}
|
||||
SUBCASE("Test if not crashes when agent is null") {
|
||||
ERR_PRINT_OFF;
|
||||
task->initialize(nullptr, bb);
|
||||
task->initialize(nullptr, bb, dummy);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("Test if not crashes when scene_owner is null") {
|
||||
ERR_PRINT_OFF;
|
||||
task->initialize(dummy, bb, nullptr);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
SUBCASE("Test if not crashes when BB is null") {
|
||||
ERR_PRINT_OFF;
|
||||
task->initialize(dummy, nullptr);
|
||||
task->initialize(dummy, nullptr, dummy);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
memdelete(dummy);
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define PERFORMANCE_ADD_CUSTOM_MONITOR(m_id, m_callable) (Performance::get_singleton()->add_custom_monitor(m_id, m_callable, Variant()))
|
||||
#define GET_SCRIPT(m_obj) (m_obj->get_script_instance() ? m_obj->get_script_instance()->get_script() : nullptr)
|
||||
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_style_override(m_name, m_stylebox))
|
||||
#define GET_NODE(m_parent, m_path) m_parent->get_node(m_path)
|
||||
|
||||
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
||||
bool r_valid;
|
||||
|
@ -137,6 +138,7 @@ using namespace godot;
|
|||
#define PERFORMANCE_ADD_CUSTOM_MONITOR(m_id, m_callable) (Performance::get_singleton()->add_custom_monitor(m_id, m_callable))
|
||||
#define GET_SCRIPT(m_obj) (m_obj->get_script())
|
||||
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_stylebox_override(m_name, m_stylebox))
|
||||
#define GET_NODE(m_parent, m_path) m_parent->get_node_internal(m_path)
|
||||
|
||||
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
||||
return Variant(p_obj).has_key(p_prop);
|
||||
|
|
|
@ -166,4 +166,6 @@ LimboStringNames::LimboStringNames() {
|
|||
|
||||
repeat_forever.parse_utf8("Repeat ∞");
|
||||
output_var_prefix.parse_utf8("➜");
|
||||
|
||||
node_pp = NodePath("..");
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define LIMBO_STRING_NAMES_H
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/string/node_path.h"
|
||||
#include "core/string/string_name.h"
|
||||
#include "core/typedefs.h"
|
||||
#include "modules/register_module_types.h"
|
||||
|
@ -20,6 +21,7 @@
|
|||
|
||||
#ifdef LIMBOAI_GDEXTENSION
|
||||
#include "godot_cpp/variant/string.hpp"
|
||||
#include <godot_cpp/variant/node_path.hpp>
|
||||
#include <godot_cpp/variant/string_name.hpp>
|
||||
using namespace godot;
|
||||
#endif // LIMBOAI_GDEXTENSION
|
||||
|
@ -181,6 +183,8 @@ public:
|
|||
|
||||
String repeat_forever;
|
||||
String output_var_prefix;
|
||||
|
||||
NodePath node_pp;
|
||||
};
|
||||
|
||||
#define LW_NAME(m_arg) LimboStringNames::get_singleton()->m_arg
|
||||
|
|
Loading…
Reference in New Issue