BTRunLimit: Add `count_policy` property

Breaking compatibility: RunLimit count policy defaults to counting only successful runs. Previously, both successful and failed runs were counted.
This commit is contained in:
Serhii Snitsaruk 2024-02-10 20:13:39 +01:00
parent 654eda1c65
commit e6e2f5595d
2 changed files with 34 additions and 5 deletions

View File

@ -16,23 +16,39 @@ void BTRunLimit::set_run_limit(int p_value) {
emit_changed(); emit_changed();
} }
void BTRunLimit::set_count_policy(CountPolicy p_policy) {
count_policy = p_policy;
emit_changed();
}
String BTRunLimit::_generate_name() { String BTRunLimit::_generate_name() {
return vformat("RunLimit x%d", run_limit); return vformat("RunLimit x%d", run_limit);
} }
BT::Status BTRunLimit::_tick(double p_delta) { BT::Status BTRunLimit::_tick(double p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child."); ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
if (get_child(0)->get_status() != RUNNING) {
if (num_runs >= run_limit) { if (num_runs >= run_limit) {
return FAILURE; return FAILURE;
} }
Status child_status = get_child(0)->execute(p_delta);
if ((count_policy == COUNT_SUCCESSFUL && child_status == SUCCESS) ||
(count_policy == COUNT_FAILED && child_status == FAILURE) ||
(count_policy == COUNT_ALL && child_status != RUNNING)) {
num_runs += 1; num_runs += 1;
} }
return get_child(0)->execute(p_delta); return child_status;
} }
void BTRunLimit::_bind_methods() { void BTRunLimit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_run_limit", "p_value"), &BTRunLimit::set_run_limit); ClassDB::bind_method(D_METHOD("set_run_limit", "p_value"), &BTRunLimit::set_run_limit);
ClassDB::bind_method(D_METHOD("get_run_limit"), &BTRunLimit::get_run_limit); ClassDB::bind_method(D_METHOD("get_run_limit"), &BTRunLimit::get_run_limit);
ClassDB::bind_method(D_METHOD("set_count_policy", "p_policy"), &BTRunLimit::set_count_policy);
ClassDB::bind_method(D_METHOD("get_count_policy"), &BTRunLimit::get_count_policy);
ADD_PROPERTY(PropertyInfo(Variant::INT, "run_limit"), "set_run_limit", "get_run_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "run_limit"), "set_run_limit", "get_run_limit");
ADD_PROPERTY(PropertyInfo(Variant::INT, "count_policy", PROPERTY_HINT_ENUM, "COUNT_SUCCESSFUL,COUNT_FAILED,COUNT_ALL"), "set_count_policy", "get_count_policy");
BIND_ENUM_CONSTANT(COUNT_SUCCESSFUL);
BIND_ENUM_CONSTANT(COUNT_FAILED);
BIND_ENUM_CONSTANT(COUNT_ALL);
} }

View File

@ -18,8 +18,16 @@ class BTRunLimit : public BTDecorator {
GDCLASS(BTRunLimit, BTDecorator); GDCLASS(BTRunLimit, BTDecorator);
TASK_CATEGORY(Decorators); TASK_CATEGORY(Decorators);
public:
enum CountPolicy {
COUNT_SUCCESSFUL,
COUNT_FAILED,
COUNT_ALL,
};
private: private:
int run_limit = 1; int run_limit = 1;
CountPolicy count_policy = CountPolicy::COUNT_SUCCESSFUL;
int num_runs = 0; int num_runs = 0;
protected: protected:
@ -31,6 +39,11 @@ protected:
public: public:
void set_run_limit(int p_value); void set_run_limit(int p_value);
int get_run_limit() const { return run_limit; } int get_run_limit() const { return run_limit; }
void set_count_policy(CountPolicy p_policy);
CountPolicy get_count_policy() const { return count_policy; }
}; };
VARIANT_ENUM_CAST(BTRunLimit::CountPolicy);
#endif // BT_RUN_LIMIT_H #endif // BT_RUN_LIMIT_H