Merge branch 'blackboard-tasks'

This commit is contained in:
Serhii Snitsaruk 2023-08-11 13:49:05 +02:00
commit de2137bfd2
67 changed files with 1041 additions and 115 deletions

View File

@ -29,10 +29,6 @@ void BBParam::set_value_source(ValueSource p_value) {
} }
Variant BBParam::get_saved_value() { Variant BBParam::get_saved_value() {
if (saved_value.get_type() != get_type()) {
Callable::CallError err;
Variant::construct(get_type(), saved_value, nullptr, 0, err);
}
return saved_value; return saved_value;
} }
@ -50,7 +46,21 @@ void BBParam::set_variable(const String &p_value) {
String BBParam::to_string() { String BBParam::to_string() {
if (value_source == SAVED_VALUE) { if (value_source == SAVED_VALUE) {
return String(saved_value); String s = saved_value.stringify();
switch (get_type()) {
case Variant::STRING: {
s = s.c_escape().quote();
} break;
case Variant::STRING_NAME: {
s = "&" + s.c_escape().quote();
} break;
case Variant::NODE_PATH: {
s = "^" + s.c_escape().quote();
} break;
default: {
} break;
}
return s;
} else { } else {
return LimboUtility::get_singleton()->decorate_var(variable); return LimboUtility::get_singleton()->decorate_var(variable);
} }
@ -62,6 +72,7 @@ Variant BBParam::get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard,
if (value_source == SAVED_VALUE) { if (value_source == SAVED_VALUE) {
return saved_value; return saved_value;
} else { } else {
ERR_FAIL_COND_V_MSG(!p_blackboard->has_var(variable), Variant(), vformat("BBParam: Blackboard variable doesn't exist: \"%s\".", p_default));
return p_blackboard->get_var(variable, p_default); return p_blackboard->get_var(variable, p_default);
} }
} }
@ -84,7 +95,7 @@ void BBParam::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_type"), &BBParam::get_type); ClassDB::bind_method(D_METHOD("get_type"), &BBParam::get_type);
ClassDB::bind_method(D_METHOD("get_value", "p_agent", "p_blackboard", "p_default"), &BBParam::get_value, Variant()); ClassDB::bind_method(D_METHOD("get_value", "p_agent", "p_blackboard", "p_default"), &BBParam::get_value, Variant());
ADD_PROPERTY(PropertyInfo(Variant::INT, "value_source", PROPERTY_HINT_ENUM, "Saved Value, Blackboard Var"), "set_value_source", "get_value_source"); ADD_PROPERTY(PropertyInfo(Variant::INT, "value_source", PROPERTY_HINT_ENUM, "Saved Value,Blackboard Var"), "set_value_source", "get_value_source");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable", PROPERTY_HINT_NONE, "", 0), "set_variable", "get_variable"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable", PROPERTY_HINT_NONE, "", 0), "set_variable", "get_variable");
ADD_PROPERTY(PropertyInfo(Variant::NIL, "saved_value", PROPERTY_HINT_NONE, "", 0), "set_saved_value", "get_saved_value"); ADD_PROPERTY(PropertyInfo(Variant::NIL, "saved_value", PROPERTY_HINT_NONE, "", 0), "set_saved_value", "get_saved_value");
@ -95,5 +106,6 @@ void BBParam::_bind_methods() {
BBParam::BBParam() { BBParam::BBParam() {
value_source = SAVED_VALUE; value_source = SAVED_VALUE;
variable = ""; variable = "";
saved_value = Variant();
_assign_default_value();
} }

View File

@ -43,6 +43,11 @@ protected:
virtual Variant::Type get_type() const { return Variant::NIL; } virtual Variant::Type get_type() const { return Variant::NIL; }
_FORCE_INLINE_ void _assign_default_value() {
Callable::CallError err;
Variant::construct(get_type(), saved_value, nullptr, 0, err);
}
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
public: public:

View File

@ -14,9 +14,18 @@
#include "core/variant/variant.h" #include "core/variant/variant.h"
void BBVariant::set_type(Variant::Type p_type) { void BBVariant::set_type(Variant::Type p_type) {
type = p_type; if (type != p_type) {
notify_property_list_changed(); type = p_type;
emit_changed(); if (get_saved_value().get_type() != p_type) {
_assign_default_value();
}
emit_changed();
notify_property_list_changed();
}
}
Variant::Type BBVariant::get_type() const {
return type;
} }
void BBVariant::_bind_methods() { void BBVariant::_bind_methods() {
@ -33,5 +42,4 @@ void BBVariant::_bind_methods() {
} }
BBVariant::BBVariant() { BBVariant::BBVariant() {
type = Variant::NIL;
} }

View File

@ -20,12 +20,12 @@ class BBVariant : public BBParam {
GDCLASS(BBVariant, BBParam); GDCLASS(BBVariant, BBParam);
private: private:
Variant::Type type; Variant::Type type = Variant::NIL;
protected: protected:
static void _bind_methods(); static void _bind_methods();
virtual Variant::Type get_type() const override { return type; } virtual Variant::Type get_type() const override;
void set_type(Variant::Type p_type); void set_type(Variant::Type p_type);
public: public:

View File

@ -22,10 +22,13 @@ String BTConsolePrint::_generate_name() const {
tx = text.substr(0, 30) + "..."; tx = text.substr(0, 30) + "...";
} }
tx = tx.replace("\"", "\\\""); tx = tx.replace("\"", "\\\"");
tx = tx.replace("\r", "\\r");
tx = tx.replace("\t", "\\t");
tx = tx.replace("\n", "\\n");
if (bb_format_parameters.size() > 0) { if (bb_format_parameters.size() > 0) {
return vformat("ConsolePrint text: \"%s\" format_parameters: %s", tx, bb_format_parameters); return vformat("ConsolePrint text: \"%s\" params: %s", tx, bb_format_parameters);
} }
return vformat("ConsolePrint \"%s\"", tx); return vformat("ConsolePrint text: \"%s\"", tx);
} }
int BTConsolePrint::_tick(double p_delta) { int BTConsolePrint::_tick(double p_delta) {

View File

@ -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<BBVariant> 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");
}

View File

@ -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<BBVariant> 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<BBVariant> p_value);
Ref<BBVariant> get_value() const { return value; }
};
#endif // BT_SET_AGENT_PROPERTY

