BTSetVar: Specify operation to be performed with assignment

This commit is contained in:
Serhii Snitsaruk 2023-11-15 14:45:10 +01:00
parent b57528e4dc
commit 1ac24e67bb
4 changed files with 143 additions and 5 deletions

View File

@ -20,16 +20,26 @@ String BTSetVar::_generate_name() const {
if (variable.is_empty()) { if (variable.is_empty()) {
return "SetVar ???"; return "SetVar ???";
} }
return vformat("Set %s = %s", LimboUtility::get_singleton()->decorate_var(variable), return vformat("Set %s %s= %s",
LimboUtility::get_singleton()->decorate_var(variable),
LimboUtility::get_singleton()->get_operation_string(operation),
value.is_valid() ? Variant(value) : Variant("???")); value.is_valid() ? Variant(value) : Variant("???"));
} }
BT::Status BTSetVar::_tick(double p_delta) { BT::Status BTSetVar::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(variable.is_empty(), FAILURE, "BTSetVar: `variable` is not set."); ERR_FAIL_COND_V_MSG(variable.is_empty(), FAILURE, "BTSetVar: `variable` is not set.");
ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTSetVar: `value` is not set."); ERR_FAIL_COND_V_MSG(!value.is_valid(), FAILURE, "BTSetVar: `value` is not set.");
Variant result;
Variant error_result = SNAME("Error: BTSetVar failed to get value!"); Variant error_result = SNAME("Error: BTSetVar failed to get value!");
Variant result = value->get_value(get_agent(), get_blackboard(), error_result); Variant right_value = value->get_value(get_agent(), get_blackboard(), error_result);
ERR_FAIL_COND_V_MSG(result == error_result, FAILURE, "BTSetVar: Failed to get parameter value. Returning FAILURE."); ERR_FAIL_COND_V_MSG(right_value == error_result, FAILURE, "BTSetVar: Failed to get parameter value. Returning FAILURE.");
if (operation == LimboUtility::OP_NONE) {
result = right_value;
} else if (operation != LimboUtility::OP_NONE) {
Variant left_value = get_blackboard()->get_var(variable, error_result);
ERR_FAIL_COND_V_MSG(left_value == error_result, FAILURE, vformat("BTSetVar: Failed to get \"%s\" blackboard variable. Returning FAILURE.", variable));
result = LimboUtility::get_singleton()->perform_operation(operation, left_value, right_value);
}
get_blackboard()->set_var(variable, result); get_blackboard()->set_var(variable, result);
return SUCCESS; return SUCCESS;
}; };
@ -47,6 +57,11 @@ void BTSetVar::set_value(Ref<BBVariant> p_value) {
} }
} }
void BTSetVar::set_operation(LimboUtility::Operation p_operation) {
operation = p_operation;
emit_changed();
}
PackedStringArray BTSetVar::get_configuration_warnings() const { PackedStringArray BTSetVar::get_configuration_warnings() const {
PackedStringArray warnings = BTAction::get_configuration_warnings(); PackedStringArray warnings = BTAction::get_configuration_warnings();
if (variable.is_empty()) { if (variable.is_empty()) {
@ -63,7 +78,10 @@ void BTSetVar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_variable"), &BTSetVar::get_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("set_value", "p_value"), &BTSetVar::set_value);
ClassDB::bind_method(D_METHOD("get_value"), &BTSetVar::get_value); ClassDB::bind_method(D_METHOD("get_value"), &BTSetVar::get_value);
ClassDB::bind_method(D_METHOD("get_operation"), &BTSetVar::get_operation);
ClassDB::bind_method(D_METHOD("set_operation", "p_operation"), &BTSetVar::set_operation);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "variable"), "set_variable", "get_variable"); 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"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "value", PROPERTY_HINT_RESOURCE_TYPE, "BBVariant"), "set_value", "get_value");
ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "None,Addition,Subtraction,Multiplication,Division,Modulo,Power,Bit Shift Left,Bit Shift Right,Bit AND,Bit OR,Bit XOR"), "set_operation", "get_operation");
} }

View File

@ -15,6 +15,7 @@
#include "../bt_action.h" #include "../bt_action.h"
#include "modules/limboai/blackboard/bb_param/bb_variant.h" #include "modules/limboai/blackboard/bb_param/bb_variant.h"
#include "modules/limboai/util/limbo_utility.h"
#include "core/string/ustring.h" #include "core/string/ustring.h"
@ -25,6 +26,7 @@ class BTSetVar : public BTAction {
private: private:
String variable; String variable;
Ref<BBVariant> value; Ref<BBVariant> value;
LimboUtility::Operation operation = LimboUtility::OP_NONE;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -40,6 +42,9 @@ public:
void set_value(Ref<BBVariant> p_value); void set_value(Ref<BBVariant> p_value);
Ref<BBVariant> get_value() const { return value; } Ref<BBVariant> get_value() const { return value; }
void set_operation(LimboUtility::Operation p_operation);
LimboUtility::Operation get_operation() const { return operation; }
}; };
#endif // BT_SET_VAR #endif // BT_SET_VAR

View File

