From 34e70d48ce23ceb6d183bffa8a2a4dacf3117747 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Mon, 7 Aug 2023 14:36:19 +0200 Subject: [PATCH] Add BTSetVar action BTSetVar action can be used to assign any variant-type value to a blackboard variable. --- bt/actions/bt_set_var.cpp | 68 +++++++++++++++++++++++++++++++++++++++ bt/actions/bt_set_var.h | 46 ++++++++++++++++++++++++++ config.py | 1 + icons/BTSetVar.svg | 1 + register_types.cpp | 14 ++++---- 5 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 bt/actions/bt_set_var.cpp create mode 100644 bt/actions/bt_set_var.h create mode 100644 icons/BTSetVar.svg diff --git a/bt/actions/bt_set_var.cpp b/bt/actions/bt_set_var.cpp new file mode 100644 index 0000000..4f6e2fb --- /dev/null +++ b/bt/actions/bt_set_var.cpp @@ -0,0 +1,68 @@ +/** + * bt_set_var.cpp + * ============================================================================= + * Copyright 2021-2023 Serhii Snitsaruk + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ + +#include "bt_set_var.h" + +#include "modules/limboai/util/limbo_utility.h" + +#include "core/variant/callable.h" + +String BTSetVar::_generate_name() const { + if (variable.is_empty()) { + return "SetVar ???"; + } + return vformat("SetVar %s = %s", LimboUtility::get_singleton()->decorate_var(variable), + value.is_valid() ? Variant(value) : Variant("???")); +} + +int BTSetVar::_tick(double p_delta) { + ERR_FAIL_COND_V_MSG(variable.is_empty(), FAILURE, "BBSetVar: `variable` is not set."); + ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BBSetVar: `value` is not set."); + get_blackboard()->set_var(variable, value->get_value(get_agent(), get_blackboard())); + return SUCCESS; +}; + +void BTSetVar::set_variable(const String &p_variable) { + variable = p_variable; + emit_changed(); +} + +void BTSetVar::set_value(Ref p_value) { + value = p_value; + emit_changed(); + if (Engine::get_singleton()->is_editor_hint() && value.is_valid()) { + value->connect(SNAME("changed"), Callable(this, SNAME("emit_changed"))); + } +} + +String BTSetVar::get_configuration_warning() const { + String warning = BTAction::get_configuration_warning(); + if (!warning.is_empty()) { + warning += "\n"; + } + if (variable.is_empty()) { + warning += "`variable` should be assigned.\n"; + } + if (!value.is_valid()) { + warning += "`value` should be assigned.\n"; + } + return warning; +} + +void BTSetVar::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_variable", "p_variable"), &BTSetVar::set_variable); + ClassDB::bind_method(D_METHOD("get_variable"), &BTSetVar::get_variable); + ClassDB::bind_method(D_METHOD("set_value", "p_value"), &BTSetVar::set_value); + ClassDB::bind_method(D_METHOD("get_value"), &BTSetVar::get_value); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable"), "set_variable", "get_variable"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "value", PROPERTY_HINT_RESOURCE_TYPE, "BBVariant"), "set_value", "get_value"); +} diff --git a/bt/actions/bt_set_var.h b/bt/actions/bt_set_var.h new file mode 100644 index 0000000..f2f679f --- /dev/null +++ b/bt/actions/bt_set_var.h @@ -0,0 +1,46 @@ +/** + * bt_set_var.h + * ============================================================================= + * Copyright 2021-2023 Serhii Snitsaruk + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE file or at + * https://opensource.org/licenses/MIT. + * ============================================================================= + */ +/* bt_set_var.h */ + +#ifndef BT_SET_VAR_H +#define BT_SET_VAR_H + +#include "../actions/bt_action.h" + +#include "../../blackboard/bb_param/bb_variant.h" + +#include "core/object/object.h" +#include "core/string/ustring.h" + +class BTSetVar : public BTAction { + GDCLASS(BTSetVar, BTAction); + +private: + String variable; + Ref value; + +protected: + static void _bind_methods(); + + virtual String _generate_name() const override; + virtual int _tick(double p_delta) override; + +public: + virtual String get_configuration_warning() const override; + + void set_variable(const String &p_variable); + String get_variable() const { return variable; } + + void set_value(Ref p_value); + Ref get_value() const { return value; } +}; + +#endif // BT_SET_VAR \ No newline at end of file diff --git a/config.py b/config.py index 8ceb56a..bbfbd68 100644 --- a/config.py +++ b/config.py @@ -84,6 +84,7 @@ def get_doc_classes(): "BTRunLimit", "BTSelector", "BTSequence", + "BTSetVar", "BTState", "BTSubtree", "BTTask", diff --git a/icons/BTSetVar.svg b/icons/BTSetVar.svg new file mode 100644 index 0000000..09f6822 --- /dev/null +++ b/icons/BTSetVar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/register_types.cpp b/register_types.cpp index 5c4c24a..29d77d2 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -48,6 +48,7 @@ #include "bt/actions/bt_console_print.h" #include "bt/actions/bt_fail.h" #include "bt/actions/bt_random_wait.h" +#include "bt/actions/bt_set_var.h" #include "bt/actions/bt_wait.h" #include "bt/actions/bt_wait_ticks.h" #include "bt/behavior_tree.h" @@ -133,13 +134,14 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(BTForEach); GDREGISTER_CLASS(BTAction); - GDREGISTER_CLASS(BTFail); - GDREGISTER_CLASS(BTWait); - GDREGISTER_CLASS(BTRandomWait); - GDREGISTER_CLASS(BTWaitTicks); - GDREGISTER_CLASS(BTNewScope); - GDREGISTER_CLASS(BTSubtree); GDREGISTER_CLASS(BTConsolePrint); + GDREGISTER_CLASS(BTFail); + GDREGISTER_CLASS(BTNewScope); + GDREGISTER_CLASS(BTRandomWait); + GDREGISTER_CLASS(BTSetVar); + GDREGISTER_CLASS(BTSubtree); + GDREGISTER_CLASS(BTWait); + GDREGISTER_CLASS(BTWaitTicks); GDREGISTER_CLASS(BTCondition);