68
bt/actions/bt_set_var.cpp Normal file
View File

@ -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("Set %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<BBVariant> 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");
}

46
bt/actions/bt_set_var.h Normal file
View File

@ -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<BBVariant> 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<BBVariant> p_value);
Ref<BBVariant> get_value() const { return value; }
};
#endif // BT_SET_VAR

View File

@ -0,0 +1,84 @@
/**
* bt_check_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_check_agent_property.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/variant/callable.h"
void BTCheckAgentProperty::set_property_name(StringName p_prop) {
property_name = p_prop;
emit_changed();
}
void BTCheckAgentProperty::set_check_type(LimboUtility::CheckType p_check_type) {
check_type = p_check_type;
emit_changed();
}
void BTCheckAgentProperty::set_value(Ref<BBVariant> 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 BTCheckAgentProperty::get_configuration_warning() const {
String warning = BTCondition::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 BTCheckAgentProperty::_generate_name() const {
if (property_name == StringName()) {
return "CheckAgentProperty ???";
}
return vformat("Check if: agent.%s %s %s", property_name,
LimboUtility::get_singleton()->get_check_operator_string(check_type),
value.is_valid() ? Variant(value) : Variant("???"));
}
int BTCheckAgentProperty::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(property_name == StringName(), FAILURE, "BTCheckAgentProperty: `property_name` is not set.");
ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTCheckAgentProperty: `value` is not set.");
bool r_valid;
Variant left_value = get_agent()->get(property_name, &r_valid);
ERR_FAIL_COND_V_MSG(r_valid == false, FAILURE, vformat("BTCheckAgentProperty: Agent has no property named \"%s\"", property_name));
Variant right_value = value->get_value(get_agent(), get_blackboard());
return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE;
}
void BTCheckAgentProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_property_name", "p_property_name"), &BTCheckAgentProperty::set_property_name);
ClassDB::bind_method(D_METHOD("get_property_name"), &BTCheckAgentProperty::get_property_name);
ClassDB::bind_method(D_METHOD("set_check_type", "p_check_type"), &BTCheckAgentProperty::set_check_type);
ClassDB::bind_method(D_METHOD("get_check_type"), &BTCheckAgentProperty::get_check_type);
ClassDB::bind_method(D_METHOD("set_value", "p_value"), &BTCheckAgentProperty::set_value);
ClassDB::bind_method(D_METHOD("get_value"), &BTCheckAgentProperty::get_value);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "property_name"), "set_property_name", "get_property_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "check_type", PROPERTY_HINT_ENUM, "Equal,Less Than,Less Than Or Equal,Greater Than,Greater Than Or Equal,Not Equal"), "set_check_type", "get_check_type");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "value", PROPERTY_HINT_RESOURCE_TYPE, "BBVariant"), "set_value", "get_value");
}

View File

@ -0,0 +1,50 @@
/**
* bt_check_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_CHECK_AGENT_PROPERTY
#define BT_CHECK_AGENT_PROPERTY
#include "bt_condition.h"
#include "modules/limboai/blackboard/bb_param/bb_variant.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/object/object.h"
#include "core/string/string_name.h"
class BTCheckAgentProperty : public BTCondition {
GDCLASS(BTCheckAgentProperty, BTCondition);
private:
StringName property_name;
LimboUtility::CheckType check_type = LimboUtility::CheckType::CHECK_EQUAL;
Ref<BBVariant> 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_check_type(LimboUtility::CheckType p_check_type);
LimboUtility::CheckType get_check_type() const { return check_type; }
void set_value(Ref<BBVariant> p_value);
Ref<BBVariant> get_value() const { return value; }
};
#endif // BT_CHECK_AGENT_PROPERTY

View File

@ -0,0 +1,45 @@
/**
* bt_check_trigger.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_check_trigger.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/variant/variant.h"
void BTCheckTrigger::set_variable(String p_variable) {
variable = p_variable;
emit_changed();
}
String BTCheckTrigger::_generate_name() const {
if (variable.is_empty()) {
return "CheckTrigger ???";
}
return "CheckTrigger " + LimboUtility::get_singleton()->decorate_var(variable);
}
int BTCheckTrigger::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(variable.is_empty(), FAILURE, "BBCheckVar: `variable` is not set.");
Variant trigger_value = get_blackboard()->get_var(variable, false);
if (trigger_value == Variant(true)) {
get_blackboard()->set_var(variable, false);
return SUCCESS;
}
return FAILURE;
}
void BTCheckTrigger::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_variable", "p_variable"), &BTCheckTrigger::set_variable);
ClassDB::bind_method(D_METHOD("get_variable"), &BTCheckTrigger::get_variable);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable"), "set_variable", "get_variable");
}

View File

@ -0,0 +1,41 @@
/**
* bt_check_trigger.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_check_trigger.h */
#ifndef BT_CHECK_TRIGGER_H
#define BT_CHECK_TRIGGER_H
#include "bt_condition.h"
#include "core/object/object.h"
#include "core/string/ustring.h"
#include "core/object/class_db.h"
class BTCheckTrigger : public BTCondition {
GDCLASS(BTCheckTrigger, BTCondition);
private:
String variable;
protected:
static void _bind_methods();
virtual String _generate_name() const override;
virtual int _tick(double p_delta) override;
public:
void set_variable(String p_variable);
String get_variable() const { return variable; }
};
#endif // BT_CHECK_TRIGGER

