Compare commits
5 Commits
56bb91df0a
...
adff6bd08c
Author | SHA1 | Date |
---|---|---|
Serhii Snitsaruk | adff6bd08c | |
Serhii Snitsaruk | 06de52492a | |
Serhii Snitsaruk | 2c8e0d2da0 | |
Serhii Snitsaruk | ce5f012101 | |
Serhii Snitsaruk | 3bca05bc50 |
|
@ -74,7 +74,7 @@ void BTState::_exit() {
|
||||||
|
|
||||||
void BTState::_update(double p_delta) {
|
void BTState::_update(double p_delta) {
|
||||||
VCALL_ARGS(_update, p_delta);
|
VCALL_ARGS(_update, p_delta);
|
||||||
if (!active) {
|
if (!is_active()) {
|
||||||
// Bail out if a transition happened in the meantime.
|
// Bail out if a transition happened in the meantime.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,31 +118,31 @@ bool BTTask::is_displayed_collapsed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
String BTTask::get_task_name() {
|
String BTTask::get_task_name() {
|
||||||
if (data.custom_name.is_empty()) {
|
if (!data.custom_name.is_empty()) {
|
||||||
#ifdef LIMBOAI_MODULE
|
return data.custom_name;
|
||||||
if (get_script_instance() && get_script_instance()->has_method(LW_NAME(_generate_name))) {
|
|
||||||
if (unlikely(!get_script_instance()->get_script()->is_tool())) {
|
|
||||||
ERR_PRINT(vformat("BTTask: Task script should be a \"tool\" script!"));
|
|
||||||
} else {
|
|
||||||
return get_script_instance()->call(LimboStringNames::get_singleton()->_generate_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _generate_name();
|
|
||||||
#elif LIMBOAI_GDEXTENSION
|
|
||||||
Ref<Script> task_script = get_script();
|
|
||||||
if (task_script.is_valid() && task_script->is_tool()) {
|
|
||||||
Variant call_result;
|
|
||||||
VCALL_OR_NATIVE_V(_generate_name, Variant, call_result);
|
|
||||||
ERR_FAIL_COND_V(call_result.get_type() == Variant::NIL, _generate_name());
|
|
||||||
String task_name = call_result;
|
|
||||||
ERR_FAIL_COND_V(task_name.is_empty(), _generate_name());
|
|
||||||
return task_name;
|
|
||||||
} else {
|
|
||||||
return _generate_name();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return data.custom_name;
|
|
||||||
|
Ref<Script> task_script = get_script();
|
||||||
|
|
||||||
|
if (task_script.is_valid()) {
|
||||||
|
bool has_generate_method = has_method(LW_NAME(_generate_name));
|
||||||
|
ERR_FAIL_COND_V_MSG(has_generate_method && !task_script->is_tool(), _generate_name(), vformat("BTTask: @tool annotation is required if _generate_name is defined: %s", task_script->get_path()));
|
||||||
|
if (task_script->is_tool() && has_generate_method) {
|
||||||
|
String call_result;
|
||||||
|
VCALL_V(_generate_name, call_result);
|
||||||
|
if (call_result.is_empty() || call_result == "<null>") {
|
||||||
|
// Force reset script instance.
|
||||||
|
set_script(Variant());
|
||||||
|
set_script(task_script);
|
||||||
|
// Retry.
|
||||||
|
VCALL_V(_generate_name, call_result);
|
||||||
|
}
|
||||||
|
ERR_FAIL_COND_V_MSG(call_result.is_empty() || call_result == "<null>", _generate_name(), vformat("BTTask: _generate_name() failed to return a proper name string (%s)", task_script->get_path()));
|
||||||
|
return call_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _generate_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BTTask> BTTask::get_root() const {
|
Ref<BTTask> BTTask::get_root() const {
|
||||||
|
|
|
@ -124,25 +124,35 @@ void LimboAIEditor::_add_task_with_prototype(const Ref<BTTask> &p_prototype) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BTTask> LimboAIEditor::_create_task_by_class_or_path(const String &p_class_or_path) const {
|
Ref<BTTask> LimboAIEditor::_create_task_by_class_or_path(const String &p_class_or_path) const {
|
||||||
|
ERR_FAIL_COND_V(p_class_or_path.is_empty(), nullptr);
|
||||||
|
|
||||||
Ref<BTTask> ret;
|
Ref<BTTask> ret;
|
||||||
|
|
||||||
if (p_class_or_path.begins_with("res:")) {
|
if (p_class_or_path.begins_with("res:")) {
|
||||||
Ref<Script> s = RESOURCE_LOAD(p_class_or_path, "Script");
|
Ref<Script> s = RESOURCE_LOAD(p_class_or_path, "Script");
|
||||||
ERR_FAIL_COND_V_MSG(s.is_null(), nullptr, vformat("LimboAI: Failed to instantiate task. Bad script: %s", p_class_or_path));
|
ERR_FAIL_COND_V_MSG(s.is_null(), nullptr, vformat("LimboAI: Can't add task. Bad script: %s", p_class_or_path));
|
||||||
Variant inst = ClassDB::instantiate(s->get_instance_base_type());
|
StringName base_type = s->get_instance_base_type();
|
||||||
ERR_FAIL_COND_V_MSG(inst == Variant(), nullptr, vformat("LimboAI: Failed to instantiate base type \"%s\".", s->get_instance_base_type()));
|
if (base_type == StringName()) {
|
||||||
|
// Try reloading script.
|
||||||
|
s->reload(true);
|
||||||
|
base_type = s->get_instance_base_type();
|
||||||
|
}
|
||||||
|
ERR_FAIL_COND_V_MSG(base_type == StringName(), nullptr, vformat("LimboAI: Can't add task. Bad script: %s", p_class_or_path));
|
||||||
|
|
||||||
if (unlikely(!((Object *)inst)->is_class("BTTask"))) {
|
Variant inst = ClassDB::instantiate(base_type);
|
||||||
|
Object *obj = inst;
|
||||||
|
ERR_FAIL_NULL_V_MSG(obj, nullptr, vformat("LimboAI: Can't add task. Failed to create base type \"%s\".", base_type));
|
||||||
|
|
||||||
|
if (unlikely(!IS_CLASS(obj, BTTask))) {
|
||||||
|
ERR_PRINT_ED(vformat("LimboAI: Can't add task. Script is not a BTTask: %s", p_class_or_path));
|
||||||
VARIANT_DELETE_IF_OBJECT(inst);
|
VARIANT_DELETE_IF_OBJECT(inst);
|
||||||
ERR_PRINT(vformat("LimboAI: Failed to instantiate task. Script is not a BTTask: %s", p_class_or_path));
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst && s.is_valid()) {
|
ret.reference_ptr(Object::cast_to<BTTask>(obj));
|
||||||
((Object *)inst)->set_script(s);
|
ret->set_script(s);
|
||||||
ret = inst;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
ERR_FAIL_COND_V(!ClassDB::is_parent_class(p_class_or_path, "BTTask"), nullptr);
|
||||||
ret = ClassDB::instantiate(p_class_or_path);
|
ret = ClassDB::instantiate(p_class_or_path);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -185,8 +185,8 @@ void LimboState::_notification(int p_what) {
|
||||||
_update_blackboard_plan();
|
_update_blackboard_plan();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_PREDELETE: {
|
||||||
if (active) {
|
if (is_active()) {
|
||||||
_exit();
|
_exit();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -32,6 +32,7 @@ class LimboState : public Node {
|
||||||
GDCLASS(LimboState, Node);
|
GDCLASS(LimboState, Node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool active;
|
||||||
Ref<BlackboardPlan> blackboard_plan;
|
Ref<BlackboardPlan> blackboard_plan;
|
||||||
Node *agent;
|
Node *agent;
|
||||||
Ref<Blackboard> blackboard;
|
Ref<Blackboard> blackboard;
|
||||||
|
@ -43,8 +44,6 @@ private:
|
||||||
protected:
|
protected:
|
||||||
friend LimboHSM;
|
friend LimboHSM;
|
||||||
|
|
||||||
bool active;
|
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
@ -87,7 +86,7 @@ public:
|
||||||
_FORCE_INLINE_ StringName event_finished() const { return LW_NAME(EVENT_FINISHED); }
|
_FORCE_INLINE_ StringName event_finished() const { return LW_NAME(EVENT_FINISHED); }
|
||||||
LimboState *get_root() const;
|
LimboState *get_root() const;
|
||||||
_FORCE_INLINE_ bool is_root() const { return !(get_parent() && IS_CLASS(get_parent(), LimboState)); }
|
_FORCE_INLINE_ bool is_root() const { return !(get_parent() && IS_CLASS(get_parent(), LimboState)); }
|
||||||
bool is_active() const { return active; }
|
_FORCE_INLINE_ bool is_active() const { return active; }
|
||||||
|
|
||||||
void set_guard(const Callable &p_guard_callable);
|
void set_guard(const Callable &p_guard_callable);
|
||||||
void clear_guard();
|
void clear_guard();
|
||||||
|
|
Loading…
Reference in New Issue