@ -97,7 +97,7 @@ Ref<Texture2D> LimboUtility::get_task_icon(String p_class_or_script_path) const
return nullptr; return nullptr;
} }
String LimboUtility::get_check_operator_string(CheckType p_check_type) { String LimboUtility::get_check_operator_string(CheckType p_check_type) const {
switch (p_check_type) { switch (p_check_type) {
case LimboUtility::CheckType::CHECK_EQUAL: { case LimboUtility::CheckType::CHECK_EQUAL: {
return "=="; return "==";
@ -149,6 +149,88 @@ bool LimboUtility::perform_check(CheckType p_check_type, const Variant &left_val
} }
} }
String LimboUtility::get_operation_string(Operation p_operation) const {
switch (p_operation) {
case OP_NONE: {
return "";
} break;
case OP_ADDITION: {
return "+";
} break;
case OP_SUBTRACTION: {
return "-";
} break;
case OP_MULTIPLICATION: {
return "*";
} break;
case OP_DIVISION: {
return "/";
} break;
case OP_MODULO: {
return "%";
} break;
case OP_POWER: {
return "**";
} break;
case OP_BIT_SHIFT_LEFT: {
return "<<";
} break;
case OP_BIT_SHIFT_RIGHT: {
return ">>";
} break;
case OP_BIT_AND: {
return "&";
} break;
case OP_BIT_OR: {
return "|";
} break;
case OP_BIT_XOR: {
return "^";
} break;
}
}
Variant LimboUtility::perform_operation(Operation p_operation, const Variant &left_value, const Variant &right_value) {
switch (p_operation) {
case OP_NONE: {
return right_value;
} break;
case OP_ADDITION: {
return Variant::evaluate(Variant::OP_ADD, left_value, right_value);
} break;
case OP_SUBTRACTION: {
return Variant::evaluate(Variant::OP_SUBTRACT, left_value, right_value);
} break;
case OP_MULTIPLICATION: {
return Variant::evaluate(Variant::OP_MULTIPLY, left_value, right_value);
} break;
case OP_DIVISION: {
return Variant::evaluate(Variant::OP_DIVIDE, left_value, right_value);
} break;
case OP_MODULO: {
return Variant::evaluate(Variant::OP_MODULE, left_value, right_value);
} break;
case OP_POWER: {
return Variant::evaluate(Variant::OP_MODULE, left_value, right_value);
} break;
case OP_BIT_SHIFT_LEFT: {
return Variant::evaluate(Variant::OP_SHIFT_LEFT, left_value, right_value);
} break;
case OP_BIT_SHIFT_RIGHT: {
return Variant::evaluate(Variant::OP_SHIFT_RIGHT, left_value, right_value);
} break;
case OP_BIT_AND: {
return Variant::evaluate(Variant::OP_BIT_AND, left_value, right_value);
} break;
case OP_BIT_OR: {
return Variant::evaluate(Variant::OP_BIT_OR, left_value, right_value);
} break;
case OP_BIT_XOR: {
return Variant::evaluate(Variant::OP_BIT_XOR, left_value, right_value);
} 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);
@ -160,6 +242,19 @@ void LimboUtility::_bind_methods() {
BIND_ENUM_CONSTANT(CHECK_GREATER_THAN); BIND_ENUM_CONSTANT(CHECK_GREATER_THAN);
BIND_ENUM_CONSTANT(CHECK_GREATER_THAN_OR_EQUAL); BIND_ENUM_CONSTANT(CHECK_GREATER_THAN_OR_EQUAL);
BIND_ENUM_CONSTANT(CHECK_NOT_EQUAL); BIND_ENUM_CONSTANT(CHECK_NOT_EQUAL);
BIND_ENUM_CONSTANT(OP_NONE);
BIND_ENUM_CONSTANT(OP_ADDITION);
BIND_ENUM_CONSTANT(OP_SUBTRACTION);
BIND_ENUM_CONSTANT(OP_MULTIPLICATION);
BIND_ENUM_CONSTANT(OP_DIVISION);
BIND_ENUM_CONSTANT(OP_MODULO);
BIND_ENUM_CONSTANT(OP_POWER);
BIND_ENUM_CONSTANT(OP_BIT_SHIFT_LEFT);
BIND_ENUM_CONSTANT(OP_BIT_SHIFT_RIGHT);
BIND_ENUM_CONSTANT(OP_BIT_AND);
BIND_ENUM_CONSTANT(OP_BIT_OR);
BIND_ENUM_CONSTANT(OP_BIT_XOR);
} }
LimboUtility::LimboUtility() { LimboUtility::LimboUtility() {

View File

@ -15,6 +15,7 @@
#include "core/object/object.h" #include "core/object/object.h"
#include "core/object/class_db.h" #include "core/object/class_db.h"
#include "core/variant/binder_common.h"
#include "core/variant/variant.h" #include "core/variant/variant.h"
#include "scene/resources/texture.h" #include "scene/resources/texture.h"
@ -33,6 +34,21 @@ public:
CHECK_NOT_EQUAL CHECK_NOT_EQUAL
}; };
enum Operation {
OP_NONE,
OP_ADDITION,
OP_SUBTRACTION,
OP_MULTIPLICATION,
OP_DIVISION,
OP_MODULO,
OP_POWER,
OP_BIT_SHIFT_LEFT,
OP_BIT_SHIFT_RIGHT,
OP_BIT_AND,
OP_BIT_OR,
OP_BIT_XOR,
};
protected: protected:
static LimboUtility *singleton; static LimboUtility *singleton;
static void _bind_methods(); static void _bind_methods();
@ -44,13 +60,17 @@ 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); String get_check_operator_string(CheckType p_check_type) const;
bool perform_check(CheckType p_check_type, const Variant &left_value, const Variant &right_value); bool perform_check(CheckType p_check_type, const Variant &left_value, const Variant &right_value);
String get_operation_string(Operation p_operation) const;
Variant perform_operation(Operation p_operation, const Variant &left_value, const Variant &right_value);
LimboUtility(); LimboUtility();
~LimboUtility(); ~LimboUtility();
}; };
VARIANT_ENUM_CAST(LimboUtility::CheckType); VARIANT_ENUM_CAST(LimboUtility::CheckType);
VARIANT_ENUM_CAST(LimboUtility::Operation);
#endif // LIMBO_UTILITY_H #endif // LIMBO_UTILITY_H