105 lines
3.6 KiB
C++
105 lines
3.6 KiB
C++
/**
|
|
* bt_state.cpp
|
|
* =============================================================================
|
|
* Copyright 2021-2023 Serhii Snitsaruk
|
|
*
|
|
* Use of this source code is governed by an MIT-style
|
|
* license that can be found in the LICENSE file or at
|
|
* https://opensource.org/licenses/MIT.
|
|
* =============================================================================
|
|
*/
|
|
|
|
#include "bt_state.h"
|
|
|
|
#include "../editor/debugger/limbo_debugger.h"
|
|
#include "../util/limbo_compat.h"
|
|
#include "../util/limbo_string_names.h"
|
|
|
|
#ifdef LIMBOAI_MODULE
|
|
#include "core/debugger/engine_debugger.h"
|
|
#include "core/error/error_macros.h"
|
|
#include "core/object/class_db.h"
|
|
#include "core/variant/variant.h"
|
|
#endif // LIMBOAI_MODULE
|
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
|
#include <godot_cpp/classes/engine_debugger.hpp>
|
|
#endif // LIMBOAI_GDEXTENSION
|
|
|
|
void BTState::_update_blackboard_source() {
|
|
if (behavior_tree.is_valid() && behavior_tree->get_blackboard_source().is_valid()) {
|
|
if (get_blackboard_source().is_null()) {
|
|
set_blackboard_source(Ref<BlackboardSource>(memnew(BlackboardSource)));
|
|
}
|
|
if (get_blackboard_source() == behavior_tree->get_blackboard_source()) {
|
|
get_blackboard_source()->sync_base();
|
|
} else {
|
|
get_blackboard_source()->set_base_source(behavior_tree->get_blackboard_source());
|
|
}
|
|
}
|
|
}
|
|
|
|
void BTState::_setup() {
|
|
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
|
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard());
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void BTState::_exit() {
|
|
ERR_FAIL_COND(tree_instance == nullptr);
|
|
tree_instance->abort();
|
|
}
|
|
|
|
void BTState::_update(double p_delta) {
|
|
ERR_FAIL_COND(tree_instance == nullptr);
|
|
int status = tree_instance->execute(p_delta);
|
|
emit_signal(LimboStringNames::get_singleton()->updated, p_delta);
|
|
if (status == BTTask::SUCCESS) {
|
|
get_root()->dispatch(success_event, Variant());
|
|
} else if (status == BTTask::FAILURE) {
|
|
get_root()->dispatch(failure_event, Variant());
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
void BTState::_notification(int p_notification) {
|
|
switch (p_notification) {
|
|
case NOTIFICATION_ENTER_TREE: {
|
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
|
}
|
|
} break;
|
|
case NOTIFICATION_EXIT_TREE: {
|
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
|
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
|
|
}
|
|
} break;
|
|
}
|
|
}
|
|
#endif // DEBUG_ENABLED
|
|
|
|
void BTState::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("set_behavior_tree", "p_value"), &BTState::set_behavior_tree);
|
|
ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTState::get_behavior_tree);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_success_event", "p_event_name"), &BTState::set_success_event);
|
|
ClassDB::bind_method(D_METHOD("get_success_event"), &BTState::get_success_event);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_failure_event", "p_event_name"), &BTState::set_failure_event);
|
|
ClassDB::bind_method(D_METHOD("get_failure_event"), &BTState::get_failure_event);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "success_event"), "set_success_event", "get_success_event");
|
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "failure_event"), "set_failure_event", "get_failure_event");
|
|
}
|
|
|
|
BTState::BTState() {
|
|
success_event = "success";
|
|
failure_event = "failure";
|
|
}
|