View File

@ -0,0 +1,83 @@
/**
* bt_check_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_check_var.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/variant/callable.h"
void BTCheckVar::set_variable(String p_variable) {
variable = p_variable;
emit_changed();
}
void BTCheckVar::set_check_type(LimboUtility::CheckType p_check_type) {
check_type = p_check_type;
emit_changed();
}
void BTCheckVar::set_value(Ref<BBVariant> 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 BTCheckVar::get_configuration_warning() const {
String warning = BTCondition::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;
}
String BTCheckVar::_generate_name() const {
if (variable.is_empty()) {
return "CheckVar ???";
}
return vformat("Check if: %s %s %s", LimboUtility::get_singleton()->decorate_var(variable),
LimboUtility::get_singleton()->get_check_operator_string(check_type),
value.is_valid() ? Variant(value) : Variant("???"));
}
int BTCheckVar::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(variable.is_empty(), FAILURE, "BTCheckVar: `variable` is not set.");
ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTCheckVar: `value` is not set.");
ERR_FAIL_COND_V_MSG(!get_blackboard()->has_var(variable), FAILURE, vformat("BTCheckVar: Blackboard variable doesn't exist: \"%s\". Returning FAILURE.", variable));
Variant left_value = get_blackboard()->get_var(variable, Variant());
Variant right_value = value->get_value(get_agent(), get_blackboard());
return LimboUtility::get_singleton()->perform_check(check_type, left_value, right_value) ? SUCCESS : FAILURE;
}
void BTCheckVar::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_variable", "p_variable"), &BTCheckVar::set_variable);
ClassDB::bind_method(D_METHOD("get_variable"), &BTCheckVar::get_variable);
ClassDB::bind_method(D_METHOD("set_check_type", "p_check_type"), &BTCheckVar::set_check_type);
ClassDB::bind_method(D_METHOD("get_check_type"), &BTCheckVar::get_check_type);
ClassDB::bind_method(D_METHOD("set_value", "p_value"), &BTCheckVar::set_value);
ClassDB::bind_method(D_METHOD("get_value"), &BTCheckVar::get_value);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable"), "set_variable", "get_variable");
ADD_PROPERTY(PropertyInfo(Variant::INT, "check_type", PROPERTY_HINT_ENUM, "Equal,Less Than,Less Than Or Equal,Greater Than,Greater Than Or Equal,Not Equal"), "set_check_type", "get_check_type");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "value", PROPERTY_HINT_RESOURCE_TYPE, "BBVariant"), "set_value", "get_value");
}

View File

@ -0,0 +1,50 @@
/**
* bt_check_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.
* =============================================================================
*/
#ifndef BT_CHECK_VAR_H
#define BT_CHECK_VAR_H
#include "bt_condition.h"
#include "modules/limboai/blackboard/bb_param/bb_variant.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/object/class_db.h"
#include "core/object/object.h"
class BTCheckVar : public BTCondition {
GDCLASS(BTCheckVar, BTCondition);
private:
String variable;
LimboUtility::CheckType check_type = LimboUtility::CheckType::CHECK_EQUAL;
Ref<BBVariant> 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(String p_variable);
String get_variable() const { return variable; }
void set_check_type(LimboUtility::CheckType p_check_type);
LimboUtility::CheckType get_check_type() const { return check_type; }
void set_value(Ref<BBVariant> p_value);
Ref<BBVariant> get_value() const { return value; }
};
#endif // BT_CHECK_VAR_H

View File

@ -60,6 +60,9 @@ def get_doc_classes():
"BTAction", "BTAction",
"BTAlwaysFail", "BTAlwaysFail",
"BTAlwaysSucceed", "BTAlwaysSucceed",
"BTCheckAgentProperty",
"BTCheckTrigger",
"BTCheckVar",
"BTComposite", "BTComposite",
"BTCondition", "BTCondition",
"BTConsolePrint", "BTConsolePrint",
@ -84,6 +87,8 @@ def get_doc_classes():
"BTRunLimit", "BTRunLimit",
"BTSelector", "BTSelector",
"BTSequence", "BTSequence",
"BTSetAgentProperty",
"BTSetVar",
"BTState", "BTState",
"BTSubtree", "BTSubtree",
"BTTask", "BTTask",

View File

@ -0,0 +1,53 @@
[gd_resource type="BehaviorTree" load_steps=13 format=3 uid="uid://cvm3gqes75f53"]
[sub_resource type="BBVariant" id="BBVariant_t70f2"]
resource_name = "false"
saved_value = false
type = 1
[sub_resource type="BTSetVar" id="BTSetVar_nxwdg"]
variable = "triggered"
value = SubResource("BBVariant_t70f2")
[sub_resource type="BTRunLimit" id="BTRunLimit_mlytb"]
children = [SubResource("BTSetVar_nxwdg")]
[sub_resource type="BBVariant" id="BBVariant_8bpg1"]
resource_name = "false"
saved_value = false
type = 1
[sub_resource type="BTCheckVar" id="BTCheckVar_g5b0s"]
variable = "triggered"
value = SubResource("BBVariant_8bpg1")
[sub_resource type="BBVariant" id="BBVariant_loenl"]
resource_name = "true"
saved_value = true
type = 1
[sub_resource type="BTSetVar" id="BTSetVar_u051c"]
variable = "triggered"
value = SubResource("BBVariant_loenl")
[sub_resource type="BBVariant" id="BBVariant_cu1uc"]
resource_name = "Hello, World!"
saved_value = "Hello, World!"
type = 4
[sub_resource type="BTSetVar" id="BTSetVar_2e0uw"]
variable = "message"
value = SubResource("BBVariant_cu1uc")
[sub_resource type="BTConsolePrint" id="BTConsolePrint_533ui"]
text = "Message is: %s"
bb_format_parameters = PackedStringArray("message")
[sub_resource type="BTSequence" id="BTSequence_bhar3"]
children = [SubResource("BTCheckVar_g5b0s"), SubResource("BTSetVar_u051c"), SubResource("BTSetVar_2e0uw"), SubResource("BTConsolePrint_533ui")]
[sub_resource type="BTSelector" id="BTSelector_ndrjh"]
children = [SubResource("BTRunLimit_mlytb"), SubResource("BTSequence_bhar3")]
[resource]
root_task = SubResource("BTSelector_ndrjh")

