Skip to content

Commit 08f7cd0

Browse files
committed
feat: adds ability tagging inspector plugin
1 parent a82c275 commit 08f7cd0

File tree

11 files changed

+660
-6
lines changed

11 files changed

+660
-6
lines changed

project/demos/ability_test_ui/main.tscn

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
[gd_scene load_steps=2 format=3 uid="uid://ye6lunjs1ns2"]
1+
[gd_scene load_steps=3 format=3 uid="uid://ye6lunjs1ns2"]
22

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

5+
[sub_resource type="Ability" id="Ability_o615e"]
6+
tags_added_on_activation = PackedStringArray("enemy.ai.combat.chasing", "enemy.ai.combat.low_health", "enemy.ai.combat.panic")
7+
58
[node name="Main" type="Control"]
69
layout_mode = 3
710
anchors_preset = 15
@@ -12,3 +15,4 @@ grow_vertical = 2
1215
script = ExtResource("1_8w5uo")
1316

1417
[node name="AbilityContainer" type="AbilityContainer" parent="."]
18+
abilities = Array[Ability]([SubResource("Ability_o615e")])
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include "ability_inspector_plugin.h"
2+
3+
#include "ability_inspector_plugin_editor.h"
4+
#include "system/ability/ability.h"
5+
6+
using namespace ggs;
7+
using namespace ggs::editor_plugin;
8+
9+
void AbilityInspectorPlugin::_bind_methods()
10+
{
11+
}
12+
13+
bool AbilityInspectorPlugin::_create_ability_tag_control(Object *p_object, const AbilityInspectorPluginEditor::EditedProperty &p_property)
14+
{
15+
AbilityInspectorPluginEditor *editor = memnew(AbilityInspectorPluginEditor);
16+
17+
editor->set_ability(static_cast<Ability *>(p_object));
18+
editor->set_edited_property(p_property);
19+
20+
add_custom_control(editor);
21+
22+
return true;
23+
}
24+
25+
bool AbilityInspectorPlugin::_can_handle(Object *p_object) const
26+
{
27+
if (p_object == nullptr)
28+
{
29+
return false;
30+
}
31+
32+
return Ability::get_class_static() == p_object->get_class();
33+
}
34+
35+
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)
36+
{
37+
if (object != nullptr && object->get_class() == Ability::get_class_static())
38+
{
39+
if (name == "tags_added_on_cooldown_end")
40+
{
41+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_COOLDOWN_END);
42+
}
43+
else if (name == "tags_added_on_cooldown_start")
44+
{
45+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_COOLDOWN_START);
46+
}
47+
else if (name == "tags_added_on_grant")
48+
{
49+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_GRANT);
50+
}
51+
else if (name == "tags_added_on_activation")
52+
{
53+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_ADDED_ON_ACTIVATION);
54+
}
55+
else if (name == "tags_removed_on_cooldown_end")
56+
{
57+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END);
58+
}
59+
else if (name == "tags_removed_on_cooldown_start")
60+
{
61+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START);
62+
}
63+
else if (name == "tags_removed_on_activation")
64+
{
65+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_ACTIVATION);
66+
}
67+
else if (name == "tags_removed_on_block")
68+
{
69+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_BLOCK);
70+
}
71+
else if (name == "tags_removed_on_cancel")
72+
{
73+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REMOVED_ON_CANCEL);
74+
}
75+
else if (name == "tags_required_to_activate")
76+
{
77+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_ACTIVATE);
78+
}
79+
else if (name == "tags_required_to_block")
80+
{
81+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_BLOCK);
82+
}
83+
else if (name == "tags_required_to_cancel")
84+
{
85+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_CANCEL);
86+
}
87+
else if (name == "tags_required_to_grant")
88+
{
89+
return _create_ability_tag_control(object, AbilityInspectorPluginEditor::EditedProperty::TAGS_REQUIRED_TO_GRANT);
90+
}
91+
}
92+
return false;
93+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef GGS_ABILITY_INSPECTOR_PLUGIN_H
2+
#define GGS_ABILITY_INSPECTOR_PLUGIN_H
3+
4+
#include <godot_cpp/classes/editor_inspector_plugin.hpp>
5+
#include "ability_inspector_plugin_editor.h"
6+
7+
using namespace godot;
8+
9+
namespace ggs::editor_plugin
10+
{
11+
class AbilityInspectorPlugin : public EditorInspectorPlugin
12+
{
13+
GDCLASS(AbilityInspectorPlugin, EditorInspectorPlugin);
14+
15+
protected:
16+
static void _bind_methods();
17+
bool _create_ability_tag_control(Object *p_object, const AbilityInspectorPluginEditor::EditedProperty &p_property);
18+
19+
public:
20+
bool _can_handle(Object *p_object) const override;
21+
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;
22+
};
23+
}
24+
25+
#endif
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#include <godot_cpp/classes/h_box_container.hpp>
2+
#include <godot_cpp/classes/label.hpp>
3+
4+
#include "ability_inspector_plugin_editor.h"
5+
#include "system/attribute/attribute_manager.h"
6+
#include "system/tag/tag_dictionary.h"
7+
#include "system/tag/tag_tree.h"
8+
#include "system/tag/tag_manager.h"
9+
10+
using namespace ggs::editor_plugin;
11+
12+
void AbilityInspectorPluginEditor::_handle_button_pressed()
13+
{
14+
if (tag_tree->is_visible())
15+
{
16+
tag_tree->set_visible(false);
17+
button->set_text(tr("Expand"));
18+
}
19+
else
20+
{
21+
tag_tree->set_visible(true);
22+
button->set_text(tr("Collapse"));
23+
}
24+
}
25+
26+
void AbilityInspectorPluginEditor::_handle_tags_deselected(const PackedStringArray &p_tags)
27+
{
28+
set_edited_tags(p_tags);
29+
}
30+
31+
void AbilityInspectorPluginEditor::_handle_tags_selected(const PackedStringArray &p_tags)
32+
{
33+
set_edited_tags(p_tags);
34+
}
35+
36+
void AbilityInspectorPluginEditor::_bind_methods()
37+
{
38+
/// binds methods
39+
ClassDB::bind_method(D_METHOD("_handle_button_pressed"), &AbilityInspectorPluginEditor::_handle_button_pressed);
40+
ClassDB::bind_method(D_METHOD("_handle_tags_deselected"), &AbilityInspectorPluginEditor::_handle_tags_deselected);
41+
ClassDB::bind_method(D_METHOD("_handle_tags_selected"), &AbilityInspectorPluginEditor::_handle_tags_selected);
42+
43+
/// binds enum constants
44+
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_COOLDOWN_END);
45+
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_COOLDOWN_START);
46+
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_GRANT);
47+
BIND_ENUM_CONSTANT(TAGS_ADDED_ON_ACTIVATION);
48+
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_COOLDOWN_END);
49+
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_COOLDOWN_START);
50+
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_ACTIVATION);
51+
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_BLOCK);
52+
BIND_ENUM_CONSTANT(TAGS_REMOVED_ON_CANCEL);
53+
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_ACTIVATE);
54+
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_BLOCK);
55+
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_CANCEL);
56+
BIND_ENUM_CONSTANT(TAGS_REQUIRED_TO_GRANT);
57+
}
58+
59+
String AbilityInspectorPluginEditor::get_label_name() const
60+
{
61+
switch (property_name)
62+
{
63+
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
64+
return tr("Tags Added On Activation");
65+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
66+
return tr("Tags Added On Cooldown End");
67+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
68+
return tr("Tags Added On Cooldown Start");
69+
case EditedProperty::TAGS_ADDED_ON_GRANT:
70+
return tr("Tags Added On Grant");
71+
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
72+
return tr("Tags Removed On Activation");
73+
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
74+
return tr("Tags Removed On Block");
75+
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
76+
return tr("Tags Removed On Cancel");
77+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
78+
return tr("Tags Removed On Cooldown End");
79+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
80+
return tr("Tags Removed On Cooldown Start");
81+
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
82+
return tr("Tags Required To Activate");
83+
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
84+
return tr("Tags Required To Block");
85+
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
86+
return tr("Tags Required To Cancel");
87+
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
88+
return tr("Tags Required To Grant");
89+
}
90+
return String();
91+
}
92+
93+
PackedStringArray AbilityInspectorPluginEditor::get_edited_tags() const
94+
{
95+
switch (property_name)
96+
{
97+
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
98+
return ability->get_tags_added_on_activation();
99+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
100+
return ability->get_tags_added_on_cooldown_end();
101+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
102+
return ability->get_tags_added_on_cooldown_start();
103+
case EditedProperty::TAGS_ADDED_ON_GRANT:
104+
return ability->get_tags_added_on_grant();
105+
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
106+
return ability->get_tags_removed_on_activation();
107+
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
108+
return ability->get_tags_removed_on_block();
109+
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
110+
return ability->get_tags_removed_on_cancel();
111+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
112+
return ability->get_tags_removed_on_cooldown_end();
113+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
114+
return ability->get_tags_removed_on_cooldown_start();
115+
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
116+
return ability->get_tags_required_to_activate();
117+
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
118+
return ability->get_tags_required_to_block();
119+
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
120+
return ability->get_tags_required_to_cancel();
121+
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
122+
return ability->get_tags_required_to_grant();
123+
}
124+
125+
return PackedStringArray();
126+
}
127+
128+
void AbilityInspectorPluginEditor::set_edited_tags(const PackedStringArray &p_tags)
129+
{
130+
switch (property_name)
131+
{
132+
case EditedProperty::TAGS_ADDED_ON_ACTIVATION:
133+
ability->set_tags_added_on_activation(p_tags);
134+
break;
135+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_END:
136+
ability->set_tags_added_on_cooldown_end(p_tags);
137+
break;
138+
case EditedProperty::TAGS_ADDED_ON_COOLDOWN_START:
139+
ability->set_tags_added_on_cooldown_start(p_tags);
140+
break;
141+
case EditedProperty::TAGS_ADDED_ON_GRANT:
142+
ability->set_tags_added_on_grant(p_tags);
143+
break;
144+
case EditedProperty::TAGS_REMOVED_ON_ACTIVATION:
145+
ability->set_tags_removed_on_activation(p_tags);
146+
break;
147+
case EditedProperty::TAGS_REMOVED_ON_BLOCK:
148+
ability->set_tags_removed_on_block(p_tags);
149+
break;
150+
case EditedProperty::TAGS_REMOVED_ON_CANCEL:
151+
ability->set_tags_removed_on_cancel(p_tags);
152+
break;
153+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_END:
154+
ability->set_tags_removed_on_cooldown_end(p_tags);
155+
break;
156+
case EditedProperty::TAGS_REMOVED_ON_COOLDOWN_START:
157+
ability->set_tags_removed_on_cooldown_start(p_tags);
158+
break;
159+
case EditedProperty::TAGS_REQUIRED_TO_ACTIVATE:
160+
ability->set_tags_required_to_activate(p_tags);
161+
break;
162+
case EditedProperty::TAGS_REQUIRED_TO_BLOCK:
163+
ability->set_tags_required_to_block(p_tags);
164+
break;
165+
case EditedProperty::TAGS_REQUIRED_TO_CANCEL:
166+
ability->set_tags_required_to_cancel(p_tags);
167+
break;
168+
case EditedProperty::TAGS_REQUIRED_TO_GRANT:
169+
ability->set_tags_required_to_grant(p_tags);
170+
break;
171+
}
172+
}
173+
174+
void AbilityInspectorPluginEditor::_ready()
175+
{
176+
set_anchors_and_offsets_preset(PRESET_FULL_RECT);
177+
178+
HBoxContainer *hbox_container = memnew(HBoxContainer);
179+
TagDictionary *tag_dictionary = memnew(TagDictionary);
180+
TagManager *tag_manager = TagManager::get_singleton();
181+
AttributeManager *attribute_manager = AttributeManager::get_singleton();
182+
Label *label = memnew(Label);
183+
184+
button = memnew(Button);
185+
tag_tree = memnew(TagTree);
186+
187+
for (int i = 0; i < tag_manager->dictionaries->size(); i++)
188+
{
189+
Variant variant = tag_manager->dictionaries->operator[](i);
190+
TagDictionary *dictionary = cast_to<TagDictionary>(variant);
191+
192+
if (dictionary != nullptr)
193+
{
194+
tag_dictionary->add_tags(dictionary->get_tags());
195+
}
196+
}
197+
198+
tag_dictionary->remove_tags(attribute_manager->get_attributes());
199+
200+
button->connect("pressed", Callable(this, "_handle_button_pressed"));
201+
button->set_text(tr("Expand"));
202+
hbox_container->add_child(button);
203+
hbox_container->add_child(label);
204+
hbox_container->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
205+
label->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
206+
label->set_text(get_label_name());
207+
tag_tree->connect("tags_deselected", Callable(this, "_handle_tags_deselected"));
208+
tag_tree->connect("tags_selected", Callable(this, "_handle_tags_selected"));
209+
tag_tree->select_many(get_edited_tags());
210+
tag_tree->set_can_be_checked(true);
211+
tag_tree->set_custom_minimum_size(Size2(0, 200));
212+
tag_tree->set_tag_dictionary(tag_dictionary);
213+
tag_tree->set_visible(false);
214+
215+
add_child(hbox_container);
216+
add_child(tag_tree);
217+
}
218+
219+
void AbilityInspectorPluginEditor::set_ability(Ability *p_ability)
220+
{
221+
ability = p_ability;
222+
}
223+
224+
void AbilityInspectorPluginEditor::set_edited_property(const EditedProperty &p_property_name)
225+
{
226+
property_name = p_property_name;
227+
}

0 commit comments

Comments
 (0)