Compare commits
16 Commits
a17217e684
...
e12612fc31
Author | SHA1 | Date |
---|---|---|
Wilson E. Alvarez | e12612fc31 | |
Serhii Snitsaruk | 5e961ec6fa | |
Serhii Snitsaruk | bc5d5d8610 | |
Serhii Snitsaruk | 75e8e68da4 | |
Nate Moore | 4fe4049c3a | |
Serhii Snitsaruk | 69e921be31 | |
Serhii Snitsaruk | c6bb5bad74 | |
Serhii Snitsaruk | 2c2f2dd4be | |
Serhii Snitsaruk | dedffc4f22 | |
Nate Moore | 4491a23d52 | |
Wilson E. Alvarez | c42d9ebedf | |
Wilson E. Alvarez | ad71028135 | |
Wilson E. Alvarez | f8df4e695e | |
Wilson E. Alvarez | 181a45bf4a | |
Wilson E. Alvarez | 54605dbffa | |
Wilson E. Alvarez | 004d456983 |
|
@ -0,0 +1,24 @@
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v17.0.6
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
|
files: \.(c|h|cpp|hpp|cc|cxx|m|mm|inc|java|glsl)$
|
||||||
|
types_or: [text]
|
||||||
|
exclude: |
|
||||||
|
(?x)^(
|
||||||
|
tests/python_build.*|
|
||||||
|
.*thirdparty.*|
|
||||||
|
.*platform/android/java/lib/src/com.*|
|
||||||
|
.*-so_wrap.*
|
||||||
|
)
|
||||||
|
|
||||||
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
|
rev: 24.2.0
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
files: (\.py$|SConstruct|SCsub)
|
||||||
|
types_or: [text]
|
||||||
|
exclude: .*thirdparty.*
|
||||||
|
args:
|
||||||
|
- --line-length=120
|
|
@ -34,6 +34,7 @@ Behavior Trees are powerful hierarchical structures used to model and control th
|
||||||
[![Demonstration](https://img.youtube.com/vi/NWaMArUg7mY/0.jpg)](https://www.youtube.com/watch?v=NWaMArUg7mY)
|
[![Demonstration](https://img.youtube.com/vi/NWaMArUg7mY/0.jpg)](https://www.youtube.com/watch?v=NWaMArUg7mY)
|
||||||
|
|
||||||
>**🛈 Demo project** lives in the `demo` folder and is available separately in [**Releases**](https://github.com/limbonaut/limboai/releases).
|
>**🛈 Demo project** lives in the `demo` folder and is available separately in [**Releases**](https://github.com/limbonaut/limboai/releases).
|
||||||
|
> Run `demo/scenes/showcase.tscn` to get started.
|
||||||
> It also contains a tutorial that introduces behavior trees using examples.
|
> It also contains a tutorial that introduces behavior trees using examples.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
2
SCsub
2
SCsub
|
@ -5,7 +5,7 @@ Import("env_modules")
|
||||||
|
|
||||||
module_env = env.Clone()
|
module_env = env.Clone()
|
||||||
|
|
||||||
module_env.Append(CPPDEFINES = ['LIMBOAI_MODULE'])
|
module_env.Append(CPPDEFINES=["LIMBOAI_MODULE"])
|
||||||
|
|
||||||
module_env.add_source_files(env.modules_sources, "*.cpp")
|
module_env.add_source_files(env.modules_sources, "*.cpp")
|
||||||
module_env.add_source_files(env.modules_sources, "blackboard/*.cpp")
|
module_env.add_source_files(env.modules_sources, "blackboard/*.cpp")
|
||||||
|
|
|
@ -79,6 +79,9 @@ Variant BBParam::get_value(Object *p_agent, const Ref<Blackboard> &p_blackboard,
|
||||||
ERR_FAIL_COND_V(!p_blackboard.is_valid(), p_default);
|
ERR_FAIL_COND_V(!p_blackboard.is_valid(), p_default);
|
||||||
|
|
||||||
if (value_source == SAVED_VALUE) {
|
if (value_source == SAVED_VALUE) {
|
||||||
|
if (saved_value == Variant()) {
|
||||||
|
_assign_default_value();
|
||||||
|
}
|
||||||
return saved_value;
|
return saved_value;
|
||||||
} else {
|
} else {
|
||||||
ERR_FAIL_COND_V_MSG(!p_blackboard->has_var(variable), p_default, vformat("BBParam: Blackboard variable \"%s\" doesn't exist.", variable));
|
ERR_FAIL_COND_V_MSG(!p_blackboard->has_var(variable), p_default, vformat("BBParam: Blackboard variable \"%s\" doesn't exist.", variable));
|
||||||
|
@ -114,6 +117,4 @@ void BBParam::_bind_methods() {
|
||||||
|
|
||||||
BBParam::BBParam() {
|
BBParam::BBParam() {
|
||||||
value_source = SAVED_VALUE;
|
value_source = SAVED_VALUE;
|
||||||
|
|
||||||
_assign_default_value();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,19 @@
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||||
|
|
||||||
project = 'LimboAI'
|
project = "LimboAI"
|
||||||
copyright = '2021-present Serhii Snitsaruk and the LimboAI contributors'
|
copyright = "2021-present Serhii Snitsaruk and the LimboAI contributors"
|
||||||
author = 'Serhii Snitsaruk and the LimboAI contributors'
|
author = "Serhii Snitsaruk and the LimboAI contributors"
|
||||||
release = '1.0'
|
release = "1.0"
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||||
|
|
||||||
extensions = ['sphinx_rtd_dark_mode', 'sphinx_copybutton']
|
extensions = ["sphinx_rtd_dark_mode", "sphinx_copybutton"]
|
||||||
|
|
||||||
master_doc = 'index'
|
master_doc = "index"
|
||||||
templates_path = ['_templates']
|
templates_path = ["_templates"]
|
||||||
exclude_patterns = ['_build']
|
exclude_patterns = ["_build"]
|
||||||
|
|
||||||
# -- Markdown configuration (sphinx_markdown_builder).
|
# -- Markdown configuration (sphinx_markdown_builder).
|
||||||
# markdown_anchor_sections = True
|
# markdown_anchor_sections = True
|
||||||
|
@ -33,12 +33,11 @@ default_dark_mode = False
|
||||||
# -- Options for HTML output -------------------------------------------------
|
# -- Options for HTML output -------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||||
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
html_theme = "sphinx_rtd_theme"
|
||||||
html_static_path = ['_static']
|
html_static_path = ["_static"]
|
||||||
html_logo = "logo.png"
|
html_logo = "logo.png"
|
||||||
html_theme_options = {
|
html_theme_options = {
|
||||||
'logo_only': True,
|
"logo_only": True,
|
||||||
'display_version': True,
|
"display_version": True,
|
||||||
"collapse_navigation": True,
|
"collapse_navigation": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "../util/limbo_string_names.h"
|
#include "../util/limbo_string_names.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/button.h"
|
#include "scene/gui/button.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "editor/editor_interface.h"
|
#include "editor/editor_interface.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/line_edit.h"
|
#include "scene/gui/line_edit.h"
|
||||||
|
#include "scene/gui/margin_container.h"
|
||||||
#include "scene/gui/panel_container.h"
|
#include "scene/gui/panel_container.h"
|
||||||
#include "scene/resources/style_box_flat.h"
|
#include "scene/resources/style_box_flat.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "core/object/callable_method_pointer.h"
|
#include "core/object/callable_method_pointer.h"
|
||||||
#include "core/os/time.h"
|
#include "core/os/time.h"
|
||||||
#include "core/typedefs.h"
|
#include "core/typedefs.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "scene/resources/style_box.h"
|
#include "scene/resources/style_box.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
@ -127,16 +127,16 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
if (status_changed) {
|
if (status_changed) {
|
||||||
item->set_metadata(1, current_status);
|
item->set_metadata(1, current_status);
|
||||||
if (current_status == BTTask::SUCCESS) {
|
if (current_status == BTTask::SUCCESS) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_success_status));
|
||||||
item->set_icon(1, theme_cache.icon_success);
|
item->set_icon(1, theme_cache.icon_success);
|
||||||
} else if (current_status == BTTask::FAILURE) {
|
} else if (current_status == BTTask::FAILURE) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_failure_status));
|
||||||
item->set_icon(1, theme_cache.icon_failure);
|
item->set_icon(1, theme_cache.icon_failure);
|
||||||
} else if (current_status == BTTask::RUNNING) {
|
} else if (current_status == BTTask::RUNNING) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_running_status));
|
||||||
item->set_icon(1, theme_cache.icon_running);
|
item->set_icon(1, theme_cache.icon_running);
|
||||||
} else {
|
} else {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_fresh));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_fresh));
|
||||||
item->set_icon(1, nullptr);
|
item->set_icon(1, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,13 +204,13 @@ void BehaviorTreeView::_update_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
item->set_icon_max_width(0, 16 * _get_editor_scale()); // Force user icon size.
|
item->set_icon_max_width(0, 16 * _get_editor_scale()); // Force user icon size.
|
||||||
|
|
||||||
if (task_data.status == BTTask::SUCCESS) {
|
if (task_data.status == BTTask::SUCCESS) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_success_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_success_status));
|
||||||
item->set_icon(1, theme_cache.icon_success);
|
item->set_icon(1, theme_cache.icon_success);
|
||||||
} else if (task_data.status == BTTask::FAILURE) {
|
} else if (task_data.status == BTTask::FAILURE) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_failure_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_failure_status));
|
||||||
item->set_icon(1, theme_cache.icon_failure);
|
item->set_icon(1, theme_cache.icon_failure);
|
||||||
} else if (task_data.status == BTTask::RUNNING) {
|
} else if (task_data.status == BTTask::RUNNING) {
|
||||||
item->set_custom_draw(0, this, LW_NAME(_draw_running_status));
|
item->set_custom_draw_callback(0, callable_mp(this, &BehaviorTreeView::_draw_running_status));
|
||||||
item->set_icon(1, theme_cache.icon_running);
|
item->set_icon(1, theme_cache.icon_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
#include "core/variant/array.h"
|
#include "core/variant/array.h"
|
||||||
#include "editor/editor_interface.h"
|
#include "editor/editor_interface.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_scale.h"
|
|
||||||
#include "editor/filesystem_dock.h"
|
#include "editor/filesystem_dock.h"
|
||||||
#include "editor/plugins/editor_debugger_plugin.h"
|
#include "editor/plugins/editor_debugger_plugin.h"
|
||||||
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
#include "scene/gui/control.h"
|
#include "scene/gui/control.h"
|
||||||
#include "scene/gui/item_list.h"
|
#include "scene/gui/item_list.h"
|
||||||
|
|
|
@ -34,12 +34,13 @@
|
||||||
#include "editor/editor_file_system.h"
|
#include "editor/editor_file_system.h"
|
||||||
#include "editor/editor_help.h"
|
#include "editor/editor_help.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_scale.h"
|
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "editor/editor_undo_redo_manager.h"
|
#include "editor/editor_undo_redo_manager.h"
|
||||||
|
#include "editor/gui/editor_bottom_panel.h"
|
||||||
#include "editor/inspector_dock.h"
|
#include "editor/inspector_dock.h"
|
||||||
#include "editor/plugins/script_editor_plugin.h"
|
#include "editor/plugins/script_editor_plugin.h"
|
||||||
#include "editor/project_settings_editor.h"
|
#include "editor/project_settings_editor.h"
|
||||||
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/panel_container.h"
|
#include "scene/gui/panel_container.h"
|
||||||
#include "scene/gui/separator.h"
|
#include "scene/gui/separator.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
@ -682,7 +683,7 @@ void LimboAIEditor::_misc_option_selected(int p_id) {
|
||||||
LimboDebuggerPlugin::get_singleton()->get_first_session_window()->set_window_enabled(true);
|
LimboDebuggerPlugin::get_singleton()->get_first_session_window()->set_window_enabled(true);
|
||||||
} else {
|
} else {
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
EditorNode::get_singleton()->make_bottom_panel_item_visible(EditorDebuggerNode::get_singleton());
|
EditorNode::get_bottom_panel()->make_item_visible(EditorDebuggerNode::get_singleton());
|
||||||
EditorDebuggerNode::get_singleton()->get_default_debugger()->switch_to_debugger(
|
EditorDebuggerNode::get_singleton()->get_default_debugger()->switch_to_debugger(
|
||||||
LimboDebuggerPlugin::get_singleton()->get_first_session_tab_index());
|
LimboDebuggerPlugin::get_singleton()->get_first_session_tab_index());
|
||||||
#elif LIMBOAI_GDEXTENSION
|
#elif LIMBOAI_GDEXTENSION
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
#include "core/templates/hash_set.h"
|
#include "core/templates/hash_set.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_plugin.h"
|
#include "editor/plugins/editor_plugin.h"
|
||||||
#include "editor/gui/editor_spin_slider.h"
|
#include "editor/gui/editor_spin_slider.h"
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
#include "scene/gui/control.h"
|
#include "scene/gui/control.h"
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "editor/editor_help.h"
|
#include "editor/editor_help.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "editor/plugins/script_editor_plugin.h"
|
#include "editor/plugins/script_editor_plugin.h"
|
||||||
#include "scene/gui/check_box.h"
|
#include "scene/gui/check_box.h"
|
||||||
#endif // LIMBO_MODULE
|
#endif // LIMBO_MODULE
|
||||||
|
@ -60,7 +60,7 @@ void TaskButton::_bind_methods() {
|
||||||
Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
||||||
help_bit->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 1));
|
help_bit->set_content_height_limits(1, 360 * EDSCALE);
|
||||||
|
|
||||||
String help_text;
|
String help_text;
|
||||||
if (!p_text.is_empty()) {
|
if (!p_text.is_empty()) {
|
||||||
|
@ -69,7 +69,7 @@ Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
||||||
help_text = "[i]" + TTR("No description.") + "[/i]";
|
help_text = "[i]" + TTR("No description.") + "[/i]";
|
||||||
}
|
}
|
||||||
|
|
||||||
help_bit->set_text(help_text);
|
help_bit->set_custom_text(String(), String(), help_text);
|
||||||
|
|
||||||
return help_bit;
|
return help_bit;
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "core/object/script_language.h"
|
#include "core/object/script_language.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
@ -50,7 +50,7 @@ void TaskTree::_update_item(TreeItem *p_item) {
|
||||||
if (p_item->get_parent()) {
|
if (p_item->get_parent()) {
|
||||||
Ref<BTProbabilitySelector> sel = p_item->get_parent()->get_metadata(0);
|
Ref<BTProbabilitySelector> sel = p_item->get_parent()->get_metadata(0);
|
||||||
if (sel.is_valid() && sel->has_probability(p_item->get_index())) {
|
if (sel.is_valid() && sel->has_probability(p_item->get_index())) {
|
||||||
p_item->set_custom_draw(0, this, LW_NAME(_draw_probability));
|
p_item->set_custom_draw_callback(0, callable_mp(this, &TaskTree::_draw_probability));
|
||||||
p_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
p_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ env = SConscript("godot-cpp/SConstruct")
|
||||||
|
|
||||||
# tweak this if you want to use different folders, or more folders, to store your source code in.
|
# tweak this if you want to use different folders, or more folders, to store your source code in.
|
||||||
env.Append(CPPPATH=["limboai/"])
|
env.Append(CPPPATH=["limboai/"])
|
||||||
env.Append(CPPDEFINES = ['LIMBOAI_GDEXTENSION'])
|
env.Append(CPPDEFINES=["LIMBOAI_GDEXTENSION"])
|
||||||
sources = Glob("limboai/*.cpp")
|
sources = Glob("limboai/*.cpp")
|
||||||
sources += (Glob("limboai/blackboard/*.cpp"))
|
sources += Glob("limboai/blackboard/*.cpp")
|
||||||
sources += (Glob("limboai/blackboard/bb_param/*.cpp"))
|
sources += Glob("limboai/blackboard/bb_param/*.cpp")
|
||||||
sources += (Glob("limboai/bt/*.cpp"))
|
sources += Glob("limboai/bt/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/*.cpp"))
|
sources += Glob("limboai/bt/tasks/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/blackboard/*.cpp"))
|
sources += Glob("limboai/bt/tasks/blackboard/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/composites/*.cpp"))
|
sources += Glob("limboai/bt/tasks/composites/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/decorators/*.cpp"))
|
sources += Glob("limboai/bt/tasks/decorators/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/scene/*.cpp"))
|
sources += Glob("limboai/bt/tasks/scene/*.cpp")
|
||||||
sources += (Glob("limboai/bt/tasks/utility/*.cpp"))
|
sources += Glob("limboai/bt/tasks/utility/*.cpp")
|
||||||
sources += (Glob("limboai/gdextension/*.cpp"))
|
sources += Glob("limboai/gdextension/*.cpp")
|
||||||
sources += (Glob("limboai/editor/debugger/*.cpp"))
|
sources += Glob("limboai/editor/debugger/*.cpp")
|
||||||
sources += (Glob("limboai/editor/*.cpp"))
|
sources += Glob("limboai/editor/*.cpp")
|
||||||
sources += (Glob("limboai/hsm/*.cpp"))
|
sources += Glob("limboai/hsm/*.cpp")
|
||||||
sources += (Glob("limboai/util/*.cpp"))
|
sources += Glob("limboai/util/*.cpp")
|
||||||
|
|
||||||
|
|
||||||
if env["platform"] == "macos":
|
if env["platform"] == "macos":
|
||||||
|
|
|
@ -31,18 +31,23 @@ def get_script_dir():
|
||||||
def main():
|
def main():
|
||||||
silent = False
|
silent = False
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:],
|
opts, args = getopt.getopt(sys.argv[1:], "s", ["silent"])
|
||||||
"s", ["silent"])
|
|
||||||
except getopt.GetoptError as e:
|
except getopt.GetoptError as e:
|
||||||
print('%s: %s!\n' % (os.path.basename(__file__), e.msg,))
|
print(
|
||||||
|
"%s: %s!\n"
|
||||||
|
% (
|
||||||
|
os.path.basename(__file__),
|
||||||
|
e.msg,
|
||||||
|
)
|
||||||
|
)
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
for opt, arg in opts:
|
for opt, arg in opts:
|
||||||
if opt in ('-h', '--help'):
|
if opt in ("-h", "--help"):
|
||||||
usage()
|
usage()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
elif opt in ('-s','--silent'):
|
elif opt in ("-s", "--silent"):
|
||||||
silent = True
|
silent = True
|
||||||
|
|
||||||
config_dir = get_script_dir()
|
config_dir = get_script_dir()
|
||||||
|
@ -66,7 +71,7 @@ def main():
|
||||||
|
|
||||||
icon_files.sort()
|
icon_files.sort()
|
||||||
for icon_file in icon_files:
|
for icon_file in icon_files:
|
||||||
content += os.path.splitext(icon_file)[0] + " = \"res://addons/limboai/icons/" + icon_file + "\"\n"
|
content += os.path.splitext(icon_file)[0] + ' = "res://addons/limboai/icons/' + icon_file + '"\n'
|
||||||
|
|
||||||
f = open(config_path, "w")
|
f = open(config_path, "w")
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
|
@ -17,8 +17,14 @@
|
||||||
#include "core/object/ref_counted.h"
|
#include "core/object/ref_counted.h"
|
||||||
#include "core/string/node_path.h"
|
#include "core/string/node_path.h"
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_bool.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_float.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_int.h"
|
||||||
#include "modules/limboai/blackboard/bb_param/bb_node.h"
|
#include "modules/limboai/blackboard/bb_param/bb_node.h"
|
||||||
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_string.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_variant.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_vector2.h"
|
||||||
#include "modules/limboai/blackboard/blackboard.h"
|
#include "modules/limboai/blackboard/blackboard.h"
|
||||||
#include "modules/limboai/bt/tasks/bt_task.h"
|
#include "modules/limboai/bt/tasks/bt_task.h"
|
||||||
#include "tests/test_macros.h"
|
#include "tests/test_macros.h"
|
||||||
|
@ -122,6 +128,68 @@ TEST_CASE("[Modules][LimboAI] BBNode") {
|
||||||
memdelete(dummy);
|
memdelete(dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[Modules][LimboAI] BBParam default values") {
|
||||||
|
Node *dummy = memnew(Node);
|
||||||
|
Ref<Blackboard> bb = memnew(Blackboard);
|
||||||
|
|
||||||
|
SUBCASE("Test default value for BBBool") {
|
||||||
|
Ref<BBBool> param = memnew(BBBool);
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(false));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
SUBCASE("Test default value for BBInt") {
|
||||||
|
Ref<BBInt> param = memnew(BBInt);
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(0));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
SUBCASE("Test default value for BBFloat") {
|
||||||
|
Ref<BBFloat> param = memnew(BBFloat);
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(0.0));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
SUBCASE("Test default value for BBString") {
|
||||||
|
Ref<BBString> param = memnew(BBString);
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(""));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
SUBCASE("Test default value for BBVector2") {
|
||||||
|
Ref<BBVector2> param = memnew(BBVector2);
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(Vector2()));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
SUBCASE("Test default value for BBVariant") {
|
||||||
|
Ref<BBVariant> param = memnew(BBVariant);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_value_source(BBParam::SAVED_VALUE);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::BOOL);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(false));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::INT);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(0));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::FLOAT);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(0.0));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::STRING);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(""));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::VECTOR2);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(Vector2()));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
param->set_type(Variant::NODE_PATH);
|
||||||
|
CHECK_EQ(param->get_value(dummy, bb), Variant(NodePath()));
|
||||||
|
CHECK_NE(param->get_value(dummy, bb), Variant());
|
||||||
|
}
|
||||||
|
|
||||||
|
memdelete(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace TestBBParam
|
} //namespace TestBBParam
|
||||||
|
|
||||||
#endif // TEST_BB_PARAM_H
|
#endif // TEST_BB_PARAM_H
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
|
|
||||||
namespace TestHSM {
|
namespace TestHSM {
|
||||||
|
|
||||||
|
inline void wire_callbacks(LimboState *p_state, Ref<CallbackCounter> p_entries_counter, Ref<CallbackCounter> p_updates_counter, Ref<CallbackCounter> p_exits_counter) {
|
||||||
|
p_state->call_on_enter(callable_mp(p_entries_counter.ptr(), &CallbackCounter::callback));
|
||||||
|
p_state->call_on_update(callable_mp(p_updates_counter.ptr(), &CallbackCounter::callback_delta));
|
||||||
|
p_state->call_on_exit(callable_mp(p_exits_counter.ptr(), &CallbackCounter::callback));
|
||||||
|
}
|
||||||
|
|
||||||
class TestGuard : public RefCounted {
|
class TestGuard : public RefCounted {
|
||||||
GDCLASS(TestGuard, RefCounted);
|
GDCLASS(TestGuard, RefCounted);
|
||||||
|
|
||||||
|
@ -42,22 +48,38 @@ TEST_CASE("[Modules][LimboAI] HSM") {
|
||||||
Ref<CallbackCounter> beta_entries = memnew(CallbackCounter);
|
Ref<CallbackCounter> beta_entries = memnew(CallbackCounter);
|
||||||
Ref<CallbackCounter> beta_exits = memnew(CallbackCounter);
|
Ref<CallbackCounter> beta_exits = memnew(CallbackCounter);
|
||||||
Ref<CallbackCounter> beta_updates = memnew(CallbackCounter);
|
Ref<CallbackCounter> beta_updates = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> nested_entries = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> nested_exits = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> nested_updates = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> gamma_entries = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> gamma_exits = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> gamma_updates = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> delta_entries = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> delta_exits = memnew(CallbackCounter);
|
||||||
|
Ref<CallbackCounter> delta_updates = memnew(CallbackCounter);
|
||||||
|
|
||||||
LimboState *state_alpha = memnew(LimboState);
|
LimboState *state_alpha = memnew(LimboState);
|
||||||
state_alpha->call_on_enter(callable_mp(alpha_entries.ptr(), &CallbackCounter::callback));
|
wire_callbacks(state_alpha, alpha_entries, alpha_updates, alpha_exits);
|
||||||
state_alpha->call_on_update(callable_mp(alpha_updates.ptr(), &CallbackCounter::callback_delta));
|
|
||||||
state_alpha->call_on_exit(callable_mp(alpha_exits.ptr(), &CallbackCounter::callback));
|
|
||||||
|
|
||||||
LimboState *state_beta = memnew(LimboState);
|
LimboState *state_beta = memnew(LimboState);
|
||||||
state_beta->call_on_enter(callable_mp(beta_entries.ptr(), &CallbackCounter::callback));
|
wire_callbacks(state_beta, beta_entries, beta_updates, beta_exits);
|
||||||
state_beta->call_on_update(callable_mp(beta_updates.ptr(), &CallbackCounter::callback_delta));
|
LimboHSM *nested_hsm = memnew(LimboHSM);
|
||||||
state_beta->call_on_exit(callable_mp(beta_exits.ptr(), &CallbackCounter::callback));
|
wire_callbacks(nested_hsm, nested_entries, nested_updates, nested_exits);
|
||||||
|
LimboState *state_gamma = memnew(LimboState);
|
||||||
|
wire_callbacks(state_gamma, gamma_entries, gamma_updates, gamma_exits);
|
||||||
|
LimboState *state_delta = memnew(LimboState);
|
||||||
|
wire_callbacks(state_delta, delta_entries, delta_updates, delta_exits);
|
||||||
|
|
||||||
hsm->add_child(state_alpha);
|
hsm->add_child(state_alpha);
|
||||||
hsm->add_child(state_beta);
|
hsm->add_child(state_beta);
|
||||||
|
hsm->add_child(nested_hsm);
|
||||||
|
nested_hsm->add_child(state_gamma);
|
||||||
|
nested_hsm->add_child(state_delta);
|
||||||
|
|
||||||
hsm->add_transition(state_alpha, state_beta, "event_one");
|
hsm->add_transition(state_alpha, state_beta, "event_one");
|
||||||
hsm->add_transition(state_beta, state_alpha, "event_two");
|
hsm->add_transition(state_beta, state_alpha, "event_two");
|
||||||
|
hsm->add_transition(hsm->anystate(), nested_hsm, "goto_nested");
|
||||||
|
nested_hsm->add_transition(state_gamma, state_delta, "goto_delta");
|
||||||
|
nested_hsm->add_transition(state_delta, state_gamma, "goto_gamma");
|
||||||
|
|
||||||
hsm->set_initial_state(state_alpha);
|
hsm->set_initial_state(state_alpha);
|
||||||
Ref<Blackboard> parent_scope = memnew(Blackboard);
|
Ref<Blackboard> parent_scope = memnew(Blackboard);
|
||||||
|
@ -179,6 +201,57 @@ TEST_CASE("[Modules][LimboAI] HSM") {
|
||||||
CHECK(state_beta->get_blackboard()->get_parent() == parent_scope);
|
CHECK(state_beta->get_blackboard()->get_parent() == parent_scope);
|
||||||
CHECK(state_alpha->get_blackboard()->get_var("parent_var", Variant()) == Variant(100));
|
CHECK(state_alpha->get_blackboard()->get_var("parent_var", Variant()) == Variant(100));
|
||||||
}
|
}
|
||||||
|
SUBCASE("Test flow with a nested HSM, and test dispatch() from nested states") {
|
||||||
|
state_gamma->dispatch("goto_nested");
|
||||||
|
CHECK(hsm->get_leaf_state() == state_gamma);
|
||||||
|
CHECK(nested_entries->num_callbacks == 1);
|
||||||
|
CHECK(nested_updates->num_callbacks == 0);
|
||||||
|
CHECK(nested_exits->num_callbacks == 0);
|
||||||
|
CHECK(gamma_entries->num_callbacks == 1);
|
||||||
|
CHECK(gamma_updates->num_callbacks == 0);
|
||||||
|
CHECK(gamma_exits->num_callbacks == 0);
|
||||||
|
|
||||||
|
hsm->update(0.01666);
|
||||||
|
CHECK(nested_entries->num_callbacks == 1);
|
||||||
|
CHECK(nested_updates->num_callbacks == 1);
|
||||||
|
CHECK(nested_exits->num_callbacks == 0);
|
||||||
|
CHECK(gamma_entries->num_callbacks == 1);
|
||||||
|
CHECK(gamma_updates->num_callbacks == 1);
|
||||||
|
CHECK(gamma_exits->num_callbacks == 0);
|
||||||
|
|
||||||
|
state_gamma->dispatch("goto_delta");
|
||||||
|
CHECK(hsm->get_leaf_state() == state_delta);
|
||||||
|
CHECK(nested_entries->num_callbacks == 1);
|
||||||
|
CHECK(nested_updates->num_callbacks == 1);
|
||||||
|
CHECK(nested_exits->num_callbacks == 0);
|
||||||
|
CHECK(gamma_entries->num_callbacks == 1);
|
||||||
|
CHECK(gamma_updates->num_callbacks == 1);
|
||||||
|
CHECK(gamma_exits->num_callbacks == 1);
|
||||||
|
CHECK(delta_entries->num_callbacks == 1);
|
||||||
|
CHECK(delta_updates->num_callbacks == 0);
|
||||||
|
CHECK(delta_exits->num_callbacks == 0);
|
||||||
|
|
||||||
|
state_delta->dispatch(hsm->event_finished());
|
||||||
|
CHECK(nested_entries->num_callbacks == 1);
|
||||||
|
CHECK(nested_updates->num_callbacks == 1);
|
||||||
|
CHECK(nested_exits->num_callbacks == 1);
|
||||||
|
CHECK(gamma_entries->num_callbacks == 1);
|
||||||
|
CHECK(gamma_updates->num_callbacks == 1);
|
||||||
|
CHECK(gamma_exits->num_callbacks == 1);
|
||||||
|
CHECK(delta_entries->num_callbacks == 1);
|
||||||
|
CHECK(delta_updates->num_callbacks == 0);
|
||||||
|
CHECK(delta_exits->num_callbacks == 1);
|
||||||
|
CHECK(hsm->is_active() == false);
|
||||||
|
CHECK(hsm->get_leaf_state() == hsm);
|
||||||
|
}
|
||||||
|
SUBCASE("Test get_root()") {
|
||||||
|
CHECK(hsm->get_root() == hsm);
|
||||||
|
CHECK(state_alpha->get_root() == hsm);
|
||||||
|
CHECK(state_beta->get_root() == hsm);
|
||||||
|
CHECK(nested_hsm->get_root() == hsm);
|
||||||
|
CHECK(state_delta->get_root() == hsm);
|
||||||
|
CHECK(state_gamma->get_root() == hsm);
|
||||||
|
}
|
||||||
|
|
||||||
memdelete(agent);
|
memdelete(agent);
|
||||||
memdelete(hsm);
|
memdelete(hsm);
|
||||||
|
|
|
@ -27,11 +27,6 @@
|
||||||
LimboStringNames *LimboStringNames::singleton = nullptr;
|
LimboStringNames *LimboStringNames::singleton = nullptr;
|
||||||
|
|
||||||
LimboStringNames::LimboStringNames() {
|
LimboStringNames::LimboStringNames() {
|
||||||
_draw_failure_status = SN("_draw_failure_status");
|
|
||||||
_draw_fresh = SN("_draw_fresh");
|
|
||||||
_draw_probability = SN("_draw_probability");
|
|
||||||
_draw_running_status = SN("_draw_running_status");
|
|
||||||
_draw_success_status = SN("_draw_success_status");
|
|
||||||
_enter = SN("_enter");
|
_enter = SN("_enter");
|
||||||
_exit = SN("_exit");
|
_exit = SN("_exit");
|
||||||
_generate_name = SN("_generate_name");
|
_generate_name = SN("_generate_name");
|
||||||
|
|
|
@ -41,11 +41,6 @@ class LimboStringNames {
|
||||||
public:
|
public:
|
||||||
_FORCE_INLINE_ static LimboStringNames *get_singleton() { return singleton; }
|
_FORCE_INLINE_ static LimboStringNames *get_singleton() { return singleton; }
|
||||||
|
|
||||||
StringName _draw_failure_status;
|
|
||||||
StringName _draw_fresh;
|
|
||||||
StringName _draw_probability;
|
|
||||||
StringName _draw_running_status;
|
|
||||||
StringName _draw_success_status;
|
|
||||||
StringName _enter;
|
StringName _enter;
|
||||||
StringName _exit;
|
StringName _exit;
|
||||||
StringName _generate_name;
|
StringName _generate_name;
|
||||||
|
|
Loading…
Reference in New Issue