From 458ad5280eb59256473c1984c3b347662d401ad2 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sun, 6 Aug 2023 12:45:19 +0200 Subject: [PATCH] BTRepeat: Add `forever` property This property makes BTRepeat iterate child indefinitely. --- bt/decorators/bt_repeat.cpp | 41 ++++++++++++++++++++++++++++++++++--- bt/decorators/bt_repeat.h | 17 +++++++-------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/bt/decorators/bt_repeat.cpp b/bt/decorators/bt_repeat.cpp index dcb1285..3516183 100644 --- a/bt/decorators/bt_repeat.cpp +++ b/bt/decorators/bt_repeat.cpp @@ -12,9 +12,18 @@ #include "bt_repeat.h" #include "core/object/object.h" +#include "core/string/ustring.h" #include "core/variant/variant.h" +static String repeat_forever_str; + String BTRepeat::_generate_name() const { + if (forever) { + if (repeat_forever_str.is_empty()) { + repeat_forever_str.parse_utf8("Repeat ∞"); + } + return repeat_forever_str; + } return vformat("Repeat x%s", times); } @@ -25,7 +34,7 @@ void BTRepeat::_enter() { int BTRepeat::_tick(double p_delta) { ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child."); int status = get_child(0)->execute(p_delta); - if (status == RUNNING) { + if (status == RUNNING || forever) { return RUNNING; } else if (status == FAILURE && abort_on_failure) { return FAILURE; @@ -37,12 +46,38 @@ int BTRepeat::_tick(double p_delta) { } } +void BTRepeat::set_forever(bool p_forever) { + forever = p_forever; + notify_property_list_changed(); + emit_changed(); +} + +void BTRepeat::set_times(int p_value) { + times = p_value; + emit_changed(); +} + +void BTRepeat::set_abort_on_failure(bool p_value) { + abort_on_failure = p_value; + emit_changed(); +} + +void BTRepeat::_get_property_list(List *p_list) const { + if (!forever) { + p_list->push_back(PropertyInfo(Variant::INT, "times", PROPERTY_HINT_RANGE, "1,65535")); + p_list->push_back(PropertyInfo(Variant::BOOL, "abort_on_failure")); + } +} + void BTRepeat::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_forever", "p_value"), &BTRepeat::set_forever); + ClassDB::bind_method(D_METHOD("get_forever"), &BTRepeat::get_forever); ClassDB::bind_method(D_METHOD("set_times", "p_value"), &BTRepeat::set_times); ClassDB::bind_method(D_METHOD("get_times"), &BTRepeat::get_times); ClassDB::bind_method(D_METHOD("set_abort_on_failure", "p_value"), &BTRepeat::set_abort_on_failure); ClassDB::bind_method(D_METHOD("get_abort_on_failure"), &BTRepeat::get_abort_on_failure); - ADD_PROPERTY(PropertyInfo(Variant::INT, "times", PROPERTY_HINT_RANGE, "1,65535"), "set_times", "get_times"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "abort_on_failure"), "set_abort_on_failure", "get_abort_on_failure"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "forever"), "set_forever", "get_forever"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "times", PROPERTY_HINT_RANGE, "1,65535", PROPERTY_USAGE_NONE), "set_times", "get_times"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "abort_on_failure", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_abort_on_failure", "get_abort_on_failure"); } diff --git a/bt/decorators/bt_repeat.h b/bt/decorators/bt_repeat.h index 7385fdb..f0ea99c 100644 --- a/bt/decorators/bt_repeat.h +++ b/bt/decorators/bt_repeat.h @@ -20,6 +20,7 @@ class BTRepeat : public BTDecorator { GDCLASS(BTRepeat, BTDecorator); private: + bool forever = false; int times = 1; bool abort_on_failure = false; int cur_iteration = 0; @@ -27,20 +28,20 @@ private: protected: static void _bind_methods(); + void _get_property_list(List *p_list) const; + virtual String _generate_name() const override; virtual void _enter() override; virtual int _tick(double p_delta) override; public: - void set_times(int p_value) { - times = p_value; - emit_changed(); - } + void set_forever(bool p_forever); + bool get_forever() const { return forever; } + + void set_times(int p_value); int get_times() const { return times; } - void set_abort_on_failure(bool p_value) { - abort_on_failure = p_value; - emit_changed(); - } + + void set_abort_on_failure(bool p_value); bool get_abort_on_failure() const { return abort_on_failure; } };