Compare commits
24 Commits
722b4ee0a0
...
ff4f9760b5
Author | SHA1 | Date |
---|---|---|
Wilson E. Alvarez | ff4f9760b5 | |
Serhii Snitsaruk | 2f326e5b6f | |
Serhii Snitsaruk | 064d00fdfa | |
Serhii Snitsaruk | ff61d55c44 | |
Serhii Snitsaruk | 7ab7a9d098 | |
Serhii Snitsaruk | b54f3696ff | |
Serhii Snitsaruk | dc77ecd2b2 | |
Serhii Snitsaruk | 026272f7f7 | |
Serhii Snitsaruk | d08018b7b1 | |
Serhii Snitsaruk | d920060dee | |
Serhii Snitsaruk | 2718271bb1 | |
Serhii Snitsaruk | 3cf90f9387 | |
Serhii Snitsaruk | c6b1a40627 | |
Serhii Snitsaruk | d36f8f1122 | |
Serhii Snitsaruk | a572613001 | |
Serhii Snitsaruk | c30c5a4d7a | |
Serhii Snitsaruk | ef1c1e5192 | |
Serhii Snitsaruk | 3b12288ae0 | |
Serhii Snitsaruk | a1cdff2e2e | |
Serhii Snitsaruk | e43bc25d82 | |
Ola S. | 549d73b8fc | |
Serhii Snitsaruk | 0d1e846d93 | |
Serhii Snitsaruk | 2d493a76bd | |
Serhii Snitsaruk | bdfe5f52c2 |
|
@ -17,10 +17,8 @@
|
||||||
class BBNode : public BBParam {
|
class BBNode : public BBParam {
|
||||||
GDCLASS(BBNode, BBParam);
|
GDCLASS(BBNode, BBParam);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual Variant::Type get_type() const override { return Variant::NODE_PATH; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual Variant::Type get_type() const override { return Variant::NODE_PATH; }
|
||||||
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant()) override;
|
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant()) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,6 @@ protected:
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Variant::Type get_type() const { return Variant::NIL; }
|
|
||||||
|
|
||||||
void set_value_source(ValueSource p_value);
|
void set_value_source(ValueSource p_value);
|
||||||
ValueSource get_value_source() const { return value_source; }
|
ValueSource get_value_source() const { return value_source; }
|
||||||
|
|
||||||
|
@ -66,6 +64,8 @@ public:
|
||||||
virtual String _to_string();
|
virtual String _to_string();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual Variant::Type get_type() const { return Variant::NIL; }
|
||||||
|
virtual Variant::Type get_variable_expected_type() const { return get_type(); }
|
||||||
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant());
|
virtual Variant get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default = Variant());
|
||||||
|
|
||||||
BBParam();
|
BBParam();
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
virtual Variant::Type get_type() const override;
|
virtual Variant::Type get_type() const override;
|
||||||
void set_type(Variant::Type p_type);
|
void set_type(Variant::Type p_type);
|
||||||
|
|
||||||
|
virtual Variant::Type get_variable_expected_type() const override { return Variant::NIL; }
|
||||||
|
|
||||||
BBVariant(const Variant &p_value);
|
BBVariant(const Variant &p_value);
|
||||||
BBVariant();
|
BBVariant();
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "blackboard_plan.h"
|
#include "blackboard_plan.h"
|
||||||
|
|
||||||
|
#include "../util/limbo_utility.h"
|
||||||
|
|
||||||
bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
String name_str = p_name;
|
String name_str = p_name;
|
||||||
|
|
||||||
|
@ -25,6 +27,28 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * Mapping
|
||||||
|
if (name_str.begins_with("mapping/")) {
|
||||||
|
StringName mapped_var_name = name_str.get_slicec('/', 1);
|
||||||
|
StringName value = p_value;
|
||||||
|
bool properties_changed = false;
|
||||||
|
if (value == StringName()) {
|
||||||
|
if (parent_scope_mapping.has(mapped_var_name)) {
|
||||||
|
properties_changed = true;
|
||||||
|
parent_scope_mapping.erase(mapped_var_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!parent_scope_mapping.has(mapped_var_name)) {
|
||||||
|
properties_changed = true;
|
||||||
|
}
|
||||||
|
parent_scope_mapping[mapped_var_name] = value;
|
||||||
|
}
|
||||||
|
if (properties_changed) {
|
||||||
|
notify_property_list_changed();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// * Storage
|
// * Storage
|
||||||
if (name_str.begins_with("var/")) {
|
if (name_str.begins_with("var/")) {
|
||||||
StringName var_name = name_str.get_slicec('/', 1);
|
StringName var_name = name_str.get_slicec('/', 1);
|
||||||
|
@ -56,7 +80,23 @@ bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
|
|
||||||
// * Editor
|
// * Editor
|
||||||
if (var_map.has(p_name)) {
|
if (var_map.has(p_name)) {
|
||||||
|
if (has_mapping(p_name)) {
|
||||||
|
r_ret = "Mapped to " + LimboUtility::get_singleton()->decorate_var(parent_scope_mapping[p_name]);
|
||||||
|
} else {
|
||||||
r_ret = var_map[p_name].get_value();
|
r_ret = var_map[p_name].get_value();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * Mapping
|
||||||
|
if (name_str.begins_with("mapping/")) {
|
||||||
|
StringName mapped_var_name = name_str.get_slicec('/', 1);
|
||||||
|
ERR_FAIL_COND_V(mapped_var_name == StringName(), false);
|
||||||
|
if (parent_scope_mapping.has(mapped_var_name)) {
|
||||||
|
r_ret = parent_scope_mapping[mapped_var_name];
|
||||||
|
} else {
|
||||||
|
r_ret = StringName();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +104,6 @@ bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
if (!name_str.begins_with("var/")) {
|
if (!name_str.begins_with("var/")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName var_name = name_str.get_slicec('/', 1);
|
StringName var_name = name_str.get_slicec('/', 1);
|
||||||
String what = name_str.get_slicec('/', 2);
|
String what = name_str.get_slicec('/', 2);
|
||||||
ERR_FAIL_COND_V(!var_map.has(var_name), false);
|
ERR_FAIL_COND_V(!var_map.has(var_name), false);
|
||||||
|
@ -90,29 +129,49 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
// * Editor
|
// * Editor
|
||||||
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
|
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
|
||||||
|
if (has_mapping(var_name)) {
|
||||||
|
p_list->push_back(PropertyInfo(Variant::STRING, var_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
|
||||||
|
} else {
|
||||||
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
|
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * Storage
|
||||||
if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) {
|
if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) {
|
||||||
// Don't store variable if it's not modified in a derived plan.
|
// Don't store variable if it's not modified in a derived plan.
|
||||||
// Variable is considered modified when it's marked as changed and its value is different from the base plan.
|
// Variable is considered modified when it's marked as changed and its value is different from the base plan.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Storage
|
|
||||||
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||||
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||||
p_list->push_back(PropertyInfo(var.get_type(), "var/" + var_name + "/value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
p_list->push_back(PropertyInfo(var.get_type(), "var/" + var_name + "/value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||||
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
p_list->push_back(PropertyInfo(Variant::INT, "var/" + var_name + "/hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||||
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/hint_string", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
p_list->push_back(PropertyInfo(Variant::STRING, "var/" + var_name + "/hint_string", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * Mapping
|
||||||
|
if (is_mapping_enabled()) {
|
||||||
|
p_list->push_back(PropertyInfo(Variant::NIL, "Mapping", PROPERTY_HINT_NONE, "mapping/", PROPERTY_USAGE_GROUP));
|
||||||
|
for (const Pair<StringName, BBVariable> &p : var_list) {
|
||||||
|
// Serialize only non-empty mappings.
|
||||||
|
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
|
||||||
|
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackboardPlan::_property_can_revert(const StringName &p_name) const {
|
bool BlackboardPlan::_property_can_revert(const StringName &p_name) const {
|
||||||
|
if (String(p_name).begins_with("mapping/")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return base.is_valid() && base->var_map.has(p_name);
|
return base.is_valid() && base->var_map.has(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackboardPlan::_property_get_revert(const StringName &p_name, Variant &r_property) const {
|
bool BlackboardPlan::_property_get_revert(const StringName &p_name, Variant &r_property) const {
|
||||||
|
if (String(p_name).begins_with("mapping/")) {
|
||||||
|
r_property = StringName();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (base->var_map.has(p_name)) {
|
if (base->var_map.has(p_name)) {
|
||||||
r_property = base->var_map[p_name].get_value();
|
r_property = base->var_map[p_name].get_value();
|
||||||
return true;
|
return true;
|
||||||
|
@ -131,6 +190,15 @@ void BlackboardPlan::set_base_plan(const Ref<BlackboardPlan> &p_base) {
|
||||||
notify_property_list_changed();
|
notify_property_list_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlackboardPlan::set_parent_scope_plan_provider(const Callable &p_parent_scope_plan_provider) {
|
||||||
|
parent_scope_plan_provider = p_parent_scope_plan_provider;
|
||||||
|
notify_property_list_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlackboardPlan::has_mapping(const StringName &p_name) const {
|
||||||
|
return is_mapping_enabled() && parent_scope_mapping.has(p_name) && parent_scope_mapping[p_name] != StringName();
|
||||||
|
}
|
||||||
|
|
||||||
void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) {
|
void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) {
|
||||||
prefetch_nodepath_vars = p_enable;
|
prefetch_nodepath_vars = p_enable;
|
||||||
emit_changed();
|
emit_changed();
|
||||||
|
@ -214,6 +282,11 @@ void BlackboardPlan::rename_var(const StringName &p_name, const StringName &p_ne
|
||||||
var_map.erase(p_name);
|
var_map.erase(p_name);
|
||||||
var_map.insert(p_new_name, var);
|
var_map.insert(p_new_name, var);
|
||||||
|
|
||||||
|
if (parent_scope_mapping.has(p_name)) {
|
||||||
|
parent_scope_mapping[p_new_name] = parent_scope_mapping[p_name];
|
||||||
|
parent_scope_mapping.erase(p_name);
|
||||||
|
}
|
||||||
|
|
||||||
notify_property_list_changed();
|
notify_property_list_changed();
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
@ -335,12 +408,11 @@ inline void bb_add_var_dup_with_prefetch(const Ref<Blackboard> &p_blackboard, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node) {
|
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node, const Ref<Blackboard> &p_parent_scope) {
|
||||||
ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
|
ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
|
||||||
Ref<Blackboard> bb = memnew(Blackboard);
|
Ref<Blackboard> bb = memnew(Blackboard);
|
||||||
for (const Pair<StringName, BBVariable> &p : var_list) {
|
bb->set_parent(p_parent_scope);
|
||||||
bb_add_var_dup_with_prefetch(bb, p.first, p.second, prefetch_nodepath_vars, p_node);
|
populate_blackboard(bb, true, p_node);
|
||||||
}
|
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +423,13 @@ void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bo
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, prefetch_nodepath_vars, p_node);
|
bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, prefetch_nodepath_vars, p_node);
|
||||||
|
if (parent_scope_mapping.has(p.first)) {
|
||||||
|
StringName target_var = parent_scope_mapping[p.first];
|
||||||
|
if (target_var != StringName()) {
|
||||||
|
ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable $%s to parent scope because the parent scope is not set.", p.first));
|
||||||
|
p_blackboard->link_var(p.first, p_blackboard->get_parent(), target_var);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +441,9 @@ void BlackboardPlan::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_base_plan"), &BlackboardPlan::get_base_plan);
|
ClassDB::bind_method(D_METHOD("get_base_plan"), &BlackboardPlan::get_base_plan);
|
||||||
ClassDB::bind_method(D_METHOD("is_derived"), &BlackboardPlan::is_derived);
|
ClassDB::bind_method(D_METHOD("is_derived"), &BlackboardPlan::is_derived);
|
||||||
ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan);
|
ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan);
|
||||||
ClassDB::bind_method(D_METHOD("create_blackboard", "node"), &BlackboardPlan::create_blackboard);
|
ClassDB::bind_method(D_METHOD("set_parent_scope_plan_provider", "callable"), &BlackboardPlan::set_parent_scope_plan_provider);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_parent_scope_plan_provider"), &BlackboardPlan::get_parent_scope_plan_provider);
|
||||||
|
ClassDB::bind_method(D_METHOD("create_blackboard", "node", "parent_scope"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()));
|
||||||
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard);
|
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard);
|
||||||
|
|
||||||
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class.
|
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class.
|
||||||
|
|
|
@ -36,6 +36,13 @@ private:
|
||||||
// and only the values can be different in those variables.
|
// and only the values can be different in those variables.
|
||||||
Ref<BlackboardPlan> base;
|
Ref<BlackboardPlan> base;
|
||||||
|
|
||||||
|
// Mapping between variables in this plan and their parent scope names.
|
||||||
|
// Used for linking variables to their parent scope counterparts upon Blackboard creation/population.
|
||||||
|
HashMap<StringName, StringName> parent_scope_mapping;
|
||||||
|
// Fetcher function for the parent scope plan. Funtion should return a Ref<BlackboardPlan>.
|
||||||
|
// Used in the inspector. When set, mapping feature becomes available.
|
||||||
|
Callable parent_scope_plan_provider;
|
||||||
|
|
||||||
// If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population).
|
// If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population).
|
||||||
bool prefetch_nodepath_vars = true;
|
bool prefetch_nodepath_vars = true;
|
||||||
|
|
||||||
|
@ -52,6 +59,12 @@ public:
|
||||||
void set_base_plan(const Ref<BlackboardPlan> &p_base);
|
void set_base_plan(const Ref<BlackboardPlan> &p_base);
|
||||||
Ref<BlackboardPlan> get_base_plan() const { return base; }
|
Ref<BlackboardPlan> get_base_plan() const { return base; }
|
||||||
|
|
||||||
|
void set_parent_scope_plan_provider(const Callable &p_parent_scope_plan_provider);
|
||||||
|
Callable get_parent_scope_plan_provider() const { return parent_scope_plan_provider; }
|
||||||
|
|
||||||
|
bool is_mapping_enabled() const { return parent_scope_plan_provider.is_valid() && (parent_scope_plan_provider.call() != Ref<BlackboardPlan>()); }
|
||||||
|
bool has_mapping(const StringName &p_name) const;
|
||||||
|
|
||||||
void set_prefetch_nodepath_vars(bool p_enable);
|
void set_prefetch_nodepath_vars(bool p_enable);
|
||||||
bool is_prefetching_nodepath_vars() const;
|
bool is_prefetching_nodepath_vars() const;
|
||||||
|
|
||||||
|
@ -72,7 +85,7 @@ public:
|
||||||
void sync_with_base_plan();
|
void sync_with_base_plan();
|
||||||
_FORCE_INLINE_ bool is_derived() const { return base.is_valid(); }
|
_FORCE_INLINE_ bool is_derived() const { return base.is_valid(); }
|
||||||
|
|
||||||
Ref<Blackboard> create_blackboard(Node *p_agent);
|
Ref<Blackboard> create_blackboard(Node *p_agent, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>());
|
||||||
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node);
|
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node);
|
||||||
|
|
||||||
BlackboardPlan();
|
BlackboardPlan();
|
||||||
|
|
|
@ -52,7 +52,13 @@ void BehaviorTree::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BehaviorTree::set_root_task(const Ref<BTTask> &p_value) {
|
void BehaviorTree::set_root_task(const Ref<BTTask> &p_value) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
_unset_editor_behavior_tree_hint();
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
root_task = p_value;
|
root_task = p_value;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
_set_editor_behavior_tree_hint();
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +91,22 @@ void BehaviorTree::_plan_changed() {
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
|
void BehaviorTree::_set_editor_behavior_tree_hint() {
|
||||||
|
if (root_task.is_valid()) {
|
||||||
|
root_task->data.behavior_tree_id = this->get_instance_id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BehaviorTree::_unset_editor_behavior_tree_hint() {
|
||||||
|
if (root_task.is_valid()) {
|
||||||
|
root_task->data.behavior_tree_id = ObjectID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
void BehaviorTree::_bind_methods() {
|
void BehaviorTree::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_description", "description"), &BehaviorTree::set_description);
|
ClassDB::bind_method(D_METHOD("set_description", "description"), &BehaviorTree::set_description);
|
||||||
ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description);
|
ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description);
|
||||||
|
|
|
@ -34,6 +34,11 @@ private:
|
||||||
|
|
||||||
void _plan_changed();
|
void _plan_changed();
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
void _set_editor_behavior_tree_hint();
|
||||||
|
void _unset_editor_behavior_tree_hint();
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ void BTState::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
p_tree->connect(LW_NAME(plan_changed), callable_mp(this, &BTState::_update_blackboard_plan));
|
p_tree->connect(LW_NAME(plan_changed), callable_mp(this, &BTState::_update_blackboard_plan));
|
||||||
}
|
}
|
||||||
behavior_tree = p_tree;
|
behavior_tree = p_tree;
|
||||||
_update_blackboard_plan();
|
|
||||||
} else {
|
} else {
|
||||||
behavior_tree = p_tree;
|
behavior_tree = p_tree;
|
||||||
}
|
}
|
||||||
|
_update_blackboard_plan();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTState::_update_blackboard_plan() {
|
void BTState::_update_blackboard_plan() {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "../../blackboard/blackboard.h"
|
#include "../../blackboard/blackboard.h"
|
||||||
#include "../../util/limbo_string_names.h"
|
#include "../../util/limbo_string_names.h"
|
||||||
#include "../../util/limbo_utility.h"
|
#include "../../util/limbo_utility.h"
|
||||||
|
#include "../behavior_tree.h"
|
||||||
#include "bt_comment.h"
|
#include "bt_comment.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
|
@ -376,6 +377,22 @@ void BTTask::print_tree(int p_initial_tabs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
|
Ref<BehaviorTree> BTTask::editor_get_behavior_tree() {
|
||||||
|
BTTask *task = this;
|
||||||
|
while (task->data.behavior_tree_id.is_null() && task->get_parent().is_valid()) {
|
||||||
|
task = task->data.parent;
|
||||||
|
}
|
||||||
|
return Object::cast_to<BehaviorTree>(ObjectDB::get_instance(task->data.behavior_tree_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTTask::editor_set_behavior_tree(const Ref<BehaviorTree> &p_bt) {
|
||||||
|
data.behavior_tree_id = p_bt->get_instance_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
void BTTask::_bind_methods() {
|
void BTTask::_bind_methods() {
|
||||||
// Public Methods.
|
// Public Methods.
|
||||||
ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root);
|
ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root);
|
||||||
|
@ -397,6 +414,9 @@ void BTTask::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("print_tree", "initial_tabs"), &BTTask::print_tree, Variant(0));
|
ClassDB::bind_method(D_METHOD("print_tree", "initial_tabs"), &BTTask::print_tree, Variant(0));
|
||||||
ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name);
|
ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name);
|
||||||
ClassDB::bind_method(D_METHOD("abort"), &BTTask::abort);
|
ClassDB::bind_method(D_METHOD("abort"), &BTTask::abort);
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
ClassDB::bind_method(D_METHOD("editor_get_behavior_tree"), &BTTask::editor_get_behavior_tree);
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
// Properties, setters and getters.
|
// Properties, setters and getters.
|
||||||
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
|
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
class BehaviorTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for BTTask.
|
* Base class for BTTask.
|
||||||
* Note: In order to properly return Status in the _tick virtual method (GDVIRTUAL1R...)
|
* Note: In order to properly return Status in the _tick virtual method (GDVIRTUAL1R...)
|
||||||
|
@ -82,6 +84,9 @@ private:
|
||||||
Status status = FRESH;
|
Status status = FRESH;
|
||||||
double elapsed = 0.0;
|
double elapsed = 0.0;
|
||||||
bool display_collapsed = false;
|
bool display_collapsed = false;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
ObjectID behavior_tree_id;
|
||||||
|
#endif
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
Array _get_children() const;
|
Array _get_children() const;
|
||||||
|
@ -162,6 +167,11 @@ public:
|
||||||
|
|
||||||
void print_tree(int p_initial_tabs = 0);
|
void print_tree(int p_initial_tabs = 0);
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
Ref<BehaviorTree> editor_get_behavior_tree();
|
||||||
|
void editor_set_behavior_tree(const Ref<BehaviorTree> &p_bt);
|
||||||
|
#endif
|
||||||
|
|
||||||
BTTask();
|
BTTask();
|
||||||
~BTTask();
|
~BTTask();
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,28 +11,45 @@
|
||||||
|
|
||||||
#include "bt_new_scope.h"
|
#include "bt_new_scope.h"
|
||||||
|
|
||||||
|
#include "../../behavior_tree.h"
|
||||||
|
|
||||||
void BTNewScope::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
void BTNewScope::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
||||||
blackboard_plan = p_plan;
|
blackboard_plan = p_plan;
|
||||||
if (blackboard_plan.is_null()) {
|
if (blackboard_plan.is_null()) {
|
||||||
blackboard_plan.instantiate();
|
blackboard_plan.instantiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_blackboard_plan();
|
_update_blackboard_plan();
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
callable_mp(this, &BTNewScope::_set_parent_scope_plan_from_bt).call_deferred();
|
||||||
|
}
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
void BTNewScope::_set_parent_scope_plan_from_bt() {
|
||||||
|
ERR_FAIL_NULL(get_blackboard_plan());
|
||||||
|
Ref<BehaviorTree> bt = get_root()->editor_get_behavior_tree();
|
||||||
|
ERR_FAIL_NULL(bt);
|
||||||
|
get_blackboard_plan()->set_parent_scope_plan_provider(callable_mp(bt.ptr(), &BehaviorTree::get_blackboard_plan));
|
||||||
|
}
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
||||||
ERR_FAIL_COND(p_agent == nullptr);
|
ERR_FAIL_COND(p_agent == nullptr);
|
||||||
ERR_FAIL_COND(p_blackboard == nullptr);
|
ERR_FAIL_COND(p_blackboard == nullptr);
|
||||||
|
|
||||||
Ref<Blackboard> bb;
|
Ref<Blackboard> bb;
|
||||||
if (blackboard_plan.is_valid()) {
|
if (blackboard_plan.is_valid()) {
|
||||||
bb = blackboard_plan->create_blackboard(p_agent);
|
bb = blackboard_plan->create_blackboard(p_agent, p_blackboard);
|
||||||
} else {
|
} else {
|
||||||
bb = Ref<Blackboard>(memnew(Blackboard));
|
bb = Ref<Blackboard>(memnew(Blackboard));
|
||||||
}
|
|
||||||
|
|
||||||
bb->set_parent(p_blackboard);
|
bb->set_parent(p_blackboard);
|
||||||
|
}
|
||||||
BTDecorator::initialize(p_agent, bb, p_scene_root);
|
BTDecorator::initialize(p_agent, bb, p_scene_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ class BTNewScope : public BTDecorator {
|
||||||
private:
|
private:
|
||||||
Ref<BlackboardPlan> blackboard_plan;
|
Ref<BlackboardPlan> blackboard_plan;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
void _set_parent_scope_plan_from_bt();
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,20 @@ Methods
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`Blackboard<class_Blackboard>` | :ref:`create_blackboard<class_BlackboardPlan_method_create_blackboard>` **(** Node node **)** |
|
| :ref:`Blackboard<class_Blackboard>` | :ref:`create_blackboard<class_BlackboardPlan_method_create_blackboard>` **(** Node node, :ref:`Blackboard<class_Blackboard>` parent_scope=null **)** |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`get_base_plan<class_BlackboardPlan_method_get_base_plan>` **(** **)** |const| |
|
| :ref:`BlackboardPlan<class_BlackboardPlan>` | :ref:`get_base_plan<class_BlackboardPlan_method_get_base_plan>` **(** **)** |const| |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| Callable | :ref:`get_parent_scope_plan_provider<class_BlackboardPlan_method_get_parent_scope_plan_provider>` **(** **)** |const| |
|
||||||
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| bool | :ref:`is_derived<class_BlackboardPlan_method_is_derived>` **(** **)** |const| |
|
| bool | :ref:`is_derived<class_BlackboardPlan_method_is_derived>` **(** **)** |const| |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`populate_blackboard<class_BlackboardPlan_method_populate_blackboard>` **(** :ref:`Blackboard<class_Blackboard>` blackboard, bool overwrite, Node node **)** |
|
| void | :ref:`populate_blackboard<class_BlackboardPlan_method_populate_blackboard>` **(** :ref:`Blackboard<class_Blackboard>` blackboard, bool overwrite, Node node **)** |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`set_base_plan<class_BlackboardPlan_method_set_base_plan>` **(** :ref:`BlackboardPlan<class_BlackboardPlan>` blackboard_plan **)** |
|
| void | :ref:`set_base_plan<class_BlackboardPlan_method_set_base_plan>` **(** :ref:`BlackboardPlan<class_BlackboardPlan>` blackboard_plan **)** |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| void | :ref:`set_parent_scope_plan_provider<class_BlackboardPlan_method_set_parent_scope_plan_provider>` **(** Callable callable **)** |
|
||||||
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`sync_with_base_plan<class_BlackboardPlan_method_sync_with_base_plan>` **(** **)** |
|
| void | :ref:`sync_with_base_plan<class_BlackboardPlan_method_sync_with_base_plan>` **(** **)** |
|
||||||
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
@ -83,7 +87,7 @@ Method Descriptions
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
:ref:`Blackboard<class_Blackboard>` **create_blackboard** **(** Node node **)**
|
:ref:`Blackboard<class_Blackboard>` **create_blackboard** **(** Node node, :ref:`Blackboard<class_Blackboard>` parent_scope=null **)**
|
||||||
|
|
||||||
Constructs a new instance of a :ref:`Blackboard<class_Blackboard>` using this plan. If ``NodePath`` prefetching is enabled, ``node`` will be used to retrieve node instances for ``NodePath`` variables and substitute their values.
|
Constructs a new instance of a :ref:`Blackboard<class_Blackboard>` using this plan. If ``NodePath`` prefetching is enabled, ``node`` will be used to retrieve node instances for ``NodePath`` variables and substitute their values.
|
||||||
|
|
||||||
|
@ -103,6 +107,18 @@ Returns the base plan. See :ref:`is_derived<class_BlackboardPlan_method_is_deriv
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
.. _class_BlackboardPlan_method_get_parent_scope_plan_provider:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
Callable **get_parent_scope_plan_provider** **(** **)** |const|
|
||||||
|
|
||||||
|
Returns the parent scope plan provider - a callable that returns a **BlackboardPlan**.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BlackboardPlan_method_is_derived:
|
.. _class_BlackboardPlan_method_is_derived:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
@ -141,6 +157,18 @@ Use with caution, as it will remove variables not present in the base plan. Only
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
.. _class_BlackboardPlan_method_set_parent_scope_plan_provider:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
void **set_parent_scope_plan_provider** **(** Callable callable **)**
|
||||||
|
|
||||||
|
Sets the parent scope plan provider - a callable that returns a **BlackboardPlan**. Used to provide hints in the inspector. When set, mapping feature becomes available.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BlackboardPlan_method_sync_with_base_plan:
|
.. _class_BlackboardPlan_method_sync_with_base_plan:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
|
@ -59,59 +59,61 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`_enter<class_BTTask_private_method__enter>` **(** **)** |virtual| |
|
| void | :ref:`_enter<class_BTTask_private_method__enter>` **(** **)** |virtual| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`_exit<class_BTTask_private_method__exit>` **(** **)** |virtual| |
|
| void | :ref:`_exit<class_BTTask_private_method__exit>` **(** **)** |virtual| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| String | :ref:`_generate_name<class_BTTask_private_method__generate_name>` **(** **)** |virtual| |const| |
|
| String | :ref:`_generate_name<class_BTTask_private_method__generate_name>` **(** **)** |virtual| |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| PackedStringArray | :ref:`_get_configuration_warnings<class_BTTask_private_method__get_configuration_warnings>` **(** **)** |virtual| |const| |
|
| PackedStringArray | :ref:`_get_configuration_warnings<class_BTTask_private_method__get_configuration_warnings>` **(** **)** |virtual| |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`_setup<class_BTTask_private_method__setup>` **(** **)** |virtual| |
|
| void | :ref:`_setup<class_BTTask_private_method__setup>` **(** **)** |virtual| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`_tick<class_BTTask_private_method__tick>` **(** float delta **)** |virtual| |
|
| :ref:`Status<enum_BT_Status>` | :ref:`_tick<class_BTTask_private_method__tick>` **(** float delta **)** |virtual| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`abort<class_BTTask_method_abort>` **(** **)** |
|
| void | :ref:`abort<class_BTTask_method_abort>` **(** **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`add_child<class_BTTask_method_add_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
|
| void | :ref:`add_child<class_BTTask_method_add_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`add_child_at_index<class_BTTask_method_add_child_at_index>` **(** :ref:`BTTask<class_BTTask>` task, int idx **)** |
|
| void | :ref:`add_child_at_index<class_BTTask_method_add_child_at_index>` **(** :ref:`BTTask<class_BTTask>` task, int idx **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`clone<class_BTTask_method_clone>` **(** **)** |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`clone<class_BTTask_method_clone>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`editor_get_behavior_tree<class_BTTask_method_editor_get_behavior_tree>` **(** **)** |
|
||||||
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`execute<class_BTTask_method_execute>` **(** float delta **)** |
|
| :ref:`Status<enum_BT_Status>` | :ref:`execute<class_BTTask_method_execute>` **(** float delta **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_child<class_BTTask_method_get_child>` **(** int idx **)** |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_child<class_BTTask_method_get_child>` **(** int idx **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| int | :ref:`get_child_count<class_BTTask_method_get_child_count>` **(** **)** |const| |
|
| int | :ref:`get_child_count<class_BTTask_method_get_child_count>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| int | :ref:`get_child_count_excluding_comments<class_BTTask_method_get_child_count_excluding_comments>` **(** **)** |const| |
|
| int | :ref:`get_child_count_excluding_comments<class_BTTask_method_get_child_count_excluding_comments>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| int | :ref:`get_index<class_BTTask_method_get_index>` **(** **)** |const| |
|
| int | :ref:`get_index<class_BTTask_method_get_index>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_parent<class_BTTask_method_get_parent>` **(** **)** |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_parent<class_BTTask_method_get_parent>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_root<class_BTTask_method_get_root>` **(** **)** |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_root<class_BTTask_method_get_root>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| String | :ref:`get_task_name<class_BTTask_method_get_task_name>` **(** **)** |
|
| String | :ref:`get_task_name<class_BTTask_method_get_task_name>` **(** **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| bool | :ref:`has_child<class_BTTask_method_has_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
|
| bool | :ref:`has_child<class_BTTask_method_has_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`initialize<class_BTTask_method_initialize>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** |
|
| void | :ref:`initialize<class_BTTask_method_initialize>` **(** Node agent, :ref:`Blackboard<class_Blackboard>` blackboard, Node scene_root **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| bool | :ref:`is_descendant_of<class_BTTask_method_is_descendant_of>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
|
| bool | :ref:`is_descendant_of<class_BTTask_method_is_descendant_of>` **(** :ref:`BTTask<class_BTTask>` task **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| bool | :ref:`is_root<class_BTTask_method_is_root>` **(** **)** |const| |
|
| bool | :ref:`is_root<class_BTTask_method_is_root>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`next_sibling<class_BTTask_method_next_sibling>` **(** **)** |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`next_sibling<class_BTTask_method_next_sibling>` **(** **)** |const| |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`print_tree<class_BTTask_method_print_tree>` **(** int initial_tabs=0 **)** |
|
| void | :ref:`print_tree<class_BTTask_method_print_tree>` **(** int initial_tabs=0 **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`remove_child<class_BTTask_method_remove_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
|
| void | :ref:`remove_child<class_BTTask_method_remove_child>` **(** :ref:`BTTask<class_BTTask>` task **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| void | :ref:`remove_child_at_index<class_BTTask_method_remove_child_at_index>` **(** int idx **)** |
|
| void | :ref:`remove_child_at_index<class_BTTask_method_remove_child_at_index>` **(** int idx **)** |
|
||||||
+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -366,6 +368,18 @@ Duplicates the task and its children, copying the exported members. Sub-resource
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
.. _class_BTTask_method_editor_get_behavior_tree:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
:ref:`BehaviorTree<class_BehaviorTree>` **editor_get_behavior_tree** **(** **)**
|
||||||
|
|
||||||
|
Returns the behavior tree that owns this task. This is only available in the editor.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
.. _class_BTTask_method_execute:
|
.. _class_BTTask_method_execute:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
|
@ -79,6 +79,12 @@
|
||||||
Duplicates the task and its children, copying the exported members. Sub-resources are shared for efficiency, except for [BBParam] subtypes, which are always copied. Used by the editor to instantiate [BehaviorTree] and copy-paste tasks.
|
Duplicates the task and its children, copying the exported members. Sub-resources are shared for efficiency, except for [BBParam] subtypes, which are always copied. Used by the editor to instantiate [BehaviorTree] and copy-paste tasks.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="editor_get_behavior_tree">
|
||||||
|
<return type="BehaviorTree" />
|
||||||
|
<description>
|
||||||
|
Returns the behavior tree that owns this task. This is only available in the editor.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="execute">
|
<method name="execute">
|
||||||
<return type="int" enum="BT.Status" />
|
<return type="int" enum="BT.Status" />
|
||||||
<param index="0" name="delta" type="float" />
|
<param index="0" name="delta" type="float" />
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<method name="create_blackboard">
|
<method name="create_blackboard">
|
||||||
<return type="Blackboard" />
|
<return type="Blackboard" />
|
||||||
<param index="0" name="node" type="Node" />
|
<param index="0" name="node" type="Node" />
|
||||||
|
<param index="1" name="parent_scope" type="Blackboard" default="null" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a new instance of a [Blackboard] using this plan. If [NodePath] prefetching is enabled, [param node] will be used to retrieve node instances for [NodePath] variables and substitute their values.
|
Constructs a new instance of a [Blackboard] using this plan. If [NodePath] prefetching is enabled, [param node] will be used to retrieve node instances for [NodePath] variables and substitute their values.
|
||||||
</description>
|
</description>
|
||||||
|
@ -21,6 +22,12 @@
|
||||||
Returns the base plan. See [method is_derived].
|
Returns the base plan. See [method is_derived].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_parent_scope_plan_provider" qualifiers="const">
|
||||||
|
<return type="Callable" />
|
||||||
|
<description>
|
||||||
|
Returns the parent scope plan provider - a callable that returns a [BlackboardPlan].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="is_derived" qualifiers="const">
|
<method name="is_derived" qualifiers="const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<description>
|
<description>
|
||||||
|
@ -44,6 +51,13 @@
|
||||||
Use with caution, as it will remove variables not present in the base plan. Only use this for custom tooling.
|
Use with caution, as it will remove variables not present in the base plan. Only use this for custom tooling.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="set_parent_scope_plan_provider">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="callable" type="Callable" />
|
||||||
|
<description>
|
||||||
|
Sets the parent scope plan provider - a callable that returns a [BlackboardPlan]. Used to provide hints in the inspector. When set, mapping feature becomes available.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="sync_with_base_plan">
|
<method name="sync_with_base_plan">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -49,14 +49,18 @@ void BlackboardPlanEditor::_add_var() {
|
||||||
ERR_FAIL_NULL(plan);
|
ERR_FAIL_NULL(plan);
|
||||||
|
|
||||||
int suffix = 1;
|
int suffix = 1;
|
||||||
StringName var_name = default_var_name;
|
StringName var_name = default_var_name == StringName() ? "var" : default_var_name;
|
||||||
while (plan->has_var(var_name)) {
|
while (plan->has_var(var_name)) {
|
||||||
suffix += 1;
|
suffix += 1;
|
||||||
var_name = String(default_var_name) + itos(suffix);
|
var_name = String(default_var_name) + itos(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
BBVariable var(Variant::Type::FLOAT);
|
BBVariable var(default_type, default_hint, default_hint_string);
|
||||||
|
if (default_value.get_type() == default_type) {
|
||||||
|
var.set_value(default_value);
|
||||||
|
}
|
||||||
plan->add_var(var_name, var);
|
plan->add_var(var_name, var);
|
||||||
|
reset_defaults();
|
||||||
_refresh();
|
_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,10 +132,19 @@ void BlackboardPlanEditor::edit_plan(const Ref<BlackboardPlan> &p_plan) {
|
||||||
_refresh();
|
_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackboardPlanEditor::set_next_var_name(const StringName &p_name) {
|
void BlackboardPlanEditor::set_defaults(const StringName &p_var_name, Variant::Type p_type, PropertyHint p_hint, String p_hint_string, Variant p_value) {
|
||||||
if (String(p_name).is_valid_identifier()) {
|
default_var_name = p_var_name;
|
||||||
default_var_name = p_name;
|
default_type = p_type;
|
||||||
|
default_hint = p_hint;
|
||||||
|
default_hint_string = p_hint_string;
|
||||||
|
default_value = p_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlackboardPlanEditor::reset_defaults() {
|
||||||
|
default_var_name = "var";
|
||||||
|
default_type = Variant::FLOAT;
|
||||||
|
default_hint = PROPERTY_HINT_NONE;
|
||||||
|
default_hint_string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackboardPlanEditor::_show_button_popup(Button *p_button, PopupMenu *p_popup, int p_index) {
|
void BlackboardPlanEditor::_show_button_popup(Button *p_button, PopupMenu *p_popup, int p_index) {
|
||||||
|
@ -234,7 +247,7 @@ void BlackboardPlanEditor::_drag_button_gui_input(const Ref<InputEvent> &p_event
|
||||||
void BlackboardPlanEditor::_visibility_changed() {
|
void BlackboardPlanEditor::_visibility_changed() {
|
||||||
if (!is_visible() && plan.is_valid()) {
|
if (!is_visible() && plan.is_valid()) {
|
||||||
plan->notify_property_list_changed();
|
plan->notify_property_list_changed();
|
||||||
default_var_name = "var";
|
reset_defaults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +381,7 @@ void BlackboardPlanEditor::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackboardPlanEditor::BlackboardPlanEditor() {
|
BlackboardPlanEditor::BlackboardPlanEditor() {
|
||||||
default_var_name = "var";
|
reset_defaults();
|
||||||
|
|
||||||
set_title(TTR("Manage Blackboard Plan"));
|
set_title(TTR("Manage Blackboard Plan"));
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,10 @@ private:
|
||||||
|
|
||||||
Ref<BlackboardPlan> plan;
|
Ref<BlackboardPlan> plan;
|
||||||
StringName default_var_name;
|
StringName default_var_name;
|
||||||
|
Variant::Type default_type = Variant::NIL;
|
||||||
|
PropertyHint default_hint = PROPERTY_HINT_NONE;
|
||||||
|
String default_hint_string;
|
||||||
|
Variant default_value;
|
||||||
|
|
||||||
VBoxContainer *rows_vbox;
|
VBoxContainer *rows_vbox;
|
||||||
Button *add_var_tool;
|
Button *add_var_tool;
|
||||||
|
@ -99,7 +103,8 @@ public:
|
||||||
_FORCE_INLINE_ static BlackboardPlanEditor *get_singleton() { return singleton; }
|
_FORCE_INLINE_ static BlackboardPlanEditor *get_singleton() { return singleton; }
|
||||||
|
|
||||||
void edit_plan(const Ref<BlackboardPlan> &p_plan);
|
void edit_plan(const Ref<BlackboardPlan> &p_plan);
|
||||||
void set_next_var_name(const StringName &p_name);
|
void set_defaults(const StringName &p_name, Variant::Type p_type = Variant::FLOAT, PropertyHint p_hint = PROPERTY_HINT_NONE, String p_hint_string = "", Variant p_value = Variant());
|
||||||
|
void reset_defaults();
|
||||||
|
|
||||||
BlackboardPlanEditor();
|
BlackboardPlanEditor();
|
||||||
};
|
};
|
||||||
|
|
|
@ -283,6 +283,7 @@ void EditorPropertyBBParam::update_property() {
|
||||||
if (param->get_value_source() == BBParam::BLACKBOARD_VAR) {
|
if (param->get_value_source() == BBParam::BLACKBOARD_VAR) {
|
||||||
_remove_value_editor();
|
_remove_value_editor();
|
||||||
variable_editor->set_object_and_property(param.ptr(), SNAME("variable"));
|
variable_editor->set_object_and_property(param.ptr(), SNAME("variable"));
|
||||||
|
variable_editor->setup(plan, false, param->get_variable_expected_type());
|
||||||
variable_editor->update_property();
|
variable_editor->update_property();
|
||||||
variable_editor->show();
|
variable_editor->show();
|
||||||
bottom_container->hide();
|
bottom_container->hide();
|
||||||
|
@ -300,7 +301,7 @@ void EditorPropertyBBParam::update_property() {
|
||||||
void EditorPropertyBBParam::setup(PropertyHint p_hint, const String &p_hint_text, const Ref<BlackboardPlan> &p_plan) {
|
void EditorPropertyBBParam::setup(PropertyHint p_hint, const String &p_hint_text, const Ref<BlackboardPlan> &p_plan) {
|
||||||
param_type = p_hint_text;
|
param_type = p_hint_text;
|
||||||
property_hint = p_hint;
|
property_hint = p_hint;
|
||||||
variable_editor->setup(p_plan);
|
plan = p_plan;
|
||||||
variable_editor->set_name_split_ratio(0.0);
|
variable_editor->set_name_split_ratio(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ private:
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
|
|
||||||
|
Ref<BlackboardPlan> plan;
|
||||||
StringName param_type;
|
StringName param_type;
|
||||||
PropertyHint property_hint = PROPERTY_HINT_NONE;
|
PropertyHint property_hint = PROPERTY_HINT_NONE;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include <godot_cpp/classes/h_box_container.hpp>
|
#include <godot_cpp/classes/h_box_container.hpp>
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
int EditorPropertyVariableName::last_caret_column = 0;
|
||||||
|
|
||||||
//***** EditorPropertyVariableName
|
//***** EditorPropertyVariableName
|
||||||
|
|
||||||
void EditorPropertyVariableName::_show_variables_popup() {
|
void EditorPropertyVariableName::_show_variables_popup() {
|
||||||
|
@ -55,14 +57,26 @@ void EditorPropertyVariableName::_show_variables_popup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyVariableName::_name_changed(const String &p_new_name) {
|
void EditorPropertyVariableName::_name_changed(const String &p_new_name) {
|
||||||
|
if (updating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
emit_changed(get_edited_property(), p_new_name);
|
emit_changed(get_edited_property(), p_new_name);
|
||||||
|
last_caret_column = name_edit->get_caret_column();
|
||||||
_update_status();
|
_update_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorPropertyVariableName::_name_submitted() {
|
||||||
|
_name_changed(name_edit->get_text());
|
||||||
|
if (name_edit->has_focus()) {
|
||||||
|
name_edit->release_focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EditorPropertyVariableName::_variable_selected(int p_id) {
|
void EditorPropertyVariableName::_variable_selected(int p_id) {
|
||||||
String var_name = plan->get_var_by_index(p_id).first;
|
String var_name = plan->get_var_by_index(p_id).first;
|
||||||
name_edit->set_text(var_name);
|
name_edit->set_text(var_name);
|
||||||
_name_changed(var_name);
|
_name_submitted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyVariableName::_update_status() {
|
void EditorPropertyVariableName::_update_status() {
|
||||||
|
@ -71,9 +85,21 @@ void EditorPropertyVariableName::_update_status() {
|
||||||
if (plan.is_null()) {
|
if (plan.is_null()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (plan->has_var(name_edit->get_text())) {
|
String var_name = name_edit->get_text();
|
||||||
|
if (var_name.is_empty() && allow_empty) {
|
||||||
|
BUTTON_SET_ICON(status_btn, theme_cache.var_empty_icon);
|
||||||
|
status_btn->set_tooltip_text(TTR("Variable name not specified.\nClick to open the blackboard plan."));
|
||||||
|
} else if (plan->has_var(var_name)) {
|
||||||
|
if (expected_type == Variant::NIL || plan->get_var(var_name).get_type() == expected_type) {
|
||||||
BUTTON_SET_ICON(status_btn, theme_cache.var_exists_icon);
|
BUTTON_SET_ICON(status_btn, theme_cache.var_exists_icon);
|
||||||
status_btn->set_tooltip_text(TTR("This variable is present in the blackboard plan.\nClick to open the blackboard plan."));
|
status_btn->set_tooltip_text(TTR("This variable is present in the blackboard plan.\nClick to open the blackboard plan."));
|
||||||
|
} else {
|
||||||
|
BUTTON_SET_ICON(status_btn, theme_cache.var_error_icon);
|
||||||
|
status_btn->set_tooltip_text(TTR(vformat(
|
||||||
|
"The %s variable in the blackboard plan should be of type %s.\nClick to open the blackboard plan.",
|
||||||
|
LimboUtility::get_singleton()->decorate_var(var_name),
|
||||||
|
Variant::get_type_name(expected_type))));
|
||||||
|
}
|
||||||
} else if (name_edit->get_text().begins_with("_")) {
|
} else if (name_edit->get_text().begins_with("_")) {
|
||||||
BUTTON_SET_ICON(status_btn, theme_cache.var_private_icon);
|
BUTTON_SET_ICON(status_btn, theme_cache.var_private_icon);
|
||||||
status_btn->set_tooltip_text(TTR("This variable is private and is not included in the blackboard plan.\nClick to open the blackboard plan."));
|
status_btn->set_tooltip_text(TTR("This variable is private and is not included in the blackboard plan.\nClick to open the blackboard plan."));
|
||||||
|
@ -86,7 +112,9 @@ void EditorPropertyVariableName::_update_status() {
|
||||||
void EditorPropertyVariableName::_status_pressed() {
|
void EditorPropertyVariableName::_status_pressed() {
|
||||||
ERR_FAIL_NULL(plan);
|
ERR_FAIL_NULL(plan);
|
||||||
if (!plan->has_var(name_edit->get_text())) {
|
if (!plan->has_var(name_edit->get_text())) {
|
||||||
BlackboardPlanEditor::get_singleton()->set_next_var_name(name_edit->get_text());
|
BlackboardPlanEditor::get_singleton()->set_defaults(name_edit->get_text(),
|
||||||
|
expected_type == Variant::NIL ? Variant::FLOAT : expected_type,
|
||||||
|
default_hint, default_hint_string, default_value);
|
||||||
}
|
}
|
||||||
BlackboardPlanEditor::get_singleton()->edit_plan(plan);
|
BlackboardPlanEditor::get_singleton()->edit_plan(plan);
|
||||||
BlackboardPlanEditor::get_singleton()->popup_centered();
|
BlackboardPlanEditor::get_singleton()->popup_centered();
|
||||||
|
@ -110,17 +138,27 @@ void EditorPropertyVariableName::update_property() {
|
||||||
void EditorPropertyVariableName::_update_property() {
|
void EditorPropertyVariableName::_update_property() {
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
String s = get_edited_object()->get(get_edited_property());
|
String s = get_edited_object()->get(get_edited_property());
|
||||||
|
updating = true;
|
||||||
if (name_edit->get_text() != s) {
|
if (name_edit->get_text() != s) {
|
||||||
int caret = name_edit->get_caret_column();
|
int caret = name_edit->get_caret_column();
|
||||||
|
if (caret == 0) {
|
||||||
|
caret = last_caret_column;
|
||||||
|
}
|
||||||
name_edit->set_text(s);
|
name_edit->set_text(s);
|
||||||
name_edit->set_caret_column(caret);
|
name_edit->set_caret_column(caret);
|
||||||
}
|
}
|
||||||
name_edit->set_editable(!is_read_only());
|
name_edit->set_editable(!is_read_only());
|
||||||
_update_status();
|
_update_status();
|
||||||
|
updating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyVariableName::setup(const Ref<BlackboardPlan> &p_plan) {
|
void EditorPropertyVariableName::setup(const Ref<BlackboardPlan> &p_plan, bool p_allow_empty, Variant::Type p_type, PropertyHint p_hint, String p_hint_string, Variant p_default_value) {
|
||||||
plan = p_plan;
|
plan = p_plan;
|
||||||
|
allow_empty = p_allow_empty;
|
||||||
|
expected_type = p_type;
|
||||||
|
default_hint = p_hint;
|
||||||
|
default_hint_string = p_hint_string;
|
||||||
|
default_value = p_default_value;
|
||||||
_update_status();
|
_update_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +166,8 @@ void EditorPropertyVariableName::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
name_edit->connect(LW_NAME(text_changed), callable_mp(this, &EditorPropertyVariableName::_name_changed));
|
name_edit->connect(LW_NAME(text_changed), callable_mp(this, &EditorPropertyVariableName::_name_changed));
|
||||||
|
name_edit->connect(LW_NAME(text_submitted), callable_mp(this, &EditorPropertyVariableName::_name_submitted).unbind(1));
|
||||||
|
name_edit->connect(LW_NAME(focus_exited), callable_mp(this, &EditorPropertyVariableName::_name_submitted));
|
||||||
variables_popup->connect(LW_NAME(id_pressed), callable_mp(this, &EditorPropertyVariableName::_variable_selected));
|
variables_popup->connect(LW_NAME(id_pressed), callable_mp(this, &EditorPropertyVariableName::_variable_selected));
|
||||||
drop_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorPropertyVariableName::_show_variables_popup));
|
drop_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorPropertyVariableName::_show_variables_popup));
|
||||||
status_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorPropertyVariableName::_status_pressed));
|
status_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorPropertyVariableName::_status_pressed));
|
||||||
|
@ -148,6 +188,8 @@ void EditorPropertyVariableName::_notification(int p_what) {
|
||||||
theme_cache.var_exists_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarExists));
|
theme_cache.var_exists_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarExists));
|
||||||
theme_cache.var_not_found_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarNotFound));
|
theme_cache.var_not_found_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarNotFound));
|
||||||
theme_cache.var_private_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarPrivate));
|
theme_cache.var_private_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarPrivate));
|
||||||
|
theme_cache.var_empty_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarEmpty));
|
||||||
|
theme_cache.var_error_icon = LimboUtility::get_singleton()->get_task_icon(LW_NAME(LimboVarError));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +234,10 @@ bool EditorInspectorPluginVariableName::_can_handle(Object *p_object) const {
|
||||||
if (param.is_valid()) {
|
if (param.is_valid()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Ref<BlackboardPlan> plan = Object::cast_to<BlackboardPlan>(p_object);
|
||||||
|
if (plan.is_valid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +246,41 @@ bool EditorInspectorPluginVariableName::parse_property(Object *p_object, const V
|
||||||
#elif LIMBOAI_GDEXTENSION
|
#elif LIMBOAI_GDEXTENSION
|
||||||
bool EditorInspectorPluginVariableName::_parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) {
|
bool EditorInspectorPluginVariableName::_parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) {
|
||||||
#endif
|
#endif
|
||||||
if (!(p_type == Variant::Type::STRING_NAME || p_type == Variant::Type::STRING) || !(p_path.ends_with("_var") || p_path.ends_with("variable"))) {
|
bool is_mapping = p_path.begins_with("mapping/");
|
||||||
|
if (!(p_type == Variant::Type::STRING_NAME || p_type == Variant::Type::STRING) || !(is_mapping || p_path.ends_with("_var") || p_path.ends_with("variable"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<BlackboardPlan> plan;
|
||||||
|
Variant::Type expected_type = Variant::NIL;
|
||||||
|
PropertyHint default_hint = PROPERTY_HINT_NONE;
|
||||||
|
String default_hint_string;
|
||||||
|
Variant default_value;
|
||||||
|
if (is_mapping) {
|
||||||
|
plan.reference_ptr(Object::cast_to<BlackboardPlan>(p_object));
|
||||||
|
ERR_FAIL_NULL_V(plan, false);
|
||||||
|
String var_name = p_path.trim_prefix("mapping/");
|
||||||
|
if (plan->has_var(var_name)) {
|
||||||
|
BBVariable variable = plan->get_var(var_name);
|
||||||
|
expected_type = variable.get_type();
|
||||||
|
default_hint = variable.get_hint();
|
||||||
|
default_hint_string = variable.get_hint_string();
|
||||||
|
default_value = variable.get_value();
|
||||||
|
}
|
||||||
|
if (plan->get_parent_scope_plan_provider().is_valid()) {
|
||||||
|
Ref<BlackboardPlan> parent_plan = plan->get_parent_scope_plan_provider().call();
|
||||||
|
if (parent_plan.is_valid()) {
|
||||||
|
plan = parent_plan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL_V(plan, false);
|
||||||
|
} else {
|
||||||
|
plan = editor_plan_provider.call();
|
||||||
|
}
|
||||||
|
|
||||||
EditorPropertyVariableName *ed = memnew(EditorPropertyVariableName);
|
EditorPropertyVariableName *ed = memnew(EditorPropertyVariableName);
|
||||||
ed->setup(plan_getter.call());
|
ed->setup(plan, is_mapping, expected_type, default_hint, default_hint_string, default_value);
|
||||||
add_property_editor(p_path, ed);
|
add_property_editor(p_path, ed, expected_type);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,17 +31,30 @@ using namespace godot;
|
||||||
class EditorPropertyVariableName : public EditorProperty {
|
class EditorPropertyVariableName : public EditorProperty {
|
||||||
GDCLASS(EditorPropertyVariableName, EditorProperty);
|
GDCLASS(EditorPropertyVariableName, EditorProperty);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int last_caret_column;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ThemeCache {
|
struct ThemeCache {
|
||||||
|
Ref<Texture2D> var_add_icon;
|
||||||
|
Ref<Texture2D> var_empty_icon;
|
||||||
|
Ref<Texture2D> var_error_icon;
|
||||||
Ref<Texture2D> var_exists_icon;
|
Ref<Texture2D> var_exists_icon;
|
||||||
Ref<Texture2D> var_not_found_icon;
|
Ref<Texture2D> var_not_found_icon;
|
||||||
Ref<Texture2D> var_add_icon;
|
|
||||||
Ref<Texture2D> var_private_icon;
|
Ref<Texture2D> var_private_icon;
|
||||||
};
|
};
|
||||||
ThemeCache theme_cache;
|
ThemeCache theme_cache;
|
||||||
|
|
||||||
Ref<BlackboardPlan> plan;
|
Ref<BlackboardPlan> plan;
|
||||||
|
|
||||||
|
bool allow_empty = false;
|
||||||
|
Variant::Type expected_type = Variant::NIL;
|
||||||
|
PropertyHint default_hint = PROPERTY_HINT_NONE;
|
||||||
|
String default_hint_string;
|
||||||
|
Variant default_value;
|
||||||
|
|
||||||
|
bool updating = false;
|
||||||
|
|
||||||
LineEdit *name_edit;
|
LineEdit *name_edit;
|
||||||
Button *drop_btn;
|
Button *drop_btn;
|
||||||
Button *status_btn;
|
Button *status_btn;
|
||||||
|
@ -49,6 +62,7 @@ private:
|
||||||
|
|
||||||
void _show_variables_popup();
|
void _show_variables_popup();
|
||||||
void _name_changed(const String &p_new_name);
|
void _name_changed(const String &p_new_name);
|
||||||
|
void _name_submitted();
|
||||||
void _variable_selected(int p_id);
|
void _variable_selected(int p_id);
|
||||||
void _update_status();
|
void _update_status();
|
||||||
|
|
||||||
|
@ -68,7 +82,7 @@ public:
|
||||||
virtual void _update_property() override;
|
virtual void _update_property() override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setup(const Ref<BlackboardPlan> &p_plan);
|
void setup(const Ref<BlackboardPlan> &p_plan, bool p_allow_empty, Variant::Type p_type = Variant::NIL, PropertyHint p_hint = PROPERTY_HINT_NONE, String p_hint_string = "", Variant p_default_value = Variant());
|
||||||
EditorPropertyVariableName();
|
EditorPropertyVariableName();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +90,7 @@ class EditorInspectorPluginVariableName : public EditorInspectorPlugin {
|
||||||
GDCLASS(EditorInspectorPluginVariableName, EditorInspectorPlugin);
|
GDCLASS(EditorInspectorPluginVariableName, EditorInspectorPlugin);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Callable plan_getter;
|
Callable editor_plan_provider;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods() {}
|
static void _bind_methods() {}
|
||||||
|
@ -90,7 +104,7 @@ public:
|
||||||
virtual bool _parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override;
|
virtual bool _parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void set_plan_getter(const Callable &p_getter) { plan_getter = p_getter; }
|
void set_editor_plan_provider(const Callable &p_getter) { editor_plan_provider = p_getter; }
|
||||||
|
|
||||||
EditorInspectorPluginVariableName() = default;
|
EditorInspectorPluginVariableName() = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1487,7 +1487,7 @@ void LimboAIEditorPlugin::_notification(int p_notification) {
|
||||||
add_debugger_plugin(memnew(LimboDebuggerPlugin));
|
add_debugger_plugin(memnew(LimboDebuggerPlugin));
|
||||||
add_inspector_plugin(memnew(EditorInspectorPluginBBPlan));
|
add_inspector_plugin(memnew(EditorInspectorPluginBBPlan));
|
||||||
EditorInspectorPluginVariableName *var_plugin = memnew(EditorInspectorPluginVariableName);
|
EditorInspectorPluginVariableName *var_plugin = memnew(EditorInspectorPluginVariableName);
|
||||||
var_plugin->set_plan_getter(Callable(limbo_ai_editor, "get_edited_blackboard_plan"));
|
var_plugin->set_editor_plan_provider(Callable(limbo_ai_editor, "get_edited_blackboard_plan"));
|
||||||
add_inspector_plugin(var_plugin);
|
add_inspector_plugin(var_plugin);
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
// ! Only used in the module version.
|
// ! Only used in the module version.
|
||||||
|
|
|
@ -22,12 +22,31 @@
|
||||||
|
|
||||||
void LimboState::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
void LimboState::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
|
||||||
blackboard_plan = p_plan;
|
blackboard_plan = p_plan;
|
||||||
|
|
||||||
|
if (Engine::get_singleton()->is_editor_hint() && blackboard_plan.is_valid()) {
|
||||||
|
blackboard_plan->set_parent_scope_plan_provider(callable_mp(this, &LimboState::_get_parent_scope_plan));
|
||||||
|
}
|
||||||
|
|
||||||
_update_blackboard_plan();
|
_update_blackboard_plan();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboState::_update_blackboard_plan() {
|
void LimboState::_update_blackboard_plan() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<BlackboardPlan> LimboState::_get_parent_scope_plan() const {
|
||||||
|
BlackboardPlan *parent_plan = nullptr;
|
||||||
|
const LimboState *state = this;
|
||||||
|
while (state->get_parent() && IS_CLASS(state->get_parent(), LimboState)) {
|
||||||
|
state = Object::cast_to<LimboState>(state->get_parent());
|
||||||
|
ERR_FAIL_NULL_V(state, parent_plan);
|
||||||
|
if (state->blackboard_plan.is_valid()) {
|
||||||
|
parent_plan = state->blackboard_plan.ptr();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parent_plan;
|
||||||
|
}
|
||||||
|
|
||||||
LimboState *LimboState::get_root() const {
|
LimboState *LimboState::get_root() const {
|
||||||
const Node *state = this;
|
const Node *state = this;
|
||||||
while (state->get_parent() && IS_CLASS(state->get_parent(), LimboState)) {
|
while (state->get_parent() && IS_CLASS(state->get_parent(), LimboState)) {
|
||||||
|
|
|
@ -38,6 +38,8 @@ private:
|
||||||
HashMap<StringName, Callable> handlers;
|
HashMap<StringName, Callable> handlers;
|
||||||
Callable guard_callable;
|
Callable guard_callable;
|
||||||
|
|
||||||
|
Ref<BlackboardPlan> _get_parent_scope_plan() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend LimboHSM;
|
friend LimboHSM;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path clip-rule="evenodd" d="m0 0h16v16h-16z"/></clipPath><path d="m0 0h16v16h-16z" fill="none"/><g clip-path="url(#a)"><circle cx="8" cy="8" fill="#e0e0e0" r="8"/></g></svg>
|
After Width: | Height: | Size: 380 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path clip-rule="evenodd" d="m0 0h16v16h-16z"/></clipPath><path d="m0 0h16v16h-16z" fill="none"/><g clip-path="url(#a)"><path d="m8 0c4.415 0 8 3.585 8 8s-3.585 8-8 8-8-3.585-8-8 3.585-8 8-8zm2.357 8 2.357-2.357-2.357-2.357-2.357 2.357-2.357-2.357-2.357 2.357 2.357 2.357-2.357 2.357 2.357 2.357 2.357-2.357 2.357 2.357 2.357-2.357z" fill="#fc7f7f"/></g><path d="m22.481 21.885 2.357-2.357-2.357-2.357-2.357 2.357-2.357-2.357-2.357 2.357 2.357 2.357-2.357 2.357 2.357 2.357 2.357-2.357 2.357 2.357 2.357-2.357z" fill="#8eef97" fill-rule="nonzero"/></svg>
|
After Width: | Height: | Size: 760 B |
|
@ -80,6 +80,7 @@ LimboStringNames::LimboStringNames() {
|
||||||
exited = SN("exited");
|
exited = SN("exited");
|
||||||
favorite_tasks_changed = SN("favorite_tasks_changed");
|
favorite_tasks_changed = SN("favorite_tasks_changed");
|
||||||
Favorites = SN("Favorites");
|
Favorites = SN("Favorites");
|
||||||
|
focus_exited = SN("focus_exited");
|
||||||
font = SN("font");
|
font = SN("font");
|
||||||
font_color = SN("font_color");
|
font_color = SN("font_color");
|
||||||
font_size = SN("font_size");
|
font_size = SN("font_size");
|
||||||
|
@ -100,6 +101,8 @@ LimboStringNames::LimboStringNames() {
|
||||||
LimboPercent = SN("LimboPercent");
|
LimboPercent = SN("LimboPercent");
|
||||||
LimboSelectAll = SN("LimboSelectAll");
|
LimboSelectAll = SN("LimboSelectAll");
|
||||||
LimboVarAdd = SN("LimboVarAdd");
|
LimboVarAdd = SN("LimboVarAdd");
|
||||||
|
LimboVarEmpty = SN("LimboVarEmpty");
|
||||||
|
LimboVarError = SN("LimboVarError");
|
||||||
LimboVarExists = SN("LimboVarExists");
|
LimboVarExists = SN("LimboVarExists");
|
||||||
LimboVarNotFound = SN("LimboVarNotFound");
|
LimboVarNotFound = SN("LimboVarNotFound");
|
||||||
LimboVarPrivate = SN("LimboVarPrivate");
|
LimboVarPrivate = SN("LimboVarPrivate");
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
StringName exited;
|
StringName exited;
|
||||||
StringName favorite_tasks_changed;
|
StringName favorite_tasks_changed;
|
||||||
StringName Favorites;
|
StringName Favorites;
|
||||||
|
StringName focus_exited;
|
||||||
StringName font_color;
|
StringName font_color;
|
||||||
StringName font_size;
|
StringName font_size;
|
||||||
StringName font;
|
StringName font;
|
||||||
|
@ -117,6 +118,8 @@ public:
|
||||||
StringName LimboPercent;
|
StringName LimboPercent;
|
||||||
StringName LimboSelectAll;
|
StringName LimboSelectAll;
|
||||||
StringName LimboVarAdd;
|
StringName LimboVarAdd;
|
||||||
|
StringName LimboVarEmpty;
|
||||||
|
StringName LimboVarError;
|
||||||
StringName LimboVarExists;
|
StringName LimboVarExists;
|
||||||
StringName LimboVarNotFound;
|
StringName LimboVarNotFound;
|
||||||
StringName LimboVarPrivate;
|
StringName LimboVarPrivate;
|
||||||
|
|
Loading…
Reference in New Issue