2022-09-01 22:20:37 +00:00
|
|
|
/* limbo_ai_editor_plugin.h */
|
|
|
|
|
2022-09-02 12:25:03 +00:00
|
|
|
#ifdef TOOLS_ENABLED
|
2022-09-01 22:20:37 +00:00
|
|
|
#ifndef LIMBO_AI_EDITOR_PLUGIN_H
|
|
|
|
#define LIMBO_AI_EDITOR_PLUGIN_H
|
|
|
|
|
|
|
|
#include "core/object.h"
|
|
|
|
#include "editor/editor_node.h"
|
|
|
|
#include "editor/editor_plugin.h"
|
2022-09-02 22:10:22 +00:00
|
|
|
#include "modules/limboai/bt/behavior_tree.h"
|
2022-09-03 15:00:20 +00:00
|
|
|
#include "modules/limboai/bt/bt_task.h"
|
2022-09-02 12:25:03 +00:00
|
|
|
#include "scene/gui/box_container.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/file_dialog.h"
|
2022-09-02 12:25:03 +00:00
|
|
|
#include "scene/gui/flow_container.h"
|
|
|
|
#include "scene/gui/line_edit.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/popup_menu.h"
|
2022-09-06 11:28:25 +00:00
|
|
|
#include "scene/gui/split_container.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/tree.h"
|
2022-09-05 14:39:40 +00:00
|
|
|
#include "scene/resources/texture.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
|
|
|
|
class TaskTree : public Control {
|
|
|
|
GDCLASS(TaskTree, Control);
|
|
|
|
|
|
|
|
private:
|
|
|
|
Tree *tree;
|
|
|
|
Ref<BehaviorTree> bt;
|
|
|
|
Ref<BTTask> last_selected;
|
2022-09-03 15:00:20 +00:00
|
|
|
bool editable;
|
2022-09-01 22:20:37 +00:00
|
|
|
|
|
|
|
TreeItem *_create_tree(const Ref<BTTask> &p_task, TreeItem *p_parent, int p_idx = -1);
|
|
|
|
void _update_item(TreeItem *p_item);
|
|
|
|
void _update_tree();
|
|
|
|
TreeItem *_find_item(const Ref<BTTask> &p_task) const;
|
|
|
|
|
|
|
|
void _on_item_selected();
|
|
|
|
void _on_item_rmb_selected(const Vector2 &p_pos);
|
2022-09-03 15:13:15 +00:00
|
|
|
void _on_task_changed();
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2022-09-03 15:00:20 +00:00
|
|
|
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
|
|
|
|
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
|
|
|
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
protected:
|
|
|
|
static void _bind_methods();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void load_bt(const Ref<BehaviorTree> &p_behavior_tree);
|
|
|
|
Ref<BehaviorTree> get_bt() const { return bt; }
|
|
|
|
void update_tree() { _update_tree(); }
|
|
|
|
void update_task(const Ref<BTTask> &p_task);
|
|
|
|
Ref<BTTask> get_selected() const;
|
|
|
|
void deselect();
|
|
|
|
|
|
|
|
TaskTree();
|
|
|
|
~TaskTree();
|
|
|
|
};
|
|
|
|
|
2022-09-02 12:25:03 +00:00
|
|
|
class TaskSection : public VBoxContainer {
|
|
|
|
GDCLASS(TaskSection, VBoxContainer);
|
|
|
|
|
|
|
|
private:
|
|
|
|
FlowContainer *tasks_container;
|
|
|
|
Button *section_header;
|
|
|
|
|
|
|
|
void _on_task_button_pressed(const StringName &p_task);
|
|
|
|
void _on_header_pressed();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static void _bind_methods();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void set_filter(String p_filter);
|
2022-09-02 17:30:32 +00:00
|
|
|
void add_task_button(String p_name, const Ref<Texture> &icon, Variant p_meta);
|
2022-09-02 12:25:03 +00:00
|
|
|
|
2022-09-02 17:30:32 +00:00
|
|
|
TaskSection(String p_category_name, EditorNode *p_editor);
|
2022-09-02 12:25:03 +00:00
|
|
|
~TaskSection();
|
|
|
|
};
|
|
|
|
|
|
|
|
class TaskPanel : public PanelContainer {
|
|
|
|
GDCLASS(TaskPanel, PanelContainer)
|
|
|
|
|
|
|
|
private:
|
|
|
|
EditorNode *editor;
|
|
|
|
LineEdit *filter_edit;
|
|
|
|
VBoxContainer *sections;
|
|
|
|
|
2022-09-02 17:30:32 +00:00
|
|
|
void _populate_core_tasks_from_class(const StringName &p_base_class, List<String> *p_task_classes);
|
2022-09-02 22:10:22 +00:00
|
|
|
void _populate_scripted_tasks_from_dir(String p_path, List<String> *p_task_classes);
|
2022-09-02 12:25:03 +00:00
|
|
|
void _on_task_button_pressed(const StringName &p_task);
|
|
|
|
void _on_filter_text_changed(String p_text);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
static void _bind_methods();
|
|
|
|
|
|
|
|
public:
|
2022-09-05 15:56:38 +00:00
|
|
|
void refresh();
|
|
|
|
|
2022-09-02 12:25:03 +00:00
|
|
|
TaskPanel(EditorNode *p_editor);
|
|
|
|
~TaskPanel();
|
|
|
|
};
|
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
class LimboAIEditor : public Control {
|
|
|
|
GDCLASS(LimboAIEditor, Control);
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum Action {
|
|
|
|
ACTION_REMOVE,
|
|
|
|
ACTION_MOVE_UP,
|
|
|
|
ACTION_MOVE_DOWN,
|
|
|
|
ACTION_DUPLICATE,
|
|
|
|
ACTION_MAKE_ROOT,
|
|
|
|
};
|
|
|
|
|
|
|
|
EditorNode *editor;
|
2022-09-02 13:43:54 +00:00
|
|
|
Vector<Ref<BehaviorTree>> history;
|
|
|
|
int idx_history;
|
2022-09-03 12:01:13 +00:00
|
|
|
Set<Ref<BehaviorTree>> dirty;
|
2022-09-02 13:43:54 +00:00
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
Button *header;
|
2022-09-06 11:28:25 +00:00
|
|
|
HSplitContainer *hsc;
|
2022-09-01 22:20:37 +00:00
|
|
|
TaskTree *task_tree;
|
2022-09-05 19:57:24 +00:00
|
|
|
Panel *usage_hint;
|
2022-09-01 22:20:37 +00:00
|
|
|
PopupMenu *menu;
|
|
|
|
FileDialog *save_dialog;
|
|
|
|
FileDialog *load_dialog;
|
2022-09-02 13:43:54 +00:00
|
|
|
Button *history_back;
|
|
|
|
Button *history_forward;
|
2022-09-05 15:56:38 +00:00
|
|
|
TaskPanel *task_panel;
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2022-09-03 12:11:47 +00:00
|
|
|
void _add_task(const Ref<BTTask> &p_task);
|
|
|
|
_FORCE_INLINE_ void _add_task_with_prototype(const Ref<BTTask> &p_prototype) { _add_task(p_prototype->clone()); }
|
2022-09-01 22:20:37 +00:00
|
|
|
void _update_header();
|
2022-09-02 13:43:54 +00:00
|
|
|
void _update_history_buttons();
|
2022-09-01 22:20:37 +00:00
|
|
|
void _new_bt();
|
|
|
|
void _save_bt(String p_path);
|
|
|
|
void _load_bt(String p_path);
|
2022-09-03 12:01:13 +00:00
|
|
|
void _mark_as_dirty(bool p_dirty);
|
2022-09-01 22:20:37 +00:00
|
|
|
|
|
|
|
void _on_tree_rmb(const Vector2 &p_menu_pos);
|
|
|
|
void _on_action_selected(int p_id);
|
2022-09-02 12:25:03 +00:00
|
|
|
void _on_tree_task_selected(const Ref<BTTask> &p_task) const;
|
2022-09-01 22:20:37 +00:00
|
|
|
void _on_visibility_changed() const;
|
|
|
|
void _on_header_pressed() const;
|
|
|
|
void _on_save_pressed();
|
2022-09-02 22:10:22 +00:00
|
|
|
void _on_panel_task_selected(String p_task);
|
2022-09-02 13:43:54 +00:00
|
|
|
void _on_history_back();
|
|
|
|
void _on_history_forward();
|
2022-09-03 15:00:20 +00:00
|
|
|
void _on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task, int p_type);
|
2022-09-01 22:20:37 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
static void _bind_methods();
|
|
|
|
|
2022-09-06 11:28:25 +00:00
|
|
|
void _notification(int p_what);
|
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
public:
|
2022-09-05 14:39:40 +00:00
|
|
|
static Ref<Texture> get_task_icon(String p_script_path_or_class);
|
|
|
|
|
2022-09-05 19:57:24 +00:00
|
|
|
void edit_bt(Ref<BehaviorTree> p_behavior_tree);
|
|
|
|
|
2022-09-03 12:01:13 +00:00
|
|
|
void apply_changes();
|
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
LimboAIEditor(EditorNode *p_editor);
|
|
|
|
~LimboAIEditor();
|
|
|
|
};
|
|
|
|
|
|
|
|
class LimboAIEditorPlugin : public EditorPlugin {
|
|
|
|
GDCLASS(LimboAIEditorPlugin, EditorPlugin);
|
|
|
|
|
|
|
|
private:
|
|
|
|
EditorNode *editor;
|
|
|
|
LimboAIEditor *limbo_ai_editor;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void _notification(int p_notification);
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual String get_name() const { return "LimboAI"; }
|
|
|
|
virtual const Ref<Texture> get_icon() const;
|
|
|
|
bool has_main_screen() const { return true; }
|
|
|
|
virtual void make_visible(bool p_visible);
|
2022-09-03 12:01:13 +00:00
|
|
|
virtual void apply_changes();
|
2022-09-05 19:57:24 +00:00
|
|
|
virtual void edit(Object *p_object);
|
|
|
|
virtual bool handles(Object *p_object) const;
|
2022-09-01 22:20:37 +00:00
|
|
|
|
|
|
|
LimboAIEditorPlugin(EditorNode *p_editor);
|
|
|
|
~LimboAIEditorPlugin();
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // TOOLS_ENABLED
|
|
|
|
|
|
|
|
#endif // LIMBO_AI_EDITOR_PLUGIN_H
|