From a3cac931748678471f8766241f7a480da389ae7e Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 20 Sep 2022 19:15:48 +0200 Subject: [PATCH] Add NewScope and refactor Subtree --- bt/actions/bt_subtree.cpp | 35 --------------- bt/bt_task.h | 2 +- bt/decorators/bt_new_scope.cpp | 26 +++++++++++ bt/decorators/bt_new_scope.h | 28 ++++++++++++ bt/decorators/bt_subtree.cpp | 59 +++++++++++++++++++++++++ bt/{actions => decorators}/bt_subtree.h | 7 +-- icons/icon_b_t_new_scope.svg | 1 + register_types.cpp | 4 +- 8 files changed, 122 insertions(+), 40 deletions(-) delete mode 100644 bt/actions/bt_subtree.cpp create mode 100644 bt/decorators/bt_new_scope.cpp create mode 100644 bt/decorators/bt_new_scope.h create mode 100644 bt/decorators/bt_subtree.cpp rename bt/{actions => decorators}/bt_subtree.h (76%) create mode 100644 icons/icon_b_t_new_scope.svg diff --git a/bt/actions/bt_subtree.cpp b/bt/actions/bt_subtree.cpp deleted file mode 100644 index c289f94..0000000 --- a/bt/actions/bt_subtree.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* bt_subtree.cpp */ - -#include "bt_subtree.h" -#include "core/error_macros.h" -#include "core/object.h" -#include "core/variant.h" -#include "modules/limboai/bt/actions/bt_action.h" - -String BTSubtree::_generate_name() const { - return vformat("Subtree '%s'", subtree.is_null() ? "?" : subtree->get_path()); -} - -Ref BTSubtree::clone() const { - ERR_FAIL_COND_V_MSG(!subtree.is_valid(), nullptr, vformat("Subtree is not valid (%s)", get_agent())); - ERR_FAIL_COND_V_MSG(!subtree->get_root_task().is_valid(), nullptr, vformat("Subtree root task is not valid (%s)", get_agent())); - return subtree->get_root_task()->clone(); -} - -String BTSubtree::get_configuration_warning() const { - String warning = BTAction::get_configuration_warning(); - if (!warning.empty()) { - warning += "\n"; - } - if (subtree.is_null()) { - warning += "Subtree needs to be assigned.\n"; - } - return warning; -} - -void BTSubtree::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_subtree", "p_value"), &BTSubtree::set_subtree); - ClassDB::bind_method(D_METHOD("get_subtree"), &BTSubtree::get_subtree); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "subtree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_subtree", "get_subtree"); -} \ No newline at end of file diff --git a/bt/bt_task.h b/bt/bt_task.h index 5a71a79..ec5a5a0 100644 --- a/bt/bt_task.h +++ b/bt/bt_task.h @@ -57,7 +57,7 @@ public: void set_custom_name(const String &p_name); String get_task_name() const; - void initialize(Object *p_agent, const Ref &p_blackboard); + virtual void initialize(Object *p_agent, const Ref &p_blackboard); virtual Ref clone() const; int execute(float p_delta); void cancel(); diff --git a/bt/decorators/bt_new_scope.cpp b/bt/decorators/bt_new_scope.cpp new file mode 100644 index 0000000..70adf3c --- /dev/null +++ b/bt/decorators/bt_new_scope.cpp @@ -0,0 +1,26 @@ +/* bt_new_scope.cpp */ + +#include "bt_new_scope.h" +#include "core/error_macros.h" +#include "core/ustring.h" + +void BTNewScope::initialize(Object *p_agent, const Ref &p_blackboard) { + ERR_FAIL_COND(p_agent == nullptr); + ERR_FAIL_COND(p_blackboard == nullptr); + Ref bb = memnew(Blackboard); + bb->set_parent_scope(p_blackboard); + bb->set_data(blackboard_data); + BTDecorator::initialize(p_agent, bb); +} + +int BTNewScope::_tick(float p_delta) { + ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator doesn't have a child."); + return get_child(0)->execute(p_delta); +} + +void BTNewScope::_bind_methods() { + ClassDB::bind_method(D_METHOD("_set_blackboard_data", "p_data"), &BTNewScope::_set_blackboard_data); + ClassDB::bind_method(D_METHOD("_get_blackboard_data"), &BTNewScope::_get_blackboard_data); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_blackboard_data"), "_set_blackboard_data", "_get_blackboard_data"); +} \ No newline at end of file diff --git a/bt/decorators/bt_new_scope.h b/bt/decorators/bt_new_scope.h new file mode 100644 index 0000000..18d4fcb --- /dev/null +++ b/bt/decorators/bt_new_scope.h @@ -0,0 +1,28 @@ +/* bt_new_scope.h */ + +#ifndef BT_NEW_SCOPE_H +#define BT_NEW_SCOPE_H + +#include "bt_decorator.h" +#include "core/object.h" + +#include "bt_decorator.h" +class BTNewScope : public BTDecorator { + GDCLASS(BTNewScope, BTDecorator); + +private: + Dictionary blackboard_data; + +protected: + static void _bind_methods(); + + void _set_blackboard_data(const Dictionary &p_value) { blackboard_data = p_value; } + Dictionary _get_blackboard_data() const { return blackboard_data; } + + virtual int _tick(float p_delta); + +public: + virtual void initialize(Object *p_agent, const Ref &p_blackboard); +}; + +#endif // BT_NEW_SCOPE_H \ No newline at end of file diff --git a/bt/decorators/bt_subtree.cpp b/bt/decorators/bt_subtree.cpp new file mode 100644 index 0000000..50bd01e --- /dev/null +++ b/bt/decorators/bt_subtree.cpp @@ -0,0 +1,59 @@ +/* bt_subtree.cpp */ + +#include "bt_subtree.h" +#include "core/engine.h" +#include "core/error_macros.h" +#include "core/object.h" +#include "core/typedefs.h" +#include "core/variant.h" +#include "modules/limboai/blackboard.h" +#include "modules/limboai/bt/actions/bt_action.h" +#include "modules/limboai/bt/actions/bt_fail.h" +#include "modules/limboai/bt/bt_task.h" +#include "modules/limboai/bt/decorators/bt_decorator.h" + +String BTSubtree::_generate_name() const { + String s; + if (subtree.is_null()) { + s = "(unassigned)"; + } else if (subtree->get_path().empty()) { + s = "(unsaved)"; + } else { + s = vformat("\"%s\"", subtree->get_path()); + } + return vformat("Subtree %s", s); +} + +Ref BTSubtree::clone() const { + Ref copy = BTDecorator::clone(); + if (!Engine::get_singleton()->is_editor_hint()) { + ERR_FAIL_COND_V_MSG(!subtree.is_valid(), copy, "Subtree is not assigned."); + ERR_FAIL_COND_V_MSG(!subtree->get_root_task().is_valid(), copy, "Subtree root task is not valid."); + + copy->add_child(subtree->get_root_task()->clone()); + } + return copy; +} + +int BTSubtree::_tick(float p_delta) { + ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator doesn't have a child."); + return get_child(0)->execute(p_delta); +} + +String BTSubtree::get_configuration_warning() const { + String warning = BTTask::get_configuration_warning(); // BTDecorator skipped intentionally + if (!warning.empty()) { + warning += "\n"; + } + if (subtree.is_null()) { + warning += "Subtree needs to be assigned.\n"; + } + return warning; +} + +void BTSubtree::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_subtree", "p_value"), &BTSubtree::set_subtree); + ClassDB::bind_method(D_METHOD("get_subtree"), &BTSubtree::get_subtree); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "subtree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_subtree", "get_subtree"); +} \ No newline at end of file diff --git a/bt/actions/bt_subtree.h b/bt/decorators/bt_subtree.h similarity index 76% rename from bt/actions/bt_subtree.h rename to bt/decorators/bt_subtree.h index e8a271f..f700d51 100644 --- a/bt/actions/bt_subtree.h +++ b/bt/decorators/bt_subtree.h @@ -3,12 +3,12 @@ #ifndef BT_SUBTREE_H #define BT_SUBTREE_H -#include "bt_action.h" +#include "bt_new_scope.h" #include "core/object.h" #include "modules/limboai/bt/behavior_tree.h" -class BTSubtree : public BTAction { - GDCLASS(BTSubtree, BTAction); +class BTSubtree : public BTNewScope { + GDCLASS(BTSubtree, BTNewScope); private: Ref subtree; @@ -17,6 +17,7 @@ protected: static void _bind_methods(); virtual String _generate_name() const; + virtual int _tick(float p_delta); public: void set_subtree(const Ref &p_value) { diff --git a/icons/icon_b_t_new_scope.svg b/icons/icon_b_t_new_scope.svg new file mode 100644 index 0000000..74acbaf --- /dev/null +++ b/icons/icon_b_t_new_scope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/register_types.cpp b/register_types.cpp index 101c9e6..79820a9 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -9,7 +9,6 @@ #include "bt/actions/bt_console_print.h" #include "bt/actions/bt_fail.h" #include "bt/actions/bt_random_wait.h" -#include "bt/actions/bt_subtree.h" #include "bt/actions/bt_wait.h" #include "bt/actions/bt_wait_ticks.h" #include "bt/behavior_tree.h" @@ -30,11 +29,13 @@ #include "bt/decorators/bt_decorator.h" #include "bt/decorators/bt_delay.h" #include "bt/decorators/bt_invert.h" +#include "bt/decorators/bt_new_scope.h" #include "bt/decorators/bt_probability.h" #include "bt/decorators/bt_repeat.h" #include "bt/decorators/bt_repeat_until_failure.h" #include "bt/decorators/bt_repeat_until_success.h" #include "bt/decorators/bt_run_limit.h" +#include "bt/decorators/bt_subtree.h" #include "bt/decorators/bt_time_limit.h" #include "limbo_string_names.h" #include "limbo_utility.h" @@ -77,6 +78,7 @@ void register_limboai_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class();