diff --git a/project/demos/ability_test_ui/main.tscn b/project/demos/ability_test_ui/main.tscn index c318785..56c9691 100644 --- a/project/demos/ability_test_ui/main.tscn +++ b/project/demos/ability_test_ui/main.tscn @@ -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 @@ -12,3 +15,4 @@ grow_vertical = 2 script = ExtResource("1_8w5uo") [node name="AbilityContainer" type="AbilityContainer" parent="."] +abilities = Array[Ability]([SubResource("Ability_o615e")]) diff --git a/src/editor_plugin/docks/ability/ability_inspector_plugin.cpp b/src/editor_plugin/docks/ability/ability_inspector_plugin.cpp new file mode 100644 index 0000000..8359518 --- /dev/null +++ b/src/editor_plugin/docks/ability/ability_inspector_plugin.cpp @@ -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(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 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; +} diff --git a/src/editor_plugin/docks/ability/ability_inspector_plugin.h b/src/editor_plugin/docks/ability/ability_inspector_plugin.h new file mode 100644 index 0000000..73658aa --- /dev/null +++ b/src/editor_plugin/docks/ability/ability_inspector_plugin.h @@ -0,0 +1,25 @@ +#ifndef GGS_ABILITY_INSPECTOR_PLUGIN_H +#define GGS_ABILITY_INSPECTOR_PLUGIN_H + +#include +#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 usage_flags, bool wide) override; + }; +} + +#endif \ No newline at end of file diff --git a/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.cpp b/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.cpp new file mode 100644 index 0000000..e18b091 --- /dev/null +++ b/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.cpp @@ -0,0 +1,227 @@ +#include +#include + +#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(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; +} diff --git a/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.h b/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.h new file mode 100644 index 0000000..a5393e7 --- /dev/null +++ b/src/editor_plugin/docks/ability/ability_inspector_plugin_editor.h @@ -0,0 +1,74 @@ +#ifndef GGS_ABILITY_INSPECTOR_PLUGIN_EDITOR_H +#define GGS_ABILITY_INSPECTOR_PLUGIN_EDITOR_H + +#include +#include +#include "system/ability/ability.h" +#include "system/tag/tag_tree.h" + +using namespace godot; + +namespace ggs::editor_plugin +{ + class AbilityInspectorPluginEditor : public VBoxContainer + { + GDCLASS(AbilityInspectorPluginEditor, VBoxContainer); + + private: + void _handle_button_pressed(); + void _handle_tags_deselected(const PackedStringArray &p_tags); + void _handle_tags_selected(const PackedStringArray &p_tags); + + protected: + /// @brief Bindings for Godot. + static void _bind_methods(); + /// @brief The ability that is being edited. + Ability *ability; + /// @brief The name of the property that is being edited. + int property_name; + /// @brief Gets the name of the property that is being edited. + /// @return The name of the property that is being edited. + String get_label_name() const; + /// @brief Returns the ability's tags that are being edited. + /// @return The ability's tags that are being edited. + PackedStringArray get_edited_tags() const; + /// @brief Sets the ability's tags that are being edited. + /// @param p_tags The ability's tags that are being edited. + void set_edited_tags(const PackedStringArray &p_tags); + /// @brief The button that expands or collapses the tag tree. + Button *button; + /// @brief The tag tree. + TagTree *tag_tree; + + public: + /// @brief The properties that can be edited. + enum EditedProperty + { + TAGS_ADDED_ON_COOLDOWN_END, + TAGS_ADDED_ON_COOLDOWN_START, + TAGS_ADDED_ON_GRANT, + TAGS_ADDED_ON_ACTIVATION, + TAGS_REMOVED_ON_COOLDOWN_END, + TAGS_REMOVED_ON_COOLDOWN_START, + TAGS_REMOVED_ON_ACTIVATION, + TAGS_REMOVED_ON_BLOCK, + TAGS_REMOVED_ON_CANCEL, + TAGS_REQUIRED_TO_ACTIVATE, + TAGS_REQUIRED_TO_BLOCK, + TAGS_REQUIRED_TO_CANCEL, + TAGS_REQUIRED_TO_GRANT, + }; + + void _ready() override; + /// @brief Sets the ability that is being edited. + /// @param ability The ability that is being edited. + void set_ability(Ability *p_ability); + /// @brief Sets the name of the property that is being edited. + /// @param property_name The name of the property that is being edited. + void set_edited_property(const EditedProperty &p_property_name); + }; +} + +VARIANT_ENUM_CAST(ggs::editor_plugin::AbilityInspectorPluginEditor::EditedProperty); + +#endif diff --git a/src/editor_plugin/ggs_editor_plugin.cpp b/src/editor_plugin/ggs_editor_plugin.cpp index 87d022b..d5453fa 100644 --- a/src/editor_plugin/ggs_editor_plugin.cpp +++ b/src/editor_plugin/ggs_editor_plugin.cpp @@ -3,6 +3,7 @@ #include #include +#include "docks/ability/ability_inspector_plugin.h" #include "docks/attribute/attribute_container_inspector.h" #include "docks/tag/tag_docks.h" #include "main_scene/ggs_main_scene.h" @@ -13,11 +14,11 @@ using namespace ggs::editor_plugin; static MainScene *ggs_tag_main_scene = nullptr; static TagDocks *ggs_tag_docks = nullptr; +static AbilityInspectorPlugin *ggs_ability_inspector_plugin = nullptr; static AttributeContainerInspector *ggs_attribute_container_inspector = nullptr; GGSEditorPlugin::GGSEditorPlugin() { - } GGSEditorPlugin::~GGSEditorPlugin() @@ -28,11 +29,13 @@ void GGSEditorPlugin::_enter_tree() { ggs_tag_main_scene = memnew(MainScene); ggs_tag_docks = memnew(TagDocks); + ggs_ability_inspector_plugin = memnew(AbilityInspectorPlugin); ggs_attribute_container_inspector = memnew(AttributeContainerInspector); EditorInterface::get_singleton()->get_editor_main_screen()->add_child(ggs_tag_main_scene); add_control_to_dock(DOCK_SLOT_RIGHT_UL, ggs_tag_docks); + add_inspector_plugin(ggs_ability_inspector_plugin); add_inspector_plugin(ggs_attribute_container_inspector); ggs_tag_main_scene->set_visible(false); @@ -43,6 +46,7 @@ void GGSEditorPlugin::_exit_tree() EditorInterface::get_singleton()->get_editor_main_screen()->remove_child(ggs_tag_main_scene); remove_control_from_docks(ggs_tag_docks); + remove_inspector_plugin(ggs_ability_inspector_plugin); remove_inspector_plugin(ggs_attribute_container_inspector); memdelete(ggs_tag_docks); @@ -51,7 +55,7 @@ void GGSEditorPlugin::_exit_tree() bool GGSEditorPlugin::_has_main_screen() const { - return true; + return true; } void GGSEditorPlugin::_make_visible(bool p_visible) diff --git a/src/register_types.cpp b/src/register_types.cpp index fcbe4fb..55a92fe 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -27,6 +27,8 @@ #include "system/tag/tag_project_settings.h" /// ggs editor stuff +#include "editor_plugin/docks/ability/ability_inspector_plugin_editor.h" +#include "editor_plugin/docks/ability/ability_inspector_plugin.h" #include "editor_plugin/docks/attribute/attribute_container_inspector_editor.h" #include "editor_plugin/docks/attribute/attribute_container_inspector.h" #include "editor_plugin/docks/tag/tag_docks.h" @@ -75,6 +77,8 @@ void initialize_ggs_module(ModuleInitializationLevel p_level) } else if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { + ClassDB::register_internal_class(); + ClassDB::register_internal_class(); ClassDB::register_internal_class(); ClassDB::register_internal_class(); ClassDB::register_internal_class(); diff --git a/src/system/ability/ability.cpp b/src/system/ability/ability.cpp index 40f429b..2dc3d3b 100644 --- a/src/system/ability/ability.cpp +++ b/src/system/ability/ability.cpp @@ -42,15 +42,15 @@ void Ability::_bind_methods() ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "ability_name"), "set_ability_name", "get_ability_name"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cooldown"), "set_cooldown", "get_cooldown"); ADD_GROUP("Tags", "tags_"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_added_on_activation"), "set_tags_added_on_activation", "get_tags_added_on_activation"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_added_on_cooldown_end"), "set_tags_added_on_cooldown_end", "get_tags_added_on_cooldown_end"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_added_on_cooldown_start"), "set_tags_added_on_cooldown_start", "get_tags_added_on_cooldown_start"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_added_on_grant"), "set_tags_added_on_grant", "get_tags_added_on_grant"); - ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_added_on_activation"), "set_tags_added_on_activation", "get_tags_added_on_activation"); - ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_cooldown_end"), "set_tags_removed_on_cooldown_end", "get_tags_removed_on_cooldown_end"); - ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_cooldown_start"), "set_tags_removed_on_cooldown_start", "get_tags_removed_on_cooldown_start"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_activation"), "set_tags_removed_on_activation", "get_tags_removed_on_activation"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_block"), "set_tags_removed_on_block", "get_tags_removed_on_block"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_cancel"), "set_tags_removed_on_cancel", "get_tags_removed_on_cancel"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_cooldown_end"), "set_tags_removed_on_cooldown_end", "get_tags_removed_on_cooldown_end"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_removed_on_cooldown_start"), "set_tags_removed_on_cooldown_start", "get_tags_removed_on_cooldown_start"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_required_to_activate"), "set_tags_required_to_activate", "get_tags_required_to_activate"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_required_to_block"), "set_tags_required_to_block", "get_tags_required_to_block"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "tags_required_to_cancel"), "set_tags_required_to_cancel", "get_tags_required_to_cancel"); diff --git a/src/system/item/Item.cpp b/src/system/item/Item.cpp new file mode 100644 index 0000000..4210649 --- /dev/null +++ b/src/system/item/Item.cpp @@ -0,0 +1,118 @@ +#include + +#include "Item.h" + +using namespace ggs; + +void ItemStack::_bind_methods() +{ + /// methods binding + ClassDB::bind_method(D_METHOD("get_item"), &ItemStack::get_item); + ClassDB::bind_method(D_METHOD("get_max_quantity"), &ItemStack::get_max_quantity); + ClassDB::bind_method(D_METHOD("get_quantity"), &ItemStack::get_quantity); + ClassDB::bind_method(D_METHOD("set_item", "p_item"), &ItemStack::set_item); + ClassDB::bind_method(D_METHOD("set_max_quantity", "p_max_quantity"), &ItemStack::set_max_quantity); + ClassDB::bind_method(D_METHOD("set_quantity", "p_quantity"), &ItemStack::set_quantity); + + /// properties binding + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "Item"), "set_item", "get_item"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_quantity"), "set_max_quantity", "get_max_quantity"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "quantity"), "set_quantity", "get_quantity"); +} + +Ref ItemStack::get_item() const +{ + return Ref(item); +} + +int ItemStack::get_max_quantity() const +{ + return 0; +} + +void ItemStack::set_item(Item *p_item) +{ + item = p_item; +} + +void ItemStack::set_max_quantity(int p_max_quantity) +{ +} + +int ItemStack::get_quantity() const +{ + return quantity; +} + +void ItemStack::set_quantity(int p_quantity) +{ + quantity = p_quantity; +} + +void ItemStackSetting::_bind_methods() +{ + /// methods binding + ClassDB::bind_method(D_METHOD("get_stacking_type"), &ItemStackSetting::get_stacking_type); + ClassDB::bind_method(D_METHOD("get_maximum_stack_size"), &ItemStackSetting::get_maximum_stack_size); + ClassDB::bind_method(D_METHOD("set_maximum_stack_size", "p_maximum_stack_size"), &ItemStackSetting::set_maximum_stack_size); + ClassDB::bind_method(D_METHOD("set_stacking_type", "p_stacking_type"), &ItemStackSetting::set_stacking_type); + + /// properties binding + ADD_PROPERTY(PropertyInfo(Variant::INT, "stacking_type", PROPERTY_HINT_ENUM, "Finite,Infinite"), "set_stacking_type", "get_stacking_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "maximum_stack_size"), "set_maximum_stack_size", "get_maximum_stack_size"); +} + +int ItemStackSetting::get_maximum_stack_size() const +{ + return maximum_stack_size; +} + +ItemStackSetting::StackingType ItemStackSetting::get_stacking_type() const +{ + return (ItemStackSetting::StackingType)stacking_type; +} + +void Item::_bind_methods() +{ + /// methods binding + ClassDB::bind_method(D_METHOD("get_stack_setting"), &Item::get_stack_setting); + ClassDB::bind_method(D_METHOD("set_stack_setting", "p_stack_setting"), &Item::set_stack_setting); + + /// properties binding + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stack_setting", PROPERTY_HINT_RESOURCE_TYPE, "ItemStackSetting"), "set_stack_setting", "get_stack_setting"); +} + +ItemStackSetting *Item::get_stack_setting() const +{ + return stack_setting; +} + +void ItemStackSetting::set_maximum_stack_size(int p_maximum_stack_size) +{ + maximum_stack_size = p_maximum_stack_size; + + if (Engine::get_singleton()->is_editor_hint()) + { + emit_changed(); + } +} + +void ItemStackSetting::set_stacking_type(ItemStackSetting::StackingType p_stacking_type) +{ + stacking_type = p_stacking_type; + + if (Engine::get_singleton()->is_editor_hint()) + { + emit_changed(); + } +} + +void Item::set_stack_setting(ItemStackSetting *p_stack_setting) +{ + stack_setting = p_stack_setting; + + if (Engine::get_singleton()->is_editor_hint()) + { + emit_changed(); + } +} diff --git a/src/system/item/Item.h b/src/system/item/Item.h new file mode 100644 index 0000000..ccb7e82 --- /dev/null +++ b/src/system/item/Item.h @@ -0,0 +1,103 @@ +#ifndef GGS_ITEM_H +#define GGS_ITEM_H + +#include +#include + +using namespace godot; + +namespace ggs +{ + class Item; + + class ItemStack : public RefCounted + { + GDCLASS(ItemStack, RefCounted); + + protected: + /// @brief Binds methods to Godot. + static void _bind_methods(); + /// @brief The item of the stack. + Item *item; + /// @brief The maximum quantity of the item. + int max_quantity; + /// @brief The quantity of the item. + int quantity; + + public: + /// @brief Gets the item of the stack. + /// @return The item of the stack. + Ref get_item() const; + /// @brief Gets the maximum quantity of the item. + /// @return The maximum quantity of the item. + int get_max_quantity() const; + /// @brief Gets the quantity of the item. + /// @return The quantity of the item. + int get_quantity() const; + /// @brief Sets the item of the stack. + /// @param p_item The item of the stack. + void set_item(Item *p_item); + /// @brief Sets the maximum quantity of the item. + /// @param p_max_quantity The maximum quantity of the item. + void set_max_quantity(int p_max_quantity); + /// @brief Sets the quantity of the item. + /// @param p_quantity The quantity of the item. + void set_quantity(int p_quantity); + }; + + class ItemStackSetting : public Resource + { + GDCLASS(ItemStackSetting, Resource); + + protected: + /// @brief Binds methods to Godot. + static void _bind_methods(); + /// @brief The maximum stack size. + int maximum_stack_size; + /// @brief The stacking type. + int stacking_type; + + public: + enum StackingType + { + FINITE, + INFINITE + }; + + /// @brief Gets the maximum stack size. + /// @return The maximum stack size. + int get_maximum_stack_size() const; + /// @brief Gets the stacking type. + /// @return The stacking type. + StackingType get_stacking_type() const; + /// @brief Sets the maximum stack size. + /// @param p_maximum_stack_size The maximum stack size. + void set_maximum_stack_size(int p_maximum_stack_size); + /// @brief Sets the stacking type. + /// @param p_stacking_type The stacking type. + void set_stacking_type(StackingType p_stacking_type); + }; + + class Item : public Resource + { + GDCLASS(Item, Resource); + + protected: + /// @brief Binds methods to Godot. + static void _bind_methods(); + /// @brief The stack setting of the item. + ItemStackSetting *stack_setting; + + public: + /// @brief Gets the stack setting of the item. + /// @return The stack setting of the item. + ItemStackSetting *get_stack_setting() const; + /// @brief Sets the stack setting of the item. + /// @param p_stack_setting The stack setting of the item. + void set_stack_setting(ItemStackSetting *p_stack_setting); + }; +} + +VARIANT_ENUM_CAST(ggs::ItemStackSetting::StackingType); + +#endif diff --git a/src/system/tag/tag_manager.h b/src/system/tag/tag_manager.h index 016a796..04058dc 100644 --- a/src/system/tag/tag_manager.h +++ b/src/system/tag/tag_manager.h @@ -13,6 +13,7 @@ namespace ggs namespace editor_plugin { class AttributeMainScene; + class AbilityInspectorPluginEditor; class TagDocks; class TagMainScene; } @@ -99,6 +100,7 @@ namespace ggs protected: friend class editor_plugin::AttributeMainScene; + friend class editor_plugin::AbilityInspectorPluginEditor; friend class editor_plugin::TagDocks; friend class editor_plugin::TagMainScene;