From cb46b5dff3b5cd7e48e2a637799281993788533b Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sun, 28 Aug 2022 22:24:33 +0200 Subject: [PATCH] Add Cooldown --- limboai/bt_cooldown.cpp | 65 ++++++++++++++++++++++++++++++++++++++ limboai/bt_cooldown.h | 60 +++++++++++++++++++++++++++++++++++ limboai/register_types.cpp | 2 ++ 3 files changed, 127 insertions(+) create mode 100644 limboai/bt_cooldown.cpp create mode 100644 limboai/bt_cooldown.h diff --git a/limboai/bt_cooldown.cpp b/limboai/bt_cooldown.cpp new file mode 100644 index 0000000..612a9fc --- /dev/null +++ b/limboai/bt_cooldown.cpp @@ -0,0 +1,65 @@ +/* bt_cooldown.cpp */ + +#include "bt_cooldown.h" +#include "core/array.h" +#include "core/class_db.h" +#include "scene/main/scene_tree.h" + +String BTCooldown::_generate_name() const { + return vformat("Cooldown %ss", duration); +} + +void BTCooldown::_setup() { + if (cooldown_state_var.empty()) { + cooldown_state_var = vformat("cooldown_%d", rand()); + } + get_blackboard()[cooldown_state_var] = false; + if (start_cooled) { + _chill(); + } +} + +int BTCooldown::_tick(float p_delta) { + if (get_blackboard().get(cooldown_state_var, true)) { + return FAILURE; + } + int status = get_child(0)->execute(p_delta); + if (status == SUCCESS || (trigger_on_failure && status == FAILURE)) { + _chill(); + } + return status; +} + +void BTCooldown::_chill() { + get_blackboard()[cooldown_state_var] = true; + if (_timer.is_valid()) { + _timer->set_time_left(duration); + } else { + _timer = SceneTree::get_singleton()->create_timer(duration, process_pause); + _timer->connect("timeout", this, "_on_timeout", Vector(), CONNECT_ONESHOT); + } +} + +void BTCooldown::_on_timeout() { + get_blackboard()[cooldown_state_var] = false; + _timer.unref(); +} + +void BTCooldown::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_duration", "p_value"), &BTCooldown::set_duration); + ClassDB::bind_method(D_METHOD("get_duration"), &BTCooldown::get_duration); + ClassDB::bind_method(D_METHOD("set_process_pause", "p_value"), &BTCooldown::set_process_pause); + ClassDB::bind_method(D_METHOD("get_process_pause"), &BTCooldown::get_process_pause); + ClassDB::bind_method(D_METHOD("set_start_cooled", "p_value"), &BTCooldown::set_start_cooled); + ClassDB::bind_method(D_METHOD("get_start_cooled"), &BTCooldown::get_start_cooled); + ClassDB::bind_method(D_METHOD("set_trigger_on_failure", "p_value"), &BTCooldown::set_trigger_on_failure); + ClassDB::bind_method(D_METHOD("get_trigger_on_failure"), &BTCooldown::get_trigger_on_failure); + ClassDB::bind_method(D_METHOD("set_cooldown_state_var", "p_value"), &BTCooldown::set_cooldown_state_var); + ClassDB::bind_method(D_METHOD("get_cooldown_state_var"), &BTCooldown::get_cooldown_state_var); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "duration"), "set_duration", "get_duration"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "process_pause"), "set_process_pause", "get_process_pause"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "start_cooled"), "set_start_cooled", "get_start_cooled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trigger_on_failure"), "set_trigger_on_failure", "get_trigger_on_failure"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "cooldown_state_var"), "set_cooldown_state_var", "get_cooldown_state_var"); +} diff --git a/limboai/bt_cooldown.h b/limboai/bt_cooldown.h new file mode 100644 index 0000000..4169406 --- /dev/null +++ b/limboai/bt_cooldown.h @@ -0,0 +1,60 @@ +/* bt_cooldown.h */ + +#ifndef BT_COOLDOWN_H +#define BT_COOLDOWN_H + +#include "bt_decorator.h" +#include "core/object.h" +#include "scene/main/scene_tree.h" + +class BTCooldown : public BTDecorator { + GDCLASS(BTCooldown, BTDecorator); + +private: + float duration = 10.0; + bool process_pause = false; + bool start_cooled = false; + bool trigger_on_failure = false; + String cooldown_state_var = ""; + + Ref _timer = nullptr; + + void _chill(); + void _on_timeout(); + +protected: + static void _bind_methods(); + + virtual String _generate_name() const; + virtual void _setup(); + virtual int _tick(float p_delta); + +public: + void set_duration(float p_value) { + duration = p_value; + emit_changed(); + } + float get_duration() const { return duration; } + void set_process_pause(bool p_value) { + process_pause = p_value; + emit_changed(); + } + bool get_process_pause() const { return process_pause; } + void set_start_cooled(bool p_value) { + start_cooled = p_value; + emit_changed(); + } + bool get_start_cooled() const { return start_cooled; } + void set_trigger_on_failure(bool p_value) { + trigger_on_failure = p_value; + emit_changed(); + } + bool get_trigger_on_failure() const { return trigger_on_failure; } + void set_cooldown_state_var(String p_value) { + cooldown_state_var = p_value; + emit_changed(); + } + String get_cooldown_state_var() const { return cooldown_state_var; } +}; + +#endif // BT_COOLDOWN_H \ No newline at end of file diff --git a/limboai/register_types.cpp b/limboai/register_types.cpp index 8371f42..b4d76cf 100644 --- a/limboai/register_types.cpp +++ b/limboai/register_types.cpp @@ -9,6 +9,7 @@ #include "bt_always_succeed.h" #include "bt_composite.h" #include "bt_condition.h" +#include "bt_cooldown.h" #include "bt_decorator.h" #include "bt_delay.h" #include "bt_invert.h" @@ -44,6 +45,7 @@ void register_limboai_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); LimboStringNames::create(); }