diff --git a/bt/actions/bt_set_agent_property.cpp b/bt/actions/bt_set_agent_property.cpp new file mode 100644 index 0000000..a204f98 --- /dev/null +++ b/bt/actions/bt_set_agent_property.cpp @@ -0,0 +1,68 @@ +/** + * bt_set_agent_property.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_agent_property.h" + +void BTSetAgentProperty::set_property_name(StringName p_prop) { + property_name = p_prop; + emit_changed(); +} + +void BTSetAgentProperty::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 BTSetAgentProperty::get_configuration_warning() const { + String warning = BTAction::get_configuration_warning(); + if (!warning.is_empty()) { + warning += "\n"; + } + if (property_name == StringName()) { + warning += "`property_name` should be assigned.\n"; + } + if (!value.is_valid()) { + warning += "`value` should be assigned.\n"; + } + return warning; +} + +String BTSetAgentProperty::_generate_name() const { + if (property_name == StringName()) { + return "SetAgentProperty ???"; + } + + return vformat("Set agent.%s = %s", property_name, + value.is_valid() ? Variant(value) : Variant("???")); +} + +int BTSetAgentProperty::_tick(double p_delta) { + ERR_FAIL_COND_V_MSG(property_name == StringName(), FAILURE, "BTSetAgentProperty: `property_name` is not set."); + ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTSetAgentProperty: `value` is not set."); + + bool r_valid; + get_agent()->set(property_name, value->get_value(get_agent(), get_blackboard()), &r_valid); + ERR_FAIL_COND_V_MSG(!r_valid, FAILURE, vformat("BTSetAgentProperty: Agent doesn't have property named \"%s\"", property_name)); + return SUCCESS; +} + +void BTSetAgentProperty::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_property_name", "p_property_name"), &BTSetAgentProperty::set_property_name); + ClassDB::bind_method(D_METHOD("get_property_name"), &BTSetAgentProperty::get_property_name); + ClassDB::bind_method(D_METHOD("set_value", "p_value"), &BTSetAgentProperty::set_value); + ClassDB::bind_method(D_METHOD("get_value"), &BTSetAgentProperty::get_value); + + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "property_name"), "set_property_name", "get_property_name"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "value", PROPERTY_HINT_RESOURCE_TYPE, "BBVariant"), "set_value", "get_value"); +} diff --git a/bt/actions/bt_set_agent_property.h b/bt/actions/bt_set_agent_property.h new file mode 100644 index 0000000..5b7d8a8 --- /dev/null +++ b/bt/actions/bt_set_agent_property.h @@ -0,0 +1,45 @@ +/** + * bt_set_agent_property.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. + * ============================================================================= + */ + +#ifndef BT_SET_AGENT_PROPERTY_H +#define BT_SET_AGENT_PROPERTY_H + +#include "modules/limboai/bt/actions/bt_action.h" + +#include "modules/limboai/blackboard/bb_param/bb_variant.h" + +#include "core/object/class_db.h" +#include "core/object/object.h" + +class BTSetAgentProperty : public BTAction { + GDCLASS(BTSetAgentProperty, BTAction); + +private: + StringName property_name; + 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_property_name(StringName p_prop); + StringName get_property_name() const { return property_name; } + + void set_value(Ref p_value); + Ref get_value() const { return value; } +}; + +#endif // BT_SET_AGENT_PROPERTY \ No newline at end of file diff --git a/config.py b/config.py index 41cb6df..8ddd132 100644 --- a/config.py +++ b/config.py @@ -87,6 +87,7 @@ def get_doc_classes(): "BTRunLimit", "BTSelector", "BTSequence", + "BTSetAgentProperty", "BTSetVar", "BTState", "BTSubtree", diff --git a/register_types.cpp b/register_types.cpp index 67400ba..80a3074 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_agent_property.h" #include "bt/actions/bt_set_var.h" #include "bt/actions/bt_wait.h" #include "bt/actions/bt_wait_ticks.h" @@ -142,6 +143,7 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) { GDREGISTER_CLASS(BTFail); GDREGISTER_CLASS(BTNewScope); GDREGISTER_CLASS(BTRandomWait); + GDREGISTER_CLASS(BTSetAgentProperty); GDREGISTER_CLASS(BTSetVar); GDREGISTER_CLASS(BTSubtree); GDREGISTER_CLASS(BTWait);