Add `LimboTaskDB` to handle task categories and scanning user tasks
This commit is contained in:
parent
26b9327090
commit
2ffcbf0565
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class BTAwaitAnimation : public BTAction {
|
class BTAwaitAnimation : public BTAction {
|
||||||
GDCLASS(BTAwaitAnimation, BTAction);
|
GDCLASS(BTAwaitAnimation, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BBNode> animation_player_param;
|
Ref<BBNode> animation_player_param;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTCallMethod : public BTAction {
|
class BTCallMethod : public BTAction {
|
||||||
GDCLASS(BTCallMethod, BTAction);
|
GDCLASS(BTCallMethod, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringName method_name;
|
StringName method_name;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTConsolePrint : public BTAction {
|
class BTConsolePrint : public BTAction {
|
||||||
GDCLASS(BTConsolePrint, BTAction);
|
GDCLASS(BTConsolePrint, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String text;
|
String text;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTFail : public BTAction {
|
class BTFail : public BTAction {
|
||||||
GDCLASS(BTFail, BTAction);
|
GDCLASS(BTFail, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class BTPauseAnimation : public BTAction {
|
class BTPauseAnimation : public BTAction {
|
||||||
GDCLASS(BTPauseAnimation, BTAction);
|
GDCLASS(BTPauseAnimation, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BBNode> animation_player_param;
|
Ref<BBNode> animation_player_param;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class BTPlayAnimation : public BTAction {
|
class BTPlayAnimation : public BTAction {
|
||||||
GDCLASS(BTPlayAnimation, BTAction);
|
GDCLASS(BTPlayAnimation, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BBNode> animation_player_param;
|
Ref<BBNode> animation_player_param;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTRandomWait : public BTAction {
|
class BTRandomWait : public BTAction {
|
||||||
GDCLASS(BTRandomWait, BTAction);
|
GDCLASS(BTRandomWait, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double min_duration = 1.0;
|
double min_duration = 1.0;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTSetAgentProperty : public BTAction {
|
class BTSetAgentProperty : public BTAction {
|
||||||
GDCLASS(BTSetAgentProperty, BTAction);
|
GDCLASS(BTSetAgentProperty, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringName property;
|
StringName property;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
* https://opensource.org/licenses/MIT.
|
* https://opensource.org/licenses/MIT.
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
/* bt_set_var.h */
|
|
||||||
|
|
||||||
#ifndef BT_SET_VAR_H
|
#ifndef BT_SET_VAR_H
|
||||||
#define BT_SET_VAR_H
|
#define BT_SET_VAR_H
|
||||||
|
@ -21,6 +20,7 @@
|
||||||
|
|
||||||
class BTSetVar : public BTAction {
|
class BTSetVar : public BTAction {
|
||||||
GDCLASS(BTSetVar, BTAction);
|
GDCLASS(BTSetVar, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String variable;
|
String variable;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class BTStopAnimation : public BTAction {
|
class BTStopAnimation : public BTAction {
|
||||||
GDCLASS(BTStopAnimation, BTAction);
|
GDCLASS(BTStopAnimation, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BBNode> animation_player_param;
|
Ref<BBNode> animation_player_param;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTWait : public BTAction {
|
class BTWait : public BTAction {
|
||||||
GDCLASS(BTWait, BTAction);
|
GDCLASS(BTWait, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double duration = 1.0;
|
double duration = 1.0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTWaitTicks : public BTAction {
|
class BTWaitTicks : public BTAction {
|
||||||
GDCLASS(BTWaitTicks, BTAction);
|
GDCLASS(BTWaitTicks, BTAction);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int num_ticks = 1;
|
int num_ticks = 1;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
* https://opensource.org/licenses/MIT.
|
* https://opensource.org/licenses/MIT.
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
/* bt_comment.h */
|
|
||||||
|
|
||||||
#ifndef BT_COMMENT_H
|
#ifndef BT_COMMENT_H
|
||||||
#define BT_COMMENT_H
|
#define BT_COMMENT_H
|
||||||
|
@ -18,8 +17,9 @@
|
||||||
class BTComment : public BTTask {
|
class BTComment : public BTTask {
|
||||||
GDCLASS(BTComment, BTTask);
|
GDCLASS(BTComment, BTTask);
|
||||||
|
|
||||||
private:
|
|
||||||
public:
|
public:
|
||||||
|
static _FORCE_INLINE_ String get_task_category() { return LimboTaskDB::get_misc_category(); }
|
||||||
|
|
||||||
virtual Ref<BTTask> clone() const override;
|
virtual Ref<BTTask> clone() const override;
|
||||||
virtual PackedStringArray get_configuration_warnings() const override;
|
virtual PackedStringArray get_configuration_warnings() const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define BTTASK_H
|
#define BTTASK_H
|
||||||
|
|
||||||
#include "modules/limboai/blackboard/blackboard.h"
|
#include "modules/limboai/blackboard/blackboard.h"
|
||||||
|
#include "modules/limboai/util/limbo_task_db.h"
|
||||||
|
|
||||||
#include "core/io/resource.h"
|
#include "core/io/resource.h"
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTDynamicSelector : public BTComposite {
|
class BTDynamicSelector : public BTComposite {
|
||||||
GDCLASS(BTDynamicSelector, BTComposite);
|
GDCLASS(BTDynamicSelector, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTDynamicSequence : public BTComposite {
|
class BTDynamicSequence : public BTComposite {
|
||||||
GDCLASS(BTDynamicSequence, BTComposite);
|
GDCLASS(BTDynamicSequence, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTParallel : public BTComposite {
|
class BTParallel : public BTComposite {
|
||||||
GDCLASS(BTParallel, BTComposite);
|
GDCLASS(BTParallel, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int num_successes_required = 1;
|
int num_successes_required = 1;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTRandomSelector : public BTComposite {
|
class BTRandomSelector : public BTComposite {
|
||||||
GDCLASS(BTRandomSelector, BTComposite);
|
GDCLASS(BTRandomSelector, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTRandomSequence : public BTComposite {
|
class BTRandomSequence : public BTComposite {
|
||||||
GDCLASS(BTRandomSequence, BTComposite);
|
GDCLASS(BTRandomSequence, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTSelector : public BTComposite {
|
class BTSelector : public BTComposite {
|
||||||
GDCLASS(BTSelector, BTComposite);
|
GDCLASS(BTSelector, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTSequence : public BTComposite {
|
class BTSequence : public BTComposite {
|
||||||
GDCLASS(BTSequence, BTComposite);
|
GDCLASS(BTSequence, BTComposite);
|
||||||
|
TASK_CATEGORY(Composites);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_running_idx = 0;
|
int last_running_idx = 0;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
class BTCheckAgentProperty : public BTCondition {
|
class BTCheckAgentProperty : public BTCondition {
|
||||||
GDCLASS(BTCheckAgentProperty, BTCondition);
|
GDCLASS(BTCheckAgentProperty, BTCondition);
|
||||||
|
TASK_CATEGORY(Conditions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringName property;
|
StringName property;
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* bt_check_trigger.h */
|
|
||||||
|
|
||||||
#ifndef BT_CHECK_TRIGGER_H
|
#ifndef BT_CHECK_TRIGGER_H
|
||||||
#define BT_CHECK_TRIGGER_H
|
#define BT_CHECK_TRIGGER_H
|
||||||
|
|
||||||
|
@ -20,6 +18,7 @@
|
||||||
|
|
||||||
class BTCheckTrigger : public BTCondition {
|
class BTCheckTrigger : public BTCondition {
|
||||||
GDCLASS(BTCheckTrigger, BTCondition);
|
GDCLASS(BTCheckTrigger, BTCondition);
|
||||||
|
TASK_CATEGORY(Conditions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String variable;
|
String variable;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
class BTCheckVar : public BTCondition {
|
class BTCheckVar : public BTCondition {
|
||||||
GDCLASS(BTCheckVar, BTCondition);
|
GDCLASS(BTCheckVar, BTCondition);
|
||||||
|
TASK_CATEGORY(Conditions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String variable;
|
String variable;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTAlwaysFail : public BTDecorator {
|
class BTAlwaysFail : public BTDecorator {
|
||||||
GDCLASS(BTAlwaysFail, BTDecorator);
|
GDCLASS(BTAlwaysFail, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTAlwaysSucceed : public BTDecorator {
|
class BTAlwaysSucceed : public BTDecorator {
|
||||||
GDCLASS(BTAlwaysSucceed, BTDecorator);
|
GDCLASS(BTAlwaysSucceed, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTCooldown : public BTDecorator {
|
class BTCooldown : public BTDecorator {
|
||||||
GDCLASS(BTCooldown, BTDecorator);
|
GDCLASS(BTCooldown, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double duration = 10.0;
|
double duration = 10.0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTDelay : public BTDecorator {
|
class BTDelay : public BTDecorator {
|
||||||
GDCLASS(BTDelay, BTDecorator);
|
GDCLASS(BTDelay, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double seconds = 1.0;
|
double seconds = 1.0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTForEach : public BTDecorator {
|
class BTForEach : public BTDecorator {
|
||||||
GDCLASS(BTForEach, BTDecorator);
|
GDCLASS(BTForEach, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String array_var;
|
String array_var;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTInvert : public BTDecorator {
|
class BTInvert : public BTDecorator {
|
||||||
GDCLASS(BTInvert, BTDecorator);
|
GDCLASS(BTInvert, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTNewScope : public BTDecorator {
|
class BTNewScope : public BTDecorator {
|
||||||
GDCLASS(BTNewScope, BTDecorator);
|
GDCLASS(BTNewScope, BTDecorator);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Dictionary blackboard_data;
|
Dictionary blackboard_data;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTProbability : public BTDecorator {
|
class BTProbability : public BTDecorator {
|
||||||
GDCLASS(BTProbability, BTDecorator);
|
GDCLASS(BTProbability, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float run_chance = 0.5;
|
float run_chance = 0.5;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTRepeat : public BTDecorator {
|
class BTRepeat : public BTDecorator {
|
||||||
GDCLASS(BTRepeat, BTDecorator);
|
GDCLASS(BTRepeat, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool forever = false;
|
bool forever = false;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTRepeatUntilFailure : public BTDecorator {
|
class BTRepeatUntilFailure : public BTDecorator {
|
||||||
GDCLASS(BTRepeatUntilFailure, BTDecorator);
|
GDCLASS(BTRepeatUntilFailure, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTRepeatUntilSuccess : public BTDecorator {
|
class BTRepeatUntilSuccess : public BTDecorator {
|
||||||
GDCLASS(BTRepeatUntilSuccess, BTDecorator);
|
GDCLASS(BTRepeatUntilSuccess, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int _tick(double p_delta) override;
|
virtual int _tick(double p_delta) override;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTRunLimit : public BTDecorator {
|
class BTRunLimit : public BTDecorator {
|
||||||
GDCLASS(BTRunLimit, BTDecorator);
|
GDCLASS(BTRunLimit, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int run_limit = 1;
|
int run_limit = 1;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
class BTSubtree : public BTNewScope {
|
class BTSubtree : public BTNewScope {
|
||||||
GDCLASS(BTSubtree, BTNewScope);
|
GDCLASS(BTSubtree, BTNewScope);
|
||||||
|
TASK_CATEGORY(Actions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BehaviorTree> subtree;
|
Ref<BehaviorTree> subtree;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
class BTTimeLimit : public BTDecorator {
|
class BTTimeLimit : public BTDecorator {
|
||||||
GDCLASS(BTTimeLimit, BTDecorator);
|
GDCLASS(BTTimeLimit, BTDecorator);
|
||||||
|
TASK_CATEGORY(Decorators);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double time_limit = 5.0;
|
double time_limit = 5.0;
|
||||||
|
|
|
@ -563,39 +563,12 @@ void TaskPanel::refresh() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap<String, List<String>> categorized_tasks;
|
LimboTaskDB::scan_user_tasks();
|
||||||
|
List<String> categories = LimboTaskDB::get_categories();
|
||||||
categorized_tasks["Composites"] = List<String>();
|
|
||||||
_populate_core_tasks_from_class("BTComposite", &categorized_tasks["Composites"]);
|
|
||||||
|
|
||||||
categorized_tasks["Actions"] = List<String>();
|
|
||||||
_populate_core_tasks_from_class("BTAction", &categorized_tasks["Actions"]);
|
|
||||||
|
|
||||||
categorized_tasks["Decorators"] = List<String>();
|
|
||||||
_populate_core_tasks_from_class("BTDecorator", &categorized_tasks["Decorators"]);
|
|
||||||
|
|
||||||
categorized_tasks["Conditions"] = List<String>();
|
|
||||||
_populate_core_tasks_from_class("BTCondition", &categorized_tasks["Conditions"]);
|
|
||||||
|
|
||||||
categorized_tasks["Uncategorized"] = List<String>();
|
|
||||||
|
|
||||||
String dir1 = GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_1");
|
|
||||||
_populate_from_user_dir(dir1, &categorized_tasks);
|
|
||||||
|
|
||||||
String dir2 = GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_2");
|
|
||||||
_populate_from_user_dir(dir2, &categorized_tasks);
|
|
||||||
|
|
||||||
String dir3 = GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_3");
|
|
||||||
_populate_from_user_dir(dir3, &categorized_tasks);
|
|
||||||
|
|
||||||
List<String> categories;
|
|
||||||
for (KeyValue<String, List<String>> &K : categorized_tasks) {
|
|
||||||
K.value.sort();
|
|
||||||
categories.push_back(K.key);
|
|
||||||
}
|
|
||||||
categories.sort();
|
categories.sort();
|
||||||
|
|
||||||
for (String cat : categories) {
|
for (String cat : categories) {
|
||||||
List<String> tasks = categorized_tasks.get(cat);
|
List<String> tasks = LimboTaskDB::get_tasks_in_category(cat);
|
||||||
|
|
||||||
if (tasks.size() == 0) {
|
if (tasks.size() == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -642,70 +615,6 @@ void TaskPanel::refresh() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPanel::_populate_core_tasks_from_class(const StringName &p_base_class, List<String> *p_task_classes) {
|
|
||||||
List<StringName> inheriters;
|
|
||||||
ClassDB::get_inheriters_from_class(p_base_class, &inheriters);
|
|
||||||
|
|
||||||
for (StringName cl : inheriters) {
|
|
||||||
p_task_classes->push_back(cl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TaskPanel::_populate_from_user_dir(String p_path, HashMap<String, List<String>> *p_categories) {
|
|
||||||
if (p_path.is_empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
|
||||||
if (dir->change_dir(p_path) == OK) {
|
|
||||||
dir->list_dir_begin();
|
|
||||||
String fn = dir->get_next();
|
|
||||||
while (!fn.is_empty()) {
|
|
||||||
if (dir->current_is_dir() && fn != "..") {
|
|
||||||
String full_path;
|
|
||||||
String category;
|
|
||||||
if (fn == ".") {
|
|
||||||
full_path = p_path;
|
|
||||||
category = "Uncategorized";
|
|
||||||
} else {
|
|
||||||
full_path = p_path.path_join(fn);
|
|
||||||
category = fn.capitalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p_categories->has(category)) {
|
|
||||||
p_categories->insert(category, List<String>());
|
|
||||||
}
|
|
||||||
|
|
||||||
_populate_scripted_tasks_from_dir(full_path, &p_categories->get(category));
|
|
||||||
}
|
|
||||||
fn = dir->get_next();
|
|
||||||
}
|
|
||||||
dir->list_dir_end();
|
|
||||||
} else {
|
|
||||||
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TaskPanel::_populate_scripted_tasks_from_dir(String p_path, List<String> *p_task_classes) {
|
|
||||||
if (p_path.is_empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
|
||||||
if (dir->change_dir(p_path) == OK) {
|
|
||||||
dir->list_dir_begin();
|
|
||||||
String fn = dir->get_next();
|
|
||||||
while (!fn.is_empty()) {
|
|
||||||
if (fn.ends_with(".gd")) {
|
|
||||||
String full_path = p_path.path_join(fn);
|
|
||||||
p_task_classes->push_back(full_path);
|
|
||||||
}
|
|
||||||
fn = dir->get_next();
|
|
||||||
}
|
|
||||||
dir->list_dir_end();
|
|
||||||
} else {
|
|
||||||
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TaskPanel::_notification(int p_what) {
|
void TaskPanel::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
|
|
@ -129,9 +129,6 @@ private:
|
||||||
|
|
||||||
String context_task;
|
String context_task;
|
||||||
|
|
||||||
void _populate_core_tasks_from_class(const StringName &p_base_class, List<String> *p_task_classes);
|
|
||||||
void _populate_from_user_dir(String p_path, HashMap<String, List<String>> *p_categories);
|
|
||||||
void _populate_scripted_tasks_from_dir(String p_path, List<String> *p_task_classes);
|
|
||||||
void _menu_action_selected(int p_id);
|
void _menu_action_selected(int p_id);
|
||||||
void _on_task_button_pressed(const String &p_task);
|
void _on_task_button_pressed(const String &p_task);
|
||||||
void _on_task_button_rmb(const String &p_task);
|
void _on_task_button_rmb(const String &p_task);
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#include "hsm/limbo_hsm.h"
|
#include "hsm/limbo_hsm.h"
|
||||||
#include "hsm/limbo_state.h"
|
#include "hsm/limbo_state.h"
|
||||||
#include "util/limbo_string_names.h"
|
#include "util/limbo_string_names.h"
|
||||||
|
#include "util/limbo_task_db.h"
|
||||||
#include "util/limbo_utility.h"
|
#include "util/limbo_utility.h"
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
@ -121,51 +122,51 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
|
||||||
GDREGISTER_CLASS(BTPlayer);
|
GDREGISTER_CLASS(BTPlayer);
|
||||||
GDREGISTER_CLASS(BTState);
|
GDREGISTER_CLASS(BTState);
|
||||||
|
|
||||||
GDREGISTER_CLASS(BTComment);
|
LIMBO_REGISTER_TASK(BTComment);
|
||||||
|
|
||||||
GDREGISTER_CLASS(BTComposite);
|
GDREGISTER_CLASS(BTComposite);
|
||||||
GDREGISTER_CLASS(BTSequence);
|
LIMBO_REGISTER_TASK(BTSequence);
|
||||||
GDREGISTER_CLASS(BTSelector);
|
LIMBO_REGISTER_TASK(BTSelector);
|
||||||
GDREGISTER_CLASS(BTParallel);
|
LIMBO_REGISTER_TASK(BTParallel);
|
||||||
GDREGISTER_CLASS(BTDynamicSequence);
|
LIMBO_REGISTER_TASK(BTDynamicSequence);
|
||||||
GDREGISTER_CLASS(BTDynamicSelector);
|
LIMBO_REGISTER_TASK(BTDynamicSelector);
|
||||||
GDREGISTER_CLASS(BTRandomSequence);
|
LIMBO_REGISTER_TASK(BTRandomSequence);
|
||||||
GDREGISTER_CLASS(BTRandomSelector);
|
LIMBO_REGISTER_TASK(BTRandomSelector);
|
||||||
|
|
||||||
GDREGISTER_CLASS(BTDecorator);
|
GDREGISTER_CLASS(BTDecorator);
|
||||||
GDREGISTER_CLASS(BTInvert);
|
LIMBO_REGISTER_TASK(BTInvert);
|
||||||
GDREGISTER_CLASS(BTAlwaysFail);
|
LIMBO_REGISTER_TASK(BTAlwaysFail);
|
||||||
GDREGISTER_CLASS(BTAlwaysSucceed);
|
LIMBO_REGISTER_TASK(BTAlwaysSucceed);
|
||||||
GDREGISTER_CLASS(BTDelay);
|
LIMBO_REGISTER_TASK(BTDelay);
|
||||||
GDREGISTER_CLASS(BTRepeat);
|
LIMBO_REGISTER_TASK(BTRepeat);
|
||||||
GDREGISTER_CLASS(BTRepeatUntilFailure);
|
LIMBO_REGISTER_TASK(BTRepeatUntilFailure);
|
||||||
GDREGISTER_CLASS(BTRepeatUntilSuccess);
|
LIMBO_REGISTER_TASK(BTRepeatUntilSuccess);
|
||||||
GDREGISTER_CLASS(BTRunLimit);
|
LIMBO_REGISTER_TASK(BTRunLimit);
|
||||||
GDREGISTER_CLASS(BTTimeLimit);
|
LIMBO_REGISTER_TASK(BTTimeLimit);
|
||||||
GDREGISTER_CLASS(BTCooldown);
|
LIMBO_REGISTER_TASK(BTCooldown);
|
||||||
GDREGISTER_CLASS(BTProbability);
|
LIMBO_REGISTER_TASK(BTProbability);
|
||||||
GDREGISTER_CLASS(BTForEach);
|
LIMBO_REGISTER_TASK(BTForEach);
|
||||||
|
|
||||||
GDREGISTER_CLASS(BTAction);
|
GDREGISTER_CLASS(BTAction);
|
||||||
GDREGISTER_CLASS(BTAwaitAnimation);
|
LIMBO_REGISTER_TASK(BTAwaitAnimation);
|
||||||
GDREGISTER_CLASS(BTCallMethod);
|
LIMBO_REGISTER_TASK(BTCallMethod);
|
||||||
GDREGISTER_CLASS(BTConsolePrint);
|
LIMBO_REGISTER_TASK(BTConsolePrint);
|
||||||
GDREGISTER_CLASS(BTFail);
|
LIMBO_REGISTER_TASK(BTFail);
|
||||||
GDREGISTER_CLASS(BTNewScope);
|
LIMBO_REGISTER_TASK(BTNewScope);
|
||||||
GDREGISTER_CLASS(BTPauseAnimation);
|
LIMBO_REGISTER_TASK(BTPauseAnimation);
|
||||||
GDREGISTER_CLASS(BTPlayAnimation);
|
LIMBO_REGISTER_TASK(BTPlayAnimation);
|
||||||
GDREGISTER_CLASS(BTRandomWait);
|
LIMBO_REGISTER_TASK(BTRandomWait);
|
||||||
GDREGISTER_CLASS(BTSetAgentProperty);
|
LIMBO_REGISTER_TASK(BTSetAgentProperty);
|
||||||
GDREGISTER_CLASS(BTSetVar);
|
LIMBO_REGISTER_TASK(BTSetVar);
|
||||||
GDREGISTER_CLASS(BTStopAnimation);
|
LIMBO_REGISTER_TASK(BTStopAnimation);
|
||||||
GDREGISTER_CLASS(BTSubtree);
|
LIMBO_REGISTER_TASK(BTSubtree);
|
||||||
GDREGISTER_CLASS(BTWait);
|
LIMBO_REGISTER_TASK(BTWait);
|
||||||
GDREGISTER_CLASS(BTWaitTicks);
|
LIMBO_REGISTER_TASK(BTWaitTicks);
|
||||||
|
|
||||||
GDREGISTER_CLASS(BTCondition);
|
GDREGISTER_CLASS(BTCondition);
|
||||||
GDREGISTER_CLASS(BTCheckAgentProperty);
|
LIMBO_REGISTER_TASK(BTCheckAgentProperty);
|
||||||
GDREGISTER_CLASS(BTCheckTrigger);
|
LIMBO_REGISTER_TASK(BTCheckTrigger);
|
||||||
GDREGISTER_CLASS(BTCheckVar);
|
LIMBO_REGISTER_TASK(BTCheckVar);
|
||||||
|
|
||||||
GDREGISTER_ABSTRACT_CLASS(BBParam);
|
GDREGISTER_ABSTRACT_CLASS(BBParam);
|
||||||
GDREGISTER_CLASS(BBInt);
|
GDREGISTER_CLASS(BBInt);
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* limbo_task_db.cpp
|
||||||
|
* =============================================================================
|
||||||
|
* Copyright 2021-2023 Serhii Snitsaruk
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
* =============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "limbo_task_db.h"
|
||||||
|
|
||||||
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/io/dir_access.h"
|
||||||
|
|
||||||
|
HashMap<String, List<String>> LimboTaskDB::core_tasks;
|
||||||
|
HashMap<String, List<String>> LimboTaskDB::tasks_cache;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void _populate_scripted_tasks_from_dir(String p_path, List<String> *p_task_classes) {
|
||||||
|
if (p_path.is_empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||||
|
if (dir->change_dir(p_path) == OK) {
|
||||||
|
dir->list_dir_begin();
|
||||||
|
String fn = dir->get_next();
|
||||||
|
while (!fn.is_empty()) {
|
||||||
|
if (fn.ends_with(".gd")) {
|
||||||
|
String full_path = p_path.path_join(fn);
|
||||||
|
p_task_classes->push_back(full_path);
|
||||||
|
}
|
||||||
|
fn = dir->get_next();
|
||||||
|
}
|
||||||
|
dir->list_dir_end();
|
||||||
|
} else {
|
||||||
|
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void _populate_from_user_dir(String p_path, HashMap<String, List<String>> *p_categories) {
|
||||||
|
if (p_path.is_empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ref<DirAccess> dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||||
|
if (dir->change_dir(p_path) == OK) {
|
||||||
|
dir->list_dir_begin();
|
||||||
|
String fn = dir->get_next();
|
||||||
|
while (!fn.is_empty()) {
|
||||||
|
if (dir->current_is_dir() && fn != "..") {
|
||||||
|
String full_path;
|
||||||
|
String category;
|
||||||
|
if (fn == ".") {
|
||||||
|
full_path = p_path;
|
||||||
|
category = LimboTaskDB::get_misc_category();
|
||||||
|
} else {
|
||||||
|
full_path = p_path.path_join(fn);
|
||||||
|
category = fn.capitalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_categories->has(category)) {
|
||||||
|
p_categories->insert(category, List<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
_populate_scripted_tasks_from_dir(full_path, &p_categories->get(category));
|
||||||
|
}
|
||||||
|
fn = dir->get_next();
|
||||||
|
}
|
||||||
|
dir->list_dir_end();
|
||||||
|
} else {
|
||||||
|
ERR_FAIL_MSG(vformat("Failed to list \"%s\" directory.", p_path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboTaskDB::scan_user_tasks() {
|
||||||
|
tasks_cache = HashMap<String, List<String>>(core_tasks);
|
||||||
|
|
||||||
|
if (!tasks_cache.has(LimboTaskDB::get_misc_category())) {
|
||||||
|
tasks_cache[LimboTaskDB::get_misc_category()] = List<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < 4; i++) {
|
||||||
|
String dir1 = GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_" + itos(i));
|
||||||
|
_populate_from_user_dir(dir1, &tasks_cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> LimboTaskDB::get_categories() {
|
||||||
|
List<String> r_cat;
|
||||||
|
for (const KeyValue<String, List<String>> &E : tasks_cache) {
|
||||||
|
r_cat.push_back(E.key);
|
||||||
|
}
|
||||||
|
return r_cat;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> LimboTaskDB::get_tasks_in_category(const String &p_category) {
|
||||||
|
return List<String>(tasks_cache[p_category]);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* limbo_task_db.h
|
||||||
|
* =============================================================================
|
||||||
|
* Copyright 2021-2023 Serhii Snitsaruk
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
* =============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIMBO_TASK_DB_H
|
||||||
|
#define LIMBO_TASK_DB_H
|
||||||
|
|
||||||
|
#include "core/object/class_db.h"
|
||||||
|
#include "core/templates/hash_map.h"
|
||||||
|
#include "core/templates/list.h"
|
||||||
|
|
||||||
|
class LimboTaskDB {
|
||||||
|
private:
|
||||||
|
static HashMap<String, List<String>> core_tasks;
|
||||||
|
static HashMap<String, List<String>> tasks_cache;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <class T>
|
||||||
|
static void register_task() {
|
||||||
|
GDREGISTER_CLASS(T);
|
||||||
|
HashMap<String, List<String>>::Iterator E = core_tasks.find(T::get_task_category());
|
||||||
|
if (E) {
|
||||||
|
E->value.push_back(T::get_class_static());
|
||||||
|
} else {
|
||||||
|
List<String> tasks;
|
||||||
|
tasks.push_back(T::get_class_static());
|
||||||
|
core_tasks.insert(T::get_task_category(), tasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scan_user_tasks();
|
||||||
|
static _FORCE_INLINE_ String get_misc_category() { return "Misc"; }
|
||||||
|
static List<String> get_categories();
|
||||||
|
static List<String> get_tasks_in_category(const String &p_category);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LIMBO_REGISTER_TASK(m_class) \
|
||||||
|
if (m_class::_class_is_enabled) { \
|
||||||
|
::LimboTaskDB::register_task<m_class>(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TASK_CATEGORY(m_cat) \
|
||||||
|
public: \
|
||||||
|
static _FORCE_INLINE_ String get_task_category() { \
|
||||||
|
return String(#m_cat); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
private:
|
||||||
|
|
||||||
|
#endif // LIMBO_TASK_DB_H
|
Loading…
Reference in New Issue