View File

@ -0,0 +1,8 @@
[gd_scene load_steps=2 format=3 uid="uid://d4bjeyescflm8"]
[ext_resource type="BehaviorTree" uid="uid://cvm3gqes75f53" path="res://ai/trees/variables.tres" id="1_tq7fc"]
[node name="Variables Example" type="Node2D"]
[node name="BTPlayer" type="BTPlayer" parent="."]
behavior_tree = ExtResource("1_tq7fc")

View File

@ -0,0 +1,3 @@
extends Node2D
@export var speed: float = 200.0

View File

@ -0,0 +1,10 @@
[gd_scene load_steps=3 format=3 uid="uid://c3d3ed6545cly"]
[ext_resource type="Script" path="res://tests/agent_properties/agent_properties.gd" id="1_jh88u"]
[ext_resource type="BehaviorTree" uid="uid://ddhxf0haxgw" path="res://tests/agent_properties/bt_agent_properties.tres" id="2_txe8k"]
[node name="AgentProperties" type="Node2D"]
script = ExtResource("1_jh88u")
[node name="BTPlayer" type="BTPlayer" parent="."]
behavior_tree = ExtResource("2_txe8k")

View File

@ -0,0 +1,109 @@
[gd_resource type="BehaviorTree" load_steps=29 format=3 uid="uid://ddhxf0haxgw"]
[sub_resource type="BBVariant" id="BBVariant_5o8fh"]
resource_name = "200"
saved_value = 200.0
type = 3
[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_0nprx"]
property_name = &"speed"
value = SubResource("BBVariant_5o8fh")
[sub_resource type="BTConsolePrint" id="BTConsolePrint_dlmwi"]
text = "Test 1: Passed"
[sub_resource type="BTSequence" id="BTSequence_fou4d"]
children = [SubResource("BTCheckAgentProperty_0nprx"), SubResource("BTConsolePrint_dlmwi")]
[sub_resource type="BTConsolePrint" id="BTConsolePrint_ggvml"]
text = "Test 1: Failed"
[sub_resource type="BTSelector" id="BTSelector_hw3on"]
custom_name = "Test 1"
children = [SubResource("BTSequence_fou4d"), SubResource("BTConsolePrint_ggvml")]
[sub_resource type="BBVariant" id="BBVariant_r2elk"]
resource_name = "300"
saved_value = 300.0
type = 3
[sub_resource type="BTSetAgentProperty" id="BTSetAgentProperty_lh1xy"]
property_name = &"speed"
value = SubResource("BBVariant_r2elk")
[sub_resource type="BBVariant" id="BBVariant_jhcxn"]
resource_name = "200"
saved_value = 200.0
type = 3
[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_p20lt"]
property_name = &"speed"
check_type = 3
value = SubResource("BBVariant_jhcxn")
[sub_resource type="BTConsolePrint" id="BTConsolePrint_nb21y"]
text = "Test 2: Passed"
[sub_resource type="BTSequence" id="BTSequence_rp57i"]
children = [SubResource("BTCheckAgentProperty_p20lt"), SubResource("BTConsolePrint_nb21y")]
[sub_resource type="BTConsolePrint" id="BTConsolePrint_o5xxa"]
text = "Test 2: Failed"
[sub_resource type="BTSelector" id="BTSelector_cr664"]
custom_name = "Test 2"
children = [SubResource("BTSequence_rp57i"), SubResource("BTConsolePrint_o5xxa")]
[sub_resource type="BBVariant" id="BBVariant_2aotu"]
resource_name = "400"
saved_value = 400.0
type = 3
[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_avnfr"]
property_name = &"speed"
check_type = 1
value = SubResource("BBVariant_2aotu")
[sub_resource type="BTConsolePrint" id="BTConsolePrint_wgw5j"]
text = "Test 3: Passed"
[sub_resource type="BTSequence" id="BTSequence_ykp38"]
children = [SubResource("BTCheckAgentProperty_avnfr"), SubResource("BTConsolePrint_wgw5j")]
[sub_resource type="BTConsolePrint" id="BTConsolePrint_0eshq"]
text = "Test 3: Failed"
[sub_resource type="BTSelector" id="BTSelector_nxupw"]
custom_name = "Test 3"
children = [SubResource("BTSequence_ykp38"), SubResource("BTConsolePrint_0eshq")]
[sub_resource type="BBVariant" id="BBVariant_28e2y"]
resource_name = "300"
saved_value = 300.0
type = 3
[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_sayma"]
property_name = &"speed"
value = SubResource("BBVariant_28e2y")
[sub_resource type="BTConsolePrint" id="BTConsolePrint_xugph"]
text = "Test 4: Passed"
[sub_resource type="BTSequence" id="BTSequence_3wj0i"]
children = [SubResource("BTCheckAgentProperty_sayma"), SubResource("BTConsolePrint_xugph")]
[sub_resource type="BTConsolePrint" id="BTConsolePrint_16vkj"]
text = "Test 4: Failed"
[sub_resource type="BTSelector" id="BTSelector_qhmh3"]
custom_name = "Test 4"
children = [SubResource("BTSequence_3wj0i"), SubResource("BTConsolePrint_16vkj")]
[sub_resource type="BTSequence" id="BTSequence_7bmj1"]
children = [SubResource("BTSelector_hw3on"), SubResource("BTSetAgentProperty_lh1xy"), SubResource("BTSelector_cr664"), SubResource("BTSelector_nxupw"), SubResource("BTSelector_qhmh3")]
[sub_resource type="BTRunLimit" id="BTRunLimit_034mk"]
children = [SubResource("BTSequence_7bmj1")]
[resource]
root_task = SubResource("BTRunLimit_034mk")

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="AABB(0, 0, 0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="[]" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="false" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedByteArray()" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Color(0, 0, 0, 1)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedColorArray()" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="{}" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="0.0" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedFloat64Array()" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedInt64Array()" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="NodePath(&quot;&quot;)" />
</members>
</class> </class>

View File

@ -28,7 +28,7 @@
</method> </method>
</methods> </methods>
<members> <members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" default="0"> <member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" default="null">
A value that is saved with BBParam resource. The type of value is defined by [method get_type]. Provides the parameter's value, if [member value_source] is [constant SAVED_VALUE]. A value that is saved with BBParam resource. The type of value is defined by [method get_type]. Provides the parameter's value, if [member value_source] is [constant SAVED_VALUE].
</member> </member>
<member name="value_source" type="int" setter="set_value_source" getter="get_value_source" enum="BBParam.ValueSource" default="0"> <member name="value_source" type="int" setter="set_value_source" getter="get_value_source" enum="BBParam.ValueSource" default="0">

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Plane(0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Quaternion(0, 0, 0, 1)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Rect2(0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Rect2i(0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="&quot;&quot;" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedStringArray()" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="&amp;&quot;&quot;" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Transform2D(1, 0, 0, 1, 0, 0)" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -8,7 +8,6 @@
<tutorials> <tutorials>
</tutorials> </tutorials>
<members> <members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="null" />
<member name="type" type="int" setter="set_type" getter="get_type" enum="Variant.Type" default="0"> <member name="type" type="int" setter="set_type" getter="get_type" enum="Variant.Type" default="0">
</member> </member>
</members> </members>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector2(0, 0)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedVector2Array()" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector2i(0, 0)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector3(0, 0, 0)" />
</members>
</class> </class>

View File

@ -7,7 +7,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="PackedVector3Array()" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector3i(0, 0, 0)" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector4(0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -6,7 +6,4 @@
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<members>
<member name="saved_value" type="Variant" setter="set_saved_value" getter="get_saved_value" overrides="BBParam" default="Vector4i(0, 0, 0, 0)" />
</members>
</class> </class>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BTCheckAgentProperty" inherits="BTCondition" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
BT condition that checks agent's property value.
</brief_description>
<description>
BTCheckAgentProperty checks agent's property value against [member value] and returns [code]SUCCESS[/code] or [code]FAILURE[/code] based on the [member check_type].
</description>
<tutorials>
</tutorials>
<members>
<member name="check_type" type="int" setter="set_check_type" getter="get_check_type" enum="LimboUtility.CheckType" default="0">
Type of check to perform.
</member>
<member name="property_name" type="StringName" setter="set_property_name" getter="get_property_name" default="&amp;&quot;&quot;">
Parameter that specifies the agent's property name which will be compared.
</member>
<member name="value" type="BBVariant" setter="set_value" getter="get_value">
Parameter that specifies the value to which an agent's property will be compared.
</member>
</members>
</class>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BTCheckTrigger" inherits="BTCondition" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
BT condition that checks a trigger (a boolean variable).
</brief_description>
<description>
BTCheckTrigger verifies whether the [member variable] is set to [code]true[/code]. If it is, the task changes it to [code]false[/code] and returns [code]SUCCESS[/code]. Otherwise, it returns [code]FAILURE[/code].
</description>
<tutorials>
</tutorials>
<members>
<member name="variable" type="String" setter="set_variable" getter="get_variable" default="&quot;&quot;">
A boolean variable on the blackboard that is used as a trigger.
When it is set to [code]true[/code], BTCheckTrigger will flip it to [code]false[/code] and return [code]SUCCESS[/code]. Otherwise, it will return [code]FAILURE[/code].
</member>
</members>
</class>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BTCheckVar" inherits="BTCondition" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
BT condition that checks a variable on the blackboard.
</brief_description>
<description>
BTCheckVar checks [member variable] against [member value] and returns [code]SUCCESS[/code] or [code]FAILURE[/code] based on the [member check_type].
</description>
<tutorials>
</tutorials>
<members>
<member name="check_type" type="int" setter="set_check_type" getter="get_check_type" enum="LimboUtility.CheckType" default="0">
Type of check to perform.
</member>
<member name="value" type="BBVariant" setter="set_value" getter="get_value">
Parameter that specifies the value to which the [member variable] will be compared.
</member>
<member name="variable" type="String" setter="set_variable" getter="get_variable" default="&quot;&quot;">
Variable name to check its value.
</member>
</members>
</class>

View File

@ -16,7 +16,7 @@
If [code]false[/code], [code]FAILURE[/code] status returned by the child is also considered a successfully finished execution. If [code]false[/code], [code]FAILURE[/code] status returned by the child is also considered a successfully finished execution.
</member> </member>
<member name="forever" type="bool" setter="set_forever" getter="get_forever" default="false"> <member name="forever" type="bool" setter="set_forever" getter="get_forever" default="false">
If [code]true[/code], the child's execution will be repeated indefinitely, always returning [code]RUNNING[/code]. If [code]true[/code], the child's execution will be repeated indefinitely, always returning [code]RUNNING[/code].
</member> </member>
<member name="times" type="int" setter="set_times" getter="get_times" default="1"> <member name="times" type="int" setter="set_times" getter="get_times" default="1">
A number of times to repeat an execution of the child task. A number of times to repeat an execution of the child task.

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BTSetAgentProperty" inherits="BTAction" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
BT action that assigns a value to agent's property.
</brief_description>
<description>
BTSetAgentProperty assigns the specified [member value] to the agent's property identified by the [member property_name] and returns [code]SUCCESS[/code].
Returns [code]FAILURE[/code] if it fails to set the property.
</description>
<tutorials>
</tutorials>
<members>
<member name="property_name" type="StringName" setter="set_property_name" getter="get_property_name" default="&amp;&quot;&quot;">
Parameter that specifies the agent's property name.
</member>
<member name="value" type="BBVariant" setter="set_value" getter="get_value">
Parameter that specifies the value that will be assigned to agent's property.
</member>
</members>
</class>

18
doc_classes/BTSetVar.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BTSetVar" inherits="BTAction" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
BT action that assigns [member value] to the [member variable] and then returns [code]SUCCESS[/code].
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<members>
<member name="value" type="BBVariant" setter="set_value" getter="get_value">
Parameter that specifies the value to be assigned to the variable.
</member>
<member name="variable" type="String" setter="set_variable" getter="get_variable" default="&quot;&quot;">
Variable name whose value is to be assigned.
</member>
</members>
</class>

View File

@ -30,4 +30,18 @@
</description> </description>
</method> </method>
</methods> </methods>
<constants>
<constant name="CHECK_EQUAL" value="0" enum="CheckType">
</constant>
<constant name="CHECK_LESS_THAN" value="1" enum="CheckType">
</constant>
<constant name="CHECK_LESS_THAN_OR_EQUAL" value="2" enum="CheckType">
</constant>
<constant name="CHECK_GREATER_THAN" value="3" enum="CheckType">
</constant>
<constant name="CHECK_GREATER_THAN_OR_EQUAL" value="4" enum="CheckType">
</constant>
<constant name="CHECK_NOT_EQUAL" value="5" enum="CheckType">
</constant>
</constants>
</class> </class>

View File

@ -0,0 +1 @@
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m5.7 11.5c-.83 0-1.5.67-1.5 1.49 0 .83.67 1.51 1.5 1.51.85 0 1.52-.66 1.52-1.51.01-.82-.68-1.49-1.52-1.49z"/><path d="m11.09 4.83c0-2.51-2.16-4.33-5.13-4.33-2.69 0-4.62 1.48-4.92 3.77l-.04.32h2.58l.05-.24c.2-1.03 1.17-1.72 2.41-1.72 1.47 0 2.49.91 2.49 2.21 0 1.23-1.77 2.59-3.38 2.59h-2.02l1.54 3.08h2.05l.08-1.45.01-.2.19-.03c2.52-.33 4.09-1.86 4.09-4z"/><path d="m12.62 14.17h-1.76l-.73 1.33h-1.51l3.25-5.61h1.58l.62 5.61h-1.43zm-.01-.99-.09-2.14-1.12 2.14z"/></g></svg>

After

Width:  |  Height:  |  Size: 594 B

1
icons/BTCheckTrigger.svg Normal file
View File

@ -0,0 +1 @@
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m5.7 11.5c-.83 0-1.5.67-1.5 1.49 0 .83.67 1.51 1.5 1.51.85 0 1.52-.66 1.52-1.51.01-.82-.68-1.49-1.52-1.49z"/><path d="m11.09 4.83c0-2.51-2.16-4.33-5.13-4.33-2.69 0-4.62 1.48-4.92 3.77l-.04.32h2.58l.05-.24c.2-1.03 1.17-1.72 2.41-1.72 1.47 0 2.49.91 2.49 2.21 0 1.23-1.77 2.59-3.38 2.59h-2.02l1.54 3.08h2.05l.08-1.45.01-.2.19-.03c2.52-.33 4.09-1.86 4.09-4z"/><path d="m10.35 15.5h1.61l.89-4.23h1.86l.29-1.36h-5.32l-.29 1.36h1.85z"/></g></svg>

After

Width:  |  Height:  |  Size: 561 B

1
icons/BTCheckVar.svg Normal file
View File

@ -0,0 +1 @@
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m14.1 15.5h-1.46l-.96-1.87-1.54 1.87h-1.52l2.36-2.83-1.46-2.78h1.51l.94 1.79 1.49-1.79h1.54l-2.37 2.79z"/><path d="m5.7 11.5c-.83 0-1.5.67-1.5 1.49 0 .83.67 1.51 1.5 1.51.85 0 1.52-.66 1.52-1.51.01-.82-.68-1.49-1.52-1.49z"/><path d="m11.09 4.83c0-2.51-2.16-4.33-5.13-4.33-2.69 0-4.62 1.48-4.92 3.77l-.04.32h2.58l.05-.24c.2-1.03 1.17-1.72 2.41-1.72 1.47 0 2.49.91 2.49 2.21 0 1.23-1.77 2.59-3.38 2.59h-2.02l1.54 3.08h2.05l.08-1.45.01-.2.19-.03c2.52-.33 4.09-1.86 4.09-4z"/></g></svg>

After

Width:  |  Height:  |  Size: 603 B

View File

@ -0,0 +1 @@
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m12.93 1.5h-1.95l-6.91 13h2.21l1.99-3.9h3.78l.46 3.9h1.98zm-1.08 7.23h-2.6c1.09-2.12 1.77-3.46 1.97-3.9.06-.13.13-.27.19-.4.04.54.1 1.19.19 1.94z"/><path d="m6.39 6.5h-1.3l-.86-1.67-1.38 1.67h-1.35l2.11-2.52-1.31-2.48h1.34l.84 1.59 1.33-1.59h1.38l-2.11 2.49z"/></g></svg>

After

Width:  |  Height:  |  Size: 392 B

1
icons/BTSetVar.svg Normal file
View File

@ -0,0 +1 @@
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m2.91 14.57c-1.37-2.28-1.91-4.36-1.91-6.5s.54-4.23 1.91-6.5l1.09 1.06c-1.26 2.36-1.51 3.87-1.51 5.44s.25 3.08 1.51 5.44z"/><path d="m13.09 1.57c1.37 2.27 1.91 4.35 1.91 6.5 0 2.14-.54 4.23-1.91 6.5l-1.09-1.06c1.26-2.37 1.51-3.87 1.51-5.44s-.25-3.08-1.51-5.44z"/><path d="m10.87 11.5h-1.83l-1.21-2.33-1.93 2.33h-1.9l2.96-3.53-1.84-3.47h1.89l1.18 2.23 1.86-2.23h1.95l-2.98 3.49z"/></g></svg>

After

Width:  |  Height:  |  Size: 510 B

View File

@ -48,6 +48,8 @@
#include "bt/actions/bt_console_print.h" #include "bt/actions/bt_console_print.h"
#include "bt/actions/bt_fail.h" #include "bt/actions/bt_fail.h"
#include "bt/actions/bt_random_wait.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.h"
#include "bt/actions/bt_wait_ticks.h" #include "bt/actions/bt_wait_ticks.h"
#include "bt/behavior_tree.h" #include "bt/behavior_tree.h"
@ -62,6 +64,9 @@
#include "bt/composites/bt_random_sequence.h" #include "bt/composites/bt_random_sequence.h"
#include "bt/composites/bt_selector.h" #include "bt/composites/bt_selector.h"
#include "bt/composites/bt_sequence.h" #include "bt/composites/bt_sequence.h"
#include "bt/conditions/bt_check_agent_property.h"
#include "bt/conditions/bt_check_trigger.h"
#include "bt/conditions/bt_check_var.h"
#include "bt/conditions/bt_condition.h" #include "bt/conditions/bt_condition.h"
#include "bt/decorators/bt_always_fail.h" #include "bt/decorators/bt_always_fail.h"
#include "bt/decorators/bt_always_succeed.h" #include "bt/decorators/bt_always_succeed.h"
@ -99,6 +104,7 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
LimboDebugger::initialize(); LimboDebugger::initialize();
GDREGISTER_CLASS(LimboUtility);
GDREGISTER_CLASS(Blackboard); GDREGISTER_CLASS(Blackboard);
GDREGISTER_CLASS(LimboState); GDREGISTER_CLASS(LimboState);
@ -133,15 +139,20 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(BTForEach); GDREGISTER_CLASS(BTForEach);
GDREGISTER_CLASS(BTAction); 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(BTConsolePrint);
GDREGISTER_CLASS(BTFail);
GDREGISTER_CLASS(BTNewScope);
GDREGISTER_CLASS(BTRandomWait);
GDREGISTER_CLASS(BTSetAgentProperty);
GDREGISTER_CLASS(BTSetVar);
GDREGISTER_CLASS(BTSubtree);
GDREGISTER_CLASS(BTWait);
GDREGISTER_CLASS(BTWaitTicks);
GDREGISTER_CLASS(BTCondition); GDREGISTER_CLASS(BTCondition);
GDREGISTER_CLASS(BTCheckAgentProperty);
GDREGISTER_CLASS(BTCheckTrigger);
GDREGISTER_CLASS(BTCheckVar);
GDREGISTER_ABSTRACT_CLASS(BBParam); GDREGISTER_ABSTRACT_CLASS(BBParam);
GDREGISTER_CLASS(BBInt); GDREGISTER_CLASS(BBInt);
@ -178,7 +189,6 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(BBVariant); GDREGISTER_CLASS(BBVariant);
_limbo_utility = memnew(LimboUtility); _limbo_utility = memnew(LimboUtility);
GDREGISTER_CLASS(LimboUtility);
Engine::get_singleton()->add_singleton(Engine::Singleton("LimboUtility", LimboUtility::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("LimboUtility", LimboUtility::get_singleton()));
LimboStringNames::create(); LimboStringNames::create();

View File

@ -58,17 +58,91 @@ Ref<Texture2D> LimboUtility::get_task_icon(String p_class_or_script_path) const
Ref<Script> s = ResourceLoader::load(p_class_or_script_path, "Script"); Ref<Script> s = ResourceLoader::load(p_class_or_script_path, "Script");
return EditorNode::get_singleton()->get_object_icon(s.ptr(), "BTTask"); return EditorNode::get_singleton()->get_object_icon(s.ptr(), "BTTask");
} }
// TODO: Walk inheritance tree until icon is found.
return EditorNode::get_singleton()->get_class_icon(p_class_or_script_path, "BTTask"); Control *gui_base = EditorNode::get_singleton()->get_gui_base();
if (gui_base->has_theme_icon(p_class_or_script_path, SNAME("EditorIcons"))) {
return gui_base->get_theme_icon(p_class_or_script_path, SNAME("EditorIcons"));
}
// Use an icon of one of the base classes: look up max 3 parents.
StringName class_name = p_class_or_script_path;
for (int i = 0; i < 3; i++) {
class_name = ClassDB::get_parent_class(class_name);
if (gui_base->has_theme_icon(class_name, SNAME("EditorIcons"))) {
return gui_base->get_theme_icon(class_name, SNAME("EditorIcons"));
}
}
// Return generic resource icon as a fallback.
return gui_base->get_theme_icon(SNAME("Resource"), SNAME("EditorIcons"));
#endif // TOOLS_ENABLED #endif // TOOLS_ENABLED
// Note: class icons are not available at runtime as they are part of the editor theme.
// * Class icons are not available at runtime as they are part of the editor theme.
return nullptr; return nullptr;
} }
String LimboUtility::get_check_operator_string(CheckType p_check_type) {
switch (p_check_type) {
case LimboUtility::CheckType::CHECK_EQUAL: {
return "==";
} break;
case LimboUtility::CheckType::CHECK_LESS_THAN: {
return "<";
} break;
case LimboUtility::CheckType::CHECK_LESS_THAN_OR_EQUAL: {
return "<=";
} break;
case LimboUtility::CheckType::CHECK_GREATER_THAN: {
return ">";
} break;
case LimboUtility::CheckType::CHECK_GREATER_THAN_OR_EQUAL: {
return ">=";
} break;
case LimboUtility::CheckType::CHECK_NOT_EQUAL: {
return "!=";
} break;
default: {
return "?";
} break;
}
}
bool LimboUtility::perform_check(CheckType p_check_type, const Variant &left_value, const Variant &right_value) {
switch (p_check_type) {
case LimboUtility::CheckType::CHECK_EQUAL: {
return Variant::evaluate(Variant::OP_EQUAL, left_value, right_value);
} break;
case LimboUtility::CheckType::CHECK_LESS_THAN: {
return Variant::evaluate(Variant::OP_LESS, left_value, right_value);
} break;
case LimboUtility::CheckType::CHECK_LESS_THAN_OR_EQUAL: {
return Variant::evaluate(Variant::OP_LESS_EQUAL, left_value, right_value);
} break;
case LimboUtility::CheckType::CHECK_GREATER_THAN: {
return Variant::evaluate(Variant::OP_GREATER, left_value, right_value);
} break;
case LimboUtility::CheckType::CHECK_GREATER_THAN_OR_EQUAL: {
return Variant::evaluate(Variant::OP_GREATER_EQUAL, left_value, right_value);
} break;
case LimboUtility::CheckType::CHECK_NOT_EQUAL: {
return Variant::evaluate(Variant::OP_NOT_EQUAL, left_value, right_value);
} break;
default: {
return false;
} break;
}
}
void LimboUtility::_bind_methods() { void LimboUtility::_bind_methods() {
ClassDB::bind_method(D_METHOD("decorate_var", "p_variable"), &LimboUtility::decorate_var); ClassDB::bind_method(D_METHOD("decorate_var", "p_variable"), &LimboUtility::decorate_var);
ClassDB::bind_method(D_METHOD("get_status_name", "p_status"), &LimboUtility::get_status_name); ClassDB::bind_method(D_METHOD("get_status_name", "p_status"), &LimboUtility::get_status_name);
ClassDB::bind_method(D_METHOD("get_task_icon", "p_class_or_script_path"), &LimboUtility::get_task_icon); ClassDB::bind_method(D_METHOD("get_task_icon", "p_class_or_script_path"), &LimboUtility::get_task_icon);
BIND_ENUM_CONSTANT(CHECK_EQUAL);
BIND_ENUM_CONSTANT(CHECK_LESS_THAN);
BIND_ENUM_CONSTANT(CHECK_LESS_THAN_OR_EQUAL);
BIND_ENUM_CONSTANT(CHECK_GREATER_THAN);
BIND_ENUM_CONSTANT(CHECK_GREATER_THAN_OR_EQUAL);
BIND_ENUM_CONSTANT(CHECK_NOT_EQUAL);
} }
LimboUtility::LimboUtility() { LimboUtility::LimboUtility() {

View File

@ -14,11 +14,22 @@
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/object/object.h" #include "core/object/object.h"
#include "core/variant/variant.h"
#include "scene/resources/texture.h" #include "scene/resources/texture.h"
class LimboUtility : public Object { class LimboUtility : public Object {
GDCLASS(LimboUtility, Object); GDCLASS(LimboUtility, Object);
public:
enum CheckType : unsigned int {
CHECK_EQUAL,
CHECK_LESS_THAN,
CHECK_LESS_THAN_OR_EQUAL,
CHECK_GREATER_THAN,
CHECK_GREATER_THAN_OR_EQUAL,
CHECK_NOT_EQUAL
};
protected: protected:
static LimboUtility *singleton; static LimboUtility *singleton;
static void _bind_methods(); static void _bind_methods();
@ -30,8 +41,13 @@ public:
String get_status_name(int p_status) const; String get_status_name(int p_status) const;
Ref<Texture2D> get_task_icon(String p_class_or_script_path) const; Ref<Texture2D> get_task_icon(String p_class_or_script_path) const;
String get_check_operator_string(CheckType p_check_type);
bool perform_check(CheckType p_check_type, const Variant &left_value, const Variant &right_value);
LimboUtility(); LimboUtility();
~LimboUtility(); ~LimboUtility();
}; };
VARIANT_ENUM_CAST(LimboUtility::CheckType);
#endif // LIMBO_UTILITY_H #endif // LIMBO_UTILITY_H