From bebd6a15ebf5ec7f5d5f19ff895ca285f23f5cd8 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Mon, 4 Nov 2024 14:51:37 +0100 Subject: [PATCH 1/3] Save edited built-in BT resource on `Ctrl+S` --- editor/limbo_ai_editor_plugin.cpp | 11 +++++++++++ editor/task_tree.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/editor/limbo_ai_editor_plugin.cpp b/editor/limbo_ai_editor_plugin.cpp index 589ec5f..7f21722 100644 --- a/editor/limbo_ai_editor_plugin.cpp +++ b/editor/limbo_ai_editor_plugin.cpp @@ -476,6 +476,14 @@ void LimboAIEditor::_process_shortcut_input(const Ref &p_event) { } else if (LW_IS_SHORTCUT("limbo_ai/close_tab", p_event)) { _tab_menu_option_selected(TAB_CLOSE); handled = true; + } else if (LW_IS_SHORTCUT("limbo_ai/editor_save_scene", p_event)) { + // This intercepts the editor save action, but does not set the event as handled because we don't know the user's intention. + // We just want to save the currently edited BT as well, which may cause a loop with built-in resource if done from "_save_external_data". + // Workaround for: https://github.com/limbonaut/limboai/issues/240#issuecomment-2453087424 + if (task_tree->get_bt().is_valid() && RESOURCE_IS_BUILT_IN(task_tree->get_bt())) { + _on_save_pressed(); + } + handled = false; // intentionally not set as handled } } @@ -1585,6 +1593,9 @@ LimboAIEditor::LimboAIEditor() { LW_SHORTCUT("limbo_ai/find_task", TTR("Find Task"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(F))); LW_SHORTCUT("limbo_ai/hide_tree_search", TTR("Close Search"), (Key)(LW_KEY(ESCAPE))); + // Intercept editor save scene action. + LW_SHORTCUT("limbo_ai/editor_save_scene", TTR("Save Scene"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(S))); + set_process_shortcut_input(true); save_dialog = memnew(FileDialog); diff --git a/editor/task_tree.h b/editor/task_tree.h index efb7241..d096eb3 100644 --- a/editor/task_tree.h +++ b/editor/task_tree.h @@ -95,7 +95,7 @@ protected: public: void load_bt(const Ref &p_behavior_tree); void unload(); - Ref get_bt() const { return bt; } + _FORCE_INLINE_ Ref get_bt() const { return bt; } void update_tree() { _update_tree(); } void update_task(const Ref &p_task); void add_selection(const Ref &p_task); From 03476721d93c2bacf0292077d9c09fc0c2a15f66 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Mon, 4 Nov 2024 15:52:42 +0100 Subject: [PATCH 2/3] Change shortcut for "Jump to Owner" Ctrl+J is no longer available by default --- editor/limbo_ai_editor_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/limbo_ai_editor_plugin.cpp b/editor/limbo_ai_editor_plugin.cpp index 7f21722..27ef75e 100644 --- a/editor/limbo_ai_editor_plugin.cpp +++ b/editor/limbo_ai_editor_plugin.cpp @@ -1588,7 +1588,7 @@ LimboAIEditor::LimboAIEditor() { LW_SHORTCUT("limbo_ai/save_behavior_tree", TTR("Save Behavior Tree"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY_MASK(ALT) | LW_KEY(S))); LW_SHORTCUT("limbo_ai/load_behavior_tree", TTR("Load Behavior Tree"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY_MASK(ALT) | LW_KEY(L))); LW_SHORTCUT("limbo_ai/open_debugger", TTR("Open Debugger"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY_MASK(ALT) | LW_KEY(D))); - LW_SHORTCUT("limbo_ai/jump_to_owner", TTR("Jump to Owner"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(J))); + LW_SHORTCUT("limbo_ai/jump_to_owner", TTR("Jump to Owner"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(G))); LW_SHORTCUT("limbo_ai/close_tab", TTR("Close Tab"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(W))); LW_SHORTCUT("limbo_ai/find_task", TTR("Find Task"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(F))); LW_SHORTCUT("limbo_ai/hide_tree_search", TTR("Close Search"), (Key)(LW_KEY(ESCAPE))); From bf8535026050eaf210394f2f7628ced24dadf04c Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Mon, 4 Nov 2024 19:38:48 +0100 Subject: [PATCH 3/3] Open the owner scene when switching to a built-in BT --- editor/limbo_ai_editor_plugin.cpp | 34 ++++++++++++++++++++----------- editor/limbo_ai_editor_plugin.h | 1 - 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/editor/limbo_ai_editor_plugin.cpp b/editor/limbo_ai_editor_plugin.cpp index 27ef75e..d6d59d6 100644 --- a/editor/limbo_ai_editor_plugin.cpp +++ b/editor/limbo_ai_editor_plugin.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,21 @@ #include #endif // LIMBOAI_GDEXTENSION +namespace { + +// If built-in resource - switch to the owner scene (open it if not already). +inline void _switch_to_owner_scene_if_builtin(const Ref &p_behavior_tree) { + if (p_behavior_tree.is_valid() && p_behavior_tree->get_path().contains("::")) { + String current_scene = SCENE_TREE()->get_edited_scene_root()->get_scene_file_path(); + String scene_path = p_behavior_tree->get_path().get_slice("::", 0); + if (current_scene != scene_path) { + EditorInterface::get_singleton()->open_scene_from_path(scene_path); + } + } +} + +} // unnamed namespace + //**** LimboAIEditor _FORCE_INLINE_ String _get_script_template_path() { @@ -291,6 +307,8 @@ void LimboAIEditor::_disable_editing() { void LimboAIEditor::edit_bt(const Ref &p_behavior_tree, bool p_force_refresh) { ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "p_behavior_tree is null"); + _switch_to_owner_scene_if_builtin(p_behavior_tree); + if (!p_force_refresh && task_tree->get_bt() == p_behavior_tree) { return; } @@ -882,6 +900,7 @@ void LimboAIEditor::_on_tree_task_activated() { void LimboAIEditor::_on_visibility_changed() { if (task_tree->is_visible_in_tree()) { + _switch_to_owner_scene_if_builtin(task_tree->get_bt()); Ref sel = task_tree->get_selected(); if (sel.is_valid()) { EDIT_RESOURCE(sel); @@ -899,16 +918,6 @@ void LimboAIEditor::_on_visibility_changed() { } } -void LimboAIEditor::_on_header_pressed() { - task_tree->clear_selection(); -#ifdef LIMBOAI_MODULE - if (task_tree->get_bt().is_valid()) { - task_tree->get_bt()->editor_set_section_unfold("blackboard_plan", true); - } -#endif // LIMBOAI_MODULE - EDIT_RESOURCE(task_tree->get_bt()); -} - void LimboAIEditor::_on_save_pressed() { if (task_tree->get_bt().is_null()) { return; @@ -1959,8 +1968,9 @@ void LimboAIEditorPlugin::edit(Object *p_object) { #elif LIMBOAI_GDEXTENSION void LimboAIEditorPlugin::_edit(Object *p_object) { #endif - if (Object::cast_to(p_object)) { - limbo_ai_editor->edit_bt(Object::cast_to(p_object)); + Ref bt = Object::cast_to(p_object); + if (bt.is_valid()) { + limbo_ai_editor->edit_bt(bt); } } diff --git a/editor/limbo_ai_editor_plugin.h b/editor/limbo_ai_editor_plugin.h index 6068aec..92942cb 100644 --- a/editor/limbo_ai_editor_plugin.h +++ b/editor/limbo_ai_editor_plugin.h @@ -241,7 +241,6 @@ private: void _on_tree_task_selected(const Ref &p_task); void _on_tree_task_activated(); void _on_visibility_changed(); - void _on_header_pressed(); void _on_save_pressed(); void _on_history_back(); void _on_history_forward();