From 1ac24e67bbad27a67407965318401a5eddec8291 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Wed, 15 Nov 2023 14:45:10 +0100 Subject: [PATCH] BTSetVar: Specify operation to be performed with assignment --- bt/tasks/blackboard/bt_set_var.cpp | 24 +++++++- bt/tasks/blackboard/bt_set_var.h | 5 ++ util/limbo_utility.cpp | 97 +++++++++++++++++++++++++++++- util/limbo_utility.h | 22 ++++++- 4 files changed, 143 insertions(+), 5 deletions(-) diff --git a/bt/tasks/blackboard/bt_set_var.cpp b/bt/tasks/blackboard/bt_set_var.cpp index 768bdc8..d86be66 100644 --- a/bt/tasks/blackboard/bt_set_var.cpp +++ b/bt/tasks/blackboard/bt_set_var.cpp @@ -20,16 +20,26 @@ String BTSetVar::_generate_name() const { if (variable.is_empty()) { 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("???")); } 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(!value.is_valid(), FAILURE, "BTSetVar: `value` is not set."); + Variant result; Variant error_result = SNAME("Error: BTSetVar failed to get value!"); - Variant result = 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."); + Variant right_value = value->get_value(get_agent(), get_blackboard(), error_result); + 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); return SUCCESS; }; @@ -47,6 +57,11 @@ void BTSetVar::set_value(Ref p_value) { } } +void BTSetVar::set_operation(LimboUtility::Operation p_operation) { + operation = p_operation; + emit_changed(); +} + PackedStringArray BTSetVar::get_configuration_warnings() const { PackedStringArray warnings = BTAction::get_configuration_warnings(); 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("set_value", "p_value"), &BTSetVar::set_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::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"); } diff --git a/bt/tasks/blackboard/bt_set_var.h b/bt/tasks/blackboard/bt_set_var.h index 7fcc673..d2f89a9 100644 --- a/bt/tasks/blackboard/bt_set_var.h +++ b/bt/tasks/blackboard/bt_set_var.h @@ -15,6 +15,7 @@ #include "../bt_action.h" #include "modules/limboai/blackboard/bb_param/bb_variant.h" +#include "modules/limboai/util/limbo_utility.h" #include "core/string/ustring.h" @@ -25,6 +26,7 @@ class BTSetVar : public BTAction { private: String variable; Ref value; + LimboUtility::Operation operation = LimboUtility::OP_NONE; protected: static void _bind_methods(); @@ -40,6 +42,9 @@ public: void set_value(Ref p_value); Ref get_value() const { return value; } + + void set_operation(LimboUtility::Operation p_operation); + LimboUtility::Operation get_operation() const { return operation; } }; #endif // BT_SET_VAR \ No newline at end of file diff --git a/util/limbo_utility.cpp b/util/limbo_utility.cpp index 49e8d00..f713c06 100644 --- a/util/limbo_utility.cpp +++ b/util/limbo_utility.cpp @@ -97,7 +97,7 @@ Ref LimboUtility::get_task_icon(String p_class_or_script_path) const 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) { case LimboUtility::CheckType::CHECK_EQUAL: { 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() { 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); @@ -160,6 +242,19 @@ void LimboUtility::_bind_methods() { BIND_ENUM_CONSTANT(CHECK_GREATER_THAN); BIND_ENUM_CONSTANT(CHECK_GREATER_THAN_OR_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() { diff --git a/util/limbo_utility.h b/util/limbo_utility.h index 036e3dc..8b47988 100644 --- a/util/limbo_utility.h +++ b/util/limbo_utility.h @@ -15,6 +15,7 @@ #include "core/object/object.h" #include "core/object/class_db.h" +#include "core/variant/binder_common.h" #include "core/variant/variant.h" #include "scene/resources/texture.h" @@ -33,6 +34,21 @@ public: 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: static LimboUtility *singleton; static void _bind_methods(); @@ -44,13 +60,17 @@ public: String get_status_name(int p_status) const; Ref 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); + String get_operation_string(Operation p_operation) const; + Variant perform_operation(Operation p_operation, const Variant &left_value, const Variant &right_value); + LimboUtility(); ~LimboUtility(); }; VARIANT_ENUM_CAST(LimboUtility::CheckType); +VARIANT_ENUM_CAST(LimboUtility::Operation); #endif // LIMBO_UTILITY_H \ No newline at end of file