Skip to content

Commit

Permalink
feat: adds ability tagging inspector plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
OctoD committed Jan 15, 2024
1 parent a82c275 commit 08f7cd0
Show file tree
Hide file tree
Showing 11 changed files with 660 additions and 6 deletions.
6 changes: 5 additions & 1 deletion project/demos/ability_test_ui/main.tscn
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[gd_scene load_steps=2 format=3 uid="uid://ye6lunjs1ns2"]
[gd_scene load_steps=3 format=3 uid="uid://ye6lunjs1ns2"]

[ext_resource type="Script" path="res://demos/ability_test_ui/main.gd" id="1_8w5uo"]

[sub_resource type="Ability" id="Ability_o615e"]
tags_added_on_activation = PackedStringArray("enemy.ai.combat.chasing", "enemy.ai.combat.low_health", "enemy.ai.combat.panic")

[node name="Main" type="Control"]
layout_mode = 3
anchors_preset = 15
Expand All @@ -12,3 +15,4 @@ grow_vertical = 2
script = ExtResource("1_8w5uo")

[node name="AbilityContainer" type="AbilityContainer" parent="."]
abilities = Array[Ability]([SubResource("Ability_o615e")])
93 changes: 93 additions & 0 deletions src/editor_plugin/docks/ability/ability_inspector_plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include "ability_inspector_plugin.h"

#include "ability_inspector_plugin_editor.h"
#include "system/ability/ability.h"

using namespace ggs;
using namespace ggs::editor_plugin;

void AbilityInspectorPlugin::_bind_methods()
{
}

bool AbilityInspectorPlugin::_create_ability_tag_control(Object *p_object, const AbilityInspectorPluginEditor::EditedProperty &p_property)
{
AbilityInspectorPluginEditor *editor = memnew(AbilityInspectorPluginEditor);

editor->set_ability(static_cast<Ability *>(p_object));
editor->set_edited_property(p_property);

add_custom_control(editor);

return true;
}

bool AbilityInspectorPlugin::_can_handle(Object *p_object) const
{
if (p_object == nullptr)
{
return false;
}

return Ability::get_class_static() == p_object->get_class();
}

bool AbilityInspectorPlugin::_parse_property(Object *object, Variant::Type type, const String &name, PropertyHint hint_type, const String &hint_string, BitField<PropertyUsageFlags> usage_flags, bool wide)
{
if (object != nullptr && object->get_class() == Ability::get_class_static())
{
if (name == "tags_added_on_cooldown_end")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_COOLDOWN_END);
}
else if (name == "tags_added_on_cooldown_start")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_COOLDOWN_START);
}
else if (name == "tags_added_on_grant")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_GRANT);
}
else if (name == "tags_added_on_activation")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_ACTIVATION);
}
else if (name == "tags_removed_on_cooldown_end")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END);
}
else if (name == "tags_removed_on_cooldown_start")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START);
}
else if (name == "tags_removed_on_activation")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_ACTIVATION);
}
else if (name == "tags_removed_on_block")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_BLOCK);
}
else if (name == "tags_removed_on_cancel")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_CANCEL);
}
else if (name == "tags_required_to_activate")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_ACTIVATE);
}
else if (name == "tags_required_to_block")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_BLOCK);
}
else if (name == "tags_required_to_cancel")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_CANCEL);
}
else if (name == "tags_required_to_grant")
{
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_GRANT);
}
}
return false;
}
25 changes: 25 additions & 0 deletions src/editor_plugin/docks/ability/ability_inspector_plugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef GGS_ABILITY_INSPECTOR_PLUGIN_H
#define GGS_ABILITY_INSPECTOR_PLUGIN_H

#include <godot_cpp/classes/editor_inspector_plugin.hpp>
#include "ability_inspector_plugin_editor.h"

using namespace godot;

namespace ggs::editor_plugin
{
class AbilityInspectorPlugin : public EditorInspectorPlugin
{
GDCLASS(AbilityInspectorPlugin, EditorInspectorPlugin);

protected:
static void _bind_methods();
bool _create_ability_tag_control(Object *p_object, const AbilityInspectorPluginEditor::EditedProperty &p_property);

public:
bool _can_handle(Object *p_object) const override;
bool _parse_property(Object *object, Variant::Type type, const String &name, PropertyHint hint_type, const String &hint_string, BitField<PropertyUsageFlags> usage_flags, bool wide) override;
};
}

#endif
227 changes: 227 additions & 0 deletions src/editor_plugin/docks/ability/ability_inspector_plugin_editor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#include <godot_cpp/classes/h_box_container.hpp>
#include <godot_cpp/classes/label.hpp>

#include "ability_inspector_plugin_editor.h"
#include "system/attribute/attribute_manager.h"
#include "system/tag/tag_dictionary.h"
#include "system/tag/tag_tree.h"
#include "system/tag/tag_manager.h"

using namespace ggs::editor_plugin;

void AbilityInspectorPluginEditor::_handle_button_pressed()
{
if (tag_tree->is_visible())
{
tag_tree->set_visible(false);
button->set_text(tr("Expand"));
}
else
{
tag_tree->set_visible(true);
button->set_text(tr("Collapse"));
}
}

void AbilityInspectorPluginEditor::_handle_tags_deselected(const PackedStringArray &p_tags)
{
set_edited_tags(p_tags);
}

void AbilityInspectorPluginEditor::_handle_tags_selected(const PackedStringArray &p_tags)
{
set_edited_tags(p_tags);
}

void AbilityInspectorPluginEditor::_bind_methods()
{
/// binds methods
ClassDB::bind_method(D_METHOD("_handle_button_pressed"), &AbilityInspectorPluginEditor::_handle_button_pressed);
ClassDB::bind_method(D_METHOD("_handle_tags_deselected"), &AbilityInspectorPluginEditor::_handle_tags_deselected);
ClassDB::bind_method(D_METHOD("_handle_tags_selected"), &AbilityInspectorPluginEditor::_handle_tags_selected);

/// binds enum constants
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_COOLDOWN_END);
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_COOLDOWN_START);
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_GRANT);
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_ACTIVATION);
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_COOLDOWN_END);
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_COOLDOWN_START);
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_ACTIVATION);
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_BLOCK);
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_CANCEL);
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_ACTIVATE);
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_BLOCK);
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_CANCEL);
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_GRANT);
}

String AbilityInspectorPluginEditor::get_label_name() const
{
switch (property_name)
{
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
return tr("Tags Added On Activation");
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
return tr("Tags Added On Cooldown End");
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
return tr("Tags Added On Cooldown Start");
case EditedProperty::TAGS_ADDED_ON_GRANT:
return tr("Tags Added On Grant");
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
return tr("Tags Removed On Activation");
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
return tr("Tags Removed On Block");
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
return tr("Tags Removed On Cancel");
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
return tr("Tags Removed On Cooldown End");
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
return tr("Tags Removed On Cooldown Start");
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
return tr("Tags Required To Activate");
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
return tr("Tags Required To Block");
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
return tr("Tags Required To Cancel");
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
return tr("Tags Required To Grant");
}
return String();
}

PackedStringArray AbilityInspectorPluginEditor::get_edited_tags() const
{
switch (property_name)
{
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
return ability->get_tags_added_on_activation();
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
return ability->get_tags_added_on_cooldown_end();
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
return ability->get_tags_added_on_cooldown_start();
case EditedProperty::TAGS_ADDED_ON_GRANT:
return ability->get_tags_added_on_grant();
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
return ability->get_tags_removed_on_activation();
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
return ability->get_tags_removed_on_block();
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
return ability->get_tags_removed_on_cancel();
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
return ability->get_tags_removed_on_cooldown_end();
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
return ability->get_tags_removed_on_cooldown_start();
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
return ability->get_tags_required_to_activate();
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
return ability->get_tags_required_to_block();
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
return ability->get_tags_required_to_cancel();
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
return ability->get_tags_required_to_grant();
}

return PackedStringArray();
}

void AbilityInspectorPluginEditor::set_edited_tags(const PackedStringArray &p_tags)
{
switch (property_name)
{
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
ability->set_tags_added_on_activation(p_tags);
break;
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
ability->set_tags_added_on_cooldown_end(p_tags);
break;
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
ability->set_tags_added_on_cooldown_start(p_tags);
break;
case EditedProperty::TAGS_ADDED_ON_GRANT:
ability->set_tags_added_on_grant(p_tags);
break;
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
ability->set_tags_removed_on_activation(p_tags);
break;
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
ability->set_tags_removed_on_block(p_tags);
break;
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
ability->set_tags_removed_on_cancel(p_tags);
break;
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
ability->set_tags_removed_on_cooldown_end(p_tags);
break;
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
ability->set_tags_removed_on_cooldown_start(p_tags);
break;
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
ability->set_tags_required_to_activate(p_tags);
break;
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
ability->set_tags_required_to_block(p_tags);
break;
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
ability->set_tags_required_to_cancel(p_tags);
break;
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
ability->set_tags_required_to_grant(p_tags);
break;
}
}

void AbilityInspectorPluginEditor::_ready()
{
set_anchors_and_offsets_preset(PRESET_FULL_RECT);

HBoxContainer *hbox_container = memnew(HBoxContainer);
TagDictionary *tag_dictionary = memnew(TagDictionary);
TagManager *tag_manager = TagManager::get_singleton();
AttributeManager *attribute_manager = AttributeManager::get_singleton();
Label *label = memnew(Label);

button = memnew(Button);
tag_tree = memnew(TagTree);

for (int i = 0; i < tag_manager->dictionaries->size(); i++)
{
Variant variant = tag_manager->dictionaries->operator[](i);
TagDictionary *dictionary = cast_to<TagDictionary>(variant);

if (dictionary != nullptr)
{
tag_dictionary->add_tags(dictionary->get_tags());
}
}

tag_dictionary->remove_tags(attribute_manager->get_attributes());

button->connect("pressed", Callable(this, "_handle_button_pressed"));
button->set_text(tr("Expand"));
hbox_container->add_child(button);
hbox_container->add_child(label);
hbox_container->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
label->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
label->set_text(get_label_name());
tag_tree->connect("tags_deselected", Callable(this, "_handle_tags_deselected"));
tag_tree->connect("tags_selected", Callable(this, "_handle_tags_selected"));
tag_tree->select_many(get_edited_tags());
tag_tree->set_can_be_checked(true);
tag_tree->set_custom_minimum_size(Size2(0, 200));
tag_tree->set_tag_dictionary(tag_dictionary);
tag_tree->set_visible(false);

add_child(hbox_container);
add_child(tag_tree);
}

void AbilityInspectorPluginEditor::set_ability(Ability *p_ability)
{
ability = p_ability;
}

void AbilityInspectorPluginEditor::set_edited_property(const EditedProperty &p_property_name)
{
property_name = p_property_name;
}
Loading

0 comments on commit 08f7cd0

Please sign in to comment.