pandemonium_engine/modules/godot_dragonbones/gddragonbones.cpp
2024-09-29 18:28:44 +02:00

1070 lines
31 KiB
C++

#include "gddragonbones.h"
#include "core/io/resource_loader.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/object/method_bind_ext.gen.inc"
#if (VERSION_MAJOR >= 3)
#define CLASS_BIND_GODO ClassDB
#define METH D_METHOD
#define _SCS(val) val
#else
#include "core/globals.h"
#define CLASS_BIND_GODO ObjectTypeDB
#define METH _MD
#endif
GDDragonBones::GDDragonBonesResource::GDDragonBonesResource()
{
p_data_texture_atlas = nullptr;
p_data_bones = nullptr;
}
GDDragonBones::GDDragonBonesResource::~GDDragonBonesResource()
{
if(p_data_texture_atlas)
{
memfree(p_data_texture_atlas);
p_data_texture_atlas = nullptr;
}
if(p_data_bones)
{
memfree(p_data_bones);
p_data_bones = nullptr;
}
}
char* __load_file(const String& _file_path)
{
FileAccess* __p_f = FileAccess::open(_file_path, FileAccess::READ);
ERR_FAIL_COND_V(!__p_f, nullptr);
ERR_FAIL_COND_V(!__p_f->get_len(), nullptr);
// mem
char* __p_data = (char*)memalloc(__p_f->get_len() + 1);
ERR_FAIL_COND_V(!__p_data, nullptr);
__p_f->get_buffer((uint8_t *)__p_data, __p_f->get_len());
__p_data[__p_f->get_len()] = 0x00;
memdelete(__p_f);
return __p_data;
}
void GDDragonBones::GDDragonBonesResource::set_def_texture_path(const String& _path)
{
str_default_tex_path = _path;
}
bool GDDragonBones::GDDragonBonesResource::load_texture_atlas_data(const String& _path)
{
p_data_texture_atlas = __load_file(_path);
ERR_FAIL_COND_V(!p_data_texture_atlas, false);
return true;
}
bool GDDragonBones::GDDragonBonesResource::load_bones_data(const String& _path)
{
p_data_bones = __load_file(_path);
ERR_FAIL_COND_V(!p_data_bones, false);
return true;
}
GDDragonBones::GDDragonBones()
{
p_factory = nullptr;
m_res = RES();
str_curr_anim = "[none]";
p_armature = nullptr;
m_anim_mode = GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_IDLE;
f_progress = 0;
f_speed = 1.f;
b_processing = false;
b_active = true;
b_playing = false;
b_debug = false;
c_loop = -1;
b_inited = false;
b_try_playing = false;
b_flip_x = false;
b_flip_y = false;
b_inherit_child_material = true;
}
GDDragonBones::~GDDragonBones()
{
_cleanup();
}
void GDDragonBones::_cleanup()
{
b_inited = false;
if (p_armature != nullptr) {
p_armature->queue_delete();
if (p_armature->get_parent() == this) {
remove_child(p_armature);
}
p_armature = nullptr;
}
if (p_factory != nullptr) {
memfree(p_factory);
p_factory = nullptr;
}
m_res = RES();
}
void GDDragonBones::dispatch_snd_event(const String& _str_type, const EventObject* _p_value)
{
#if (VERSION_MAJOR >= 3)
if(Engine::get_singleton()->is_editor_hint())
#else
if(get_tree()->is_editor_hint())
#endif
return;
if(_str_type == EventObject::SOUND_EVENT)
emit_signal("dragon_anim_snd_event", String(_p_value->animationState->name.c_str()), String(_p_value->name.c_str()));
}
void GDDragonBones::dispatch_event(const String& _str_type, const EventObject* _p_value)
{
#if (VERSION_MAJOR >= 3)
if(Engine::get_singleton()->is_editor_hint())
#else
if(get_tree()->is_editor_hint())
#endif
return;
if (_str_type == EventObject::START)
emit_signal("dragon_anim_start", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::LOOP_COMPLETE)
emit_signal("dragon_anim_loop_complete", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::COMPLETE)
emit_signal("dragon_anim_complete", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::FRAME_EVENT) {
int int_val = 0;
int float_val = 0;
const char *string_val = std::string("").c_str();
UserData* data = _p_value->getData();
Armature* armature = _p_value->getArmature();
if (data != NULL) {
int_val = _p_value->getData()->getInt(0);
float_val = _p_value->getData()->getFloat(0);
if (!data->getStrings().empty()) {
string_val = _p_value->getData()->getString(0).c_str();
}
}
Dictionary dict = Dictionary();
dict[String("armature")] = String(armature->getName().c_str());
dict[String("animation")] = String(_p_value->animationState->name.c_str());
dict[String("event_name")] = String(_p_value->name.c_str());
dict[String("int")] = int_val;
dict[String("float")] = float_val;
dict[String("string")] = string_val;
emit_signal("dragon_anim_event", dict);
}
else if (_str_type == EventObject::FADE_IN)
emit_signal("dragon_fade_in", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::FADE_IN_COMPLETE)
emit_signal("dragon_fade_in_complete", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::FADE_OUT)
emit_signal("dragon_fade_out", String(_p_value->animationState->name.c_str()));
else if (_str_type == EventObject::FADE_OUT_COMPLETE)
emit_signal("dragon_fade_out_complete", String(_p_value->animationState->name.c_str()));
}
void GDDragonBones::set_resource(Ref<GDDragonBonesResource> _p_data)
{
String __old_texture_path = "";
if(m_res.is_valid())
__old_texture_path = m_res->str_default_tex_path;
else if(_p_data.is_valid())
__old_texture_path = _p_data->str_default_tex_path;
if (m_res == _p_data)
return;
stop();
_cleanup();
p_factory = memnew(GDFactory(this));
m_res = _p_data;
if (m_res.is_null())
{
m_texture_atlas = Ref<TEXTURE_CLASS>();
ERR_PRINT("Null resources");
_change_notify();
return;
}
ERR_FAIL_COND(!m_res->p_data_texture_atlas);
ERR_FAIL_COND(!m_res->p_data_bones);
TextureAtlasData* __p_tad = p_factory->loadTextureAtlasData(m_res->p_data_texture_atlas, nullptr);
ERR_FAIL_COND(!__p_tad);
DragonBonesData* __p_dbd = p_factory->loadDragonBonesData(m_res->p_data_bones);
ERR_FAIL_COND(!__p_dbd);
// build Armature display
const std::vector<std::string>& __r_v_m_names = __p_dbd->getArmatureNames();
ERR_FAIL_COND(!__r_v_m_names.size());
p_armature = static_cast<GDArmatureDisplay*>(p_factory->buildArmatureDisplay(__r_v_m_names[0].c_str()));
// add children armature
p_armature->p_owner = this;
// To support non-texture atlas; I'd want to look around here
if(!m_texture_atlas.is_valid() || __old_texture_path != m_res->str_default_tex_path)
m_texture_atlas = ResourceLoader::load(m_res->str_default_tex_path);
// correction for old version of DB tad files (Zero width, height)
if(m_texture_atlas.is_valid())
{
__p_tad->height = m_texture_atlas->get_height();
__p_tad->width = m_texture_atlas->get_width();
}
// update flip
p_armature->getArmature()->setFlipX(b_flip_x);
p_armature->getArmature()->setFlipY(b_flip_y);
p_armature->add_parent_class(b_debug, m_texture_atlas);
// add main armature
add_child(p_armature);
p_armature->force_parent_owned();
b_inited = true;
// update color and opacity and blending
p_armature->update_childs(true, true);
// update material inheritance
p_armature->update_material_inheritance(b_inherit_child_material);
p_armature->getArmature()->advanceTime(0);
_change_notify();
update();
if (!Engine::get_singleton()->is_editor_hint()) {
_set_process(true);
}
}
Ref<GDDragonBones::GDDragonBonesResource> GDDragonBones::get_resource()
{
return m_res;
}
void GDDragonBones::set_inherit_material(bool _b_enable)
{
b_inherit_child_material = _b_enable;
if(p_armature)
p_armature->update_material_inheritance(b_inherit_child_material);
}
bool GDDragonBones::is_material_inherited() const
{
return b_inherit_child_material;
}
#if (VERSION_MAJOR >= 3)
#else
void GDDragonBones::set_opacity(float _f_opacity)
{
GDOwnerNode::set_opacity(_f_opacity);
if(p_armature)
p_armature->update_childs(true);
}
float GDDragonBones::get_opacity() const
{
#ifdef TOOLS_ENABLED
if(p_armature)
p_armature->update_childs(true);
#endif
return GDOwnerNode::get_opacity();
}
void GDDragonBones::set_blend_mode(CanvasItem::BlendMode _blend_mode)
{
GDOwnerNode::set_blend_mode(_blend_mode);
if(p_armature)
p_armature->update_childs(false, true);
}
CanvasItem::BlendMode GDDragonBones::get_blend_mode() const
{
#ifdef TOOLS_ENABLED
if(p_armature)
p_armature->update_childs(false, true);
#endif
return GDOwnerNode::get_blend_mode();
}
void GDDragonBones::set_modulate(const Color& _p_color)
{
modulate = _p_color;
if(p_armature)
p_armature->update_childs(true);
}
Color GDDragonBones::get_modulate() const
{
return modulate;
}
#endif
void GDDragonBones::fade_in(const String& _name_anim, float _time, int _loop, int _layer, const String& _group, GDArmatureDisplay::AnimFadeOutMode _fade_out_mode)
{
// setup speed
p_factory->set_speed(f_speed);
if(has_anim(_name_anim))
{
p_armature->getAnimation()->fadeIn(_name_anim.ascii().get_data(), _time, _loop, _layer, _group.ascii().get_data(), (AnimationFadeOutMode)_fade_out_mode);
if(!b_playing)
{
b_playing = true;
_set_process(true);
}
}
}
void GDDragonBones::fade_out(const String& _name_anim)
{
if(!b_inited) return;
if(!p_armature->getAnimation()->isPlaying()
|| !p_armature->getAnimation()->hasAnimation(_name_anim.ascii().get_data()))
return;
p_armature->getAnimation()->stop(_name_anim.ascii().get_data());
if(p_armature->getAnimation()->isPlaying())
return;
_set_process(false);
b_playing = false;
_reset();
}
void GDDragonBones::set_active(bool _b_active)
{
if (b_active == _b_active) return;
b_active = _b_active;
_set_process(b_processing, true);
}
bool GDDragonBones::is_active() const
{
return b_active;
}
void GDDragonBones::set_debug(bool _b_debug)
{
b_debug = _b_debug;
if(b_inited)
p_armature->set_debug(b_debug);
}
bool GDDragonBones::is_debug() const
{
return b_debug;
}
void GDDragonBones::flip_x(bool _b_flip)
{
b_flip_x = _b_flip;
if(!p_armature)
return;
p_armature->getArmature()->setFlipX(_b_flip);
p_armature->getArmature()->advanceTime(0);
}
bool GDDragonBones::is_fliped_x() const
{
return b_flip_x;
}
void GDDragonBones::flip_y(bool _b_flip)
{
b_flip_y = _b_flip;
if(!p_armature)
return;
p_armature->getArmature()->setFlipY(_b_flip);
p_armature->getArmature()->advanceTime(0);
}
bool GDDragonBones::is_fliped_y() const
{
return b_flip_y;
}
void GDDragonBones::set_speed(float _f_speed)
{
f_speed = _f_speed;
if(b_inited)
p_factory->set_speed(_f_speed);
}
float GDDragonBones::get_speed() const
{
return f_speed;
}
void GDDragonBones::set_animation_process_mode(GDArmatureDisplay::AnimMode _mode)
{
if (m_anim_mode == _mode)
return;
bool __pr = b_processing;
if (__pr)
_set_process(false);
m_anim_mode = _mode;
if (__pr)
_set_process(true);
}
GDArmatureDisplay::AnimMode GDDragonBones::get_animation_process_mode() const
{
return m_anim_mode;
}
void GDDragonBones::_notification(int _what)
{
switch (_what)
{
case NOTIFICATION_ENTER_TREE:
{
if (!b_processing)
{
set_process(false);
#if (VERSION_MAJOR >= 3)
set_physics_process(false);
#else
set_fixed_process(false);
#endif
}
}
break;
case NOTIFICATION_READY:
{
if (b_playing && b_inited)
play();
}
break;
case NOTIFICATION_PROCESS:
{
if (m_anim_mode == GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_FIXED)
break;
if (b_processing)
p_factory->update(get_process_delta_time());
}
break;
#if (VERSION_MAJOR >= 3)
case NOTIFICATION_PHYSICS_PROCESS:
{
if (m_anim_mode == GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_IDLE)
break;
if (b_processing)
p_factory->update(get_physics_process_delta_time());
}
break;
#else
case NOTIFICATION_FIXED_PROCESS:
{
if (m_anim_mode == ANIMATION_PROCESS_IDLE)
break;
if (b_processing)
p_factory->update(get_fixed_process_delta_time());
}
break;
#endif
case NOTIFICATION_EXIT_TREE:
{
}
break;
}
}
void GDDragonBones::_reset()
{
p_armature->getAnimation()->reset();
}
void GDDragonBones::set_slot_display_index(const String& _slot_name, int _index) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return;
}
p_armature->getSlot(_slot_name.ascii().get_data())->setDisplayIndex(_index);
}
void GDDragonBones::set_slot_by_item_name(const String &_slot_name, const String &_item_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return;
}
const std::vector<DisplayData *> *rawData = p_armature->getSlot(_slot_name.ascii().get_data())->getRawDisplayDatas();
// we only want to update the slot if there's a choice
if (rawData->size() > 1) {
const char *desired_item = _item_name.ascii().get_data();
std::string NONE_STRING("none");
if (NONE_STRING.compare(desired_item) == 0) {
p_armature->getSlot(_slot_name.ascii().get_data())->setDisplayIndex(-1);
}
for (int i = 0; i < rawData->size(); i++) {
DisplayData *display_data = rawData->at(i);
if (display_data->name.compare(desired_item) == 0) {
p_armature->getSlot(_slot_name.ascii().get_data())->setDisplayIndex(i);
return;
}
}
} else {
WARN_PRINT("Slot " + _slot_name + " has only 1 item; refusing to set slot");
return;
}
WARN_PRINT("Slot " + _slot_name + " has no item called \"" + _item_name);
}
void GDDragonBones::set_all_slots_by_item_name(const String& _item_name) {
std::vector<Slot*> slots = p_armature->getArmature()->getSlots();
for (Slot* slot : slots) {
set_slot_by_item_name(String(slot->getName().c_str()), _item_name);
}
}
int GDDragonBones::get_slot_display_index(const String &_slot_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return -1;
}
return p_armature->getSlot(_slot_name.ascii().get_data())->getDisplayIndex();
}
int GDDragonBones::get_total_items_in_slot(const String& _slot_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return -1;
}
return p_armature->getSlot(_slot_name.ascii().get_data())->getDisplayList().size();
}
bool GDDragonBones::has_slot(const String &_slot_name) const {
return p_armature->getSlot(_slot_name.ascii().get_data()) != nullptr;
}
void GDDragonBones::cycle_next_item_in_slot(const String &_slot_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return;
}
int current_slot = get_slot_display_index(_slot_name);
current_slot++;
set_slot_display_index(_slot_name, current_slot < get_total_items_in_slot(_slot_name) ? current_slot : -1);
}
void GDDragonBones::cycle_previous_item_in_slot(const String &_slot_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return;
}
int current_slot = get_slot_display_index(_slot_name);
current_slot--;
set_slot_display_index(_slot_name, current_slot >= -1 ? current_slot : get_total_items_in_slot(_slot_name) - 1);
}
Color GDDragonBones::get_slot_display_color_multiplier(const String &_slot_name) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return Color(-1,-1,-1,-1);
}
ColorTransform transform(p_armature->getSlot(_slot_name.ascii().get_data())->_colorTransform);
Color return_color;
return_color.r = transform.redMultiplier;
return_color.g = transform.greenMultiplier;
return_color.b = transform.blueMultiplier;
return_color.a = transform.alphaMultiplier;
return return_color;
}
void GDDragonBones::set_slot_display_color_multiplier(const String &_slot_name, const Color &_color) {
if (!has_slot(_slot_name)) {
WARN_PRINT("Slot " + _slot_name + " doesn't exist");
return;
}
ColorTransform _new_color;
_new_color.redMultiplier = _color.r;
_new_color.greenMultiplier = _color.g;
_new_color.blueMultiplier = _color.b;
_new_color.alphaMultiplier = _color.a;
p_armature->getSlot(_slot_name.ascii().get_data())->_setColor(_new_color);
}
void GDDragonBones::play(bool _b_play) {
b_playing = _b_play;
if(!_b_play)
{
stop();
return;
}
_set_process(true);
// setup speed
p_factory->set_speed(f_speed);
if(has_anim(str_curr_anim))
{
p_armature->getAnimation()->play(str_curr_anim.ascii().get_data(), c_loop);
b_try_playing = false;
}
else // not finded animation stop playing
{
b_try_playing = true;
str_curr_anim = "[none]";
stop();
}
}
void GDDragonBones::play_from_time(float _f_time)
{
play();
if(b_playing)
p_armature->getAnimation()->gotoAndPlayByTime(str_curr_anim.ascii().get_data(), _f_time, c_loop);
}
void GDDragonBones::play_from_progress(float _f_progress)
{
play();
if(b_playing)
p_armature->getAnimation()->gotoAndPlayByProgress(str_curr_anim.ascii().get_data(), CLAMP(_f_progress, 0, 1.f), c_loop);
}
void GDDragonBones::play_new_animation_from_progress(const String &_str_anim, int _num_times, float _f_progress) {
stop_all();
_set("current_animation", _str_anim);
_set("current_loop", _num_times);
play(true);
play_from_progress(_f_progress);
}
void GDDragonBones::play_new_animation_from_time(const String &_str_anim, int _num_times, float _f_time) {
stop_all();
_set("current_animation", _str_anim);
_set("current_loop", _num_times);
play(true);
play_from_time(_f_time);
}
void GDDragonBones::play_new_animation(const String &_str_anim, int _num_times) {
stop_all();
_set("current_animation", _str_anim);
_set("current_loop", _num_times);
play(true);
}
bool GDDragonBones::has_anim(const String& _str_anim)
{
return p_armature->has_animation(_str_anim);
}
void GDDragonBones::stop(bool _b_all)
{
if(!b_inited) return;
_set_process(false);
b_playing = false;
if(p_armature->getAnimation()->isPlaying())
p_armature->getAnimation()->stop(_b_all?"":str_curr_anim.ascii().get_data());
_reset();
}
const DragonBonesData *GDDragonBones::get_dragonbones_data() const {
const DragonBonesData* data = this->p_armature->getArmature()->getArmatureData()->getParent();
return data;
}
ArmatureData* GDDragonBones::get_armature_data(const String &_armature_name) {
std::map<std::string, ArmatureData *>::const_iterator data = get_dragonbones_data()->armatures.find(_armature_name.ascii().get_data());
if (data == get_dragonbones_data()->armatures.end()) {
return nullptr;
}
return data->second;
}
GDArmatureDisplay *GDDragonBones::get_armature() {
return p_armature;
}
float GDDragonBones::tell()
{
if(b_inited && has_anim(str_curr_anim))
{
AnimationState* __p_state = p_armature->getAnimation()->getState(str_curr_anim.ascii().get_data());
if(__p_state)
return __p_state->getCurrentTime()/__p_state->_duration;
}
return 0;
}
void GDDragonBones::seek(float _f_p)
{
if(b_inited && has_anim(str_curr_anim))
{
f_progress = _f_p;
stop();
auto __c_p = Math::fmod(_f_p, 1.0f);
if (__c_p == 0 && _f_p != 0)
__c_p = 1.0f;
p_armature->getAnimation()->gotoAndStopByProgress(str_curr_anim.ascii().get_data(), __c_p < 0?1.+__c_p:__c_p);
}
}
float GDDragonBones::get_progress() const
{
return f_progress;
}
bool GDDragonBones::is_playing() const
{
return b_inited && b_playing && p_armature->getAnimation()->isPlaying();
}
String GDDragonBones::get_current_animation() const
{
if(!b_inited || !p_armature->getAnimation())
return String("");
return String(p_armature->getAnimation()->getLastAnimationName().c_str());
}
String GDDragonBones::get_current_animation_on_layer(int _layer) const {
if (!b_inited || !p_armature->getAnimation())
return String("");
std::vector<AnimationState *> states = p_armature->getAnimation()->getStates();
for (AnimationState* state : states) {
if (state->layer == _layer) {
return state->getName().c_str();
}
}
return String("");
}
void GDDragonBones::_set_process(bool _b_process, bool _b_force)
{
if (b_processing == _b_process && !_b_force)
return;
switch (m_anim_mode)
{
#if (VERSION_MAJOR >= 3)
case GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_FIXED: set_physics_process(_b_process && b_active); break;
#else
case GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_FIXED: set_fixed_process(_b_process && b_active); break;
#endif
case GDArmatureDisplay::AnimMode::ANIMATION_PROCESS_IDLE: set_process(_b_process && b_active); break;
}
b_processing = _b_process;
}
void GDDragonBones::set_texture(const Ref<TEXTURE_CLASS> &_p_texture) {
if (_p_texture.is_valid()
&& m_texture_atlas.is_valid()
&& (_p_texture == m_texture_atlas
|| m_texture_atlas->get_height() != _p_texture->get_height()
|| m_texture_atlas->get_width() != _p_texture->get_width()))
return;
m_texture_atlas = _p_texture;
#ifdef DEBUG_ENABLED
if (m_texture_atlas.is_valid()) {
#if (VERSION_MAJOR < 6)
m_texture_atlas->set_flags(m_texture_atlas->get_flags()); //remove repeat from texture, it looks bad in sprites
#endif
// m_texture_atlas->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->update);
}
#endif
if(p_armature)
{
p_armature->update_texture_atlas(m_texture_atlas);
update();
}
}
Ref<Texture> GDDragonBones::get_texture() const
{
return m_texture_atlas;
}
bool GDDragonBones::_set(const StringName& _str_name, const Variant& _c_r_value)
{
String name = _str_name;
if (name == "current_animation")
{
if(str_curr_anim == _c_r_value)
return false;
str_curr_anim = _c_r_value;
if (b_inited)
{
if (str_curr_anim == "[none]")
stop();
else if (has_anim(str_curr_anim))
{
if(b_playing || b_try_playing)
play();
else
p_armature->getAnimation()->gotoAndStopByProgress(str_curr_anim.ascii().get_data());
}
}
}
else if (name == "current_loop")
{
c_loop = _c_r_value;
if (b_inited && b_playing)
{
_reset();
play();
}
}
else if (name == "current_progress")
{
seek(_c_r_value);
}
return true;
}
bool GDDragonBones::_get(const StringName& _str_name, Variant &_r_ret) const
{
String __name = _str_name;
if (__name == "current_animation")
_r_ret = str_curr_anim;
else if (__name == "current_loop")
_r_ret = c_loop;
else if (__name == "current_progress")
_r_ret = get_progress();
return true;
}
void GDDragonBones::_bind_methods()
{
#if (VERSION_MAJOR >= 3)
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &GDDragonBones::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &GDDragonBones::get_texture);
#else
ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &GDDragonBones::set_texture);
ClassDB::bind_method(D_METHOD("get_texture:Texture"), &GDDragonBones::get_texture);
#endif
ClassDB::bind_method(D_METHOD("set_resource", "dragonbones"), &GDDragonBones::set_resource);
ClassDB::bind_method(D_METHOD("get_resource"), &GDDragonBones::get_resource);
ClassDB::bind_method(D_METHOD("set_inherit_material"), &GDDragonBones::set_inherit_material);
ClassDB::bind_method(D_METHOD("is_material_inherited"), &GDDragonBones::is_material_inherited);
/*
All these functions act upon the base armature / display; a structure is being formed to make them available for all displays and armatures
*/
#if (VERSION_MAJOR >= 3)
#else
ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &GDDragonBones::set_modulate);
ClassDB::bind_method(D_METHOD("get_modulate"), &GDDragonBones::get_modulate);
ClassDB::bind_method(D_METHOD("set_opacity", "opacity"), &GDDragonBones::set_opacity);
ClassDB::bind_method(D_METHOD("get_opacity"), &GDDragonBones::get_opacity);
ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &GDDragonBones::set_blend_mode);
ClassDB::bind_method(D_METHOD("get_blend_mode"), &GDDragonBones::get_blend_mode);
#endif
ClassDB::bind_method(D_METHOD("fade_in", "anim_name", "time", "loop", "layer", "group", "fade_out_mode"), &GDDragonBones::fade_in);
ClassDB::bind_method(D_METHOD("fade_out", "anim_name"), &GDDragonBones::fade_out);
ClassDB::bind_method(D_METHOD("stop","_b_all"), &GDDragonBones::stop);
ClassDB::bind_method(D_METHOD("stop_all"), &GDDragonBones::stop_all);
ClassDB::bind_method(D_METHOD("reset"), &GDDragonBones::_reset);
ClassDB::bind_method(D_METHOD("has_slot","_slot_name"), &GDDragonBones::has_slot);
ClassDB::bind_method(D_METHOD("set_slot_by_item_name","_slot_name","_item_name"), &GDDragonBones::set_slot_by_item_name);
ClassDB::bind_method(D_METHOD("set_all_slots_by_item_name","_item_name"), &GDDragonBones::set_all_slots_by_item_name);
ClassDB::bind_method(D_METHOD("set_slot_display_index","_slot_name","_index"), &GDDragonBones::set_slot_display_index);
ClassDB::bind_method(D_METHOD("get_slot_display_index","_slot_name"), &GDDragonBones::get_slot_display_index);
ClassDB::bind_method(D_METHOD("get_total_items_in_slot","_slot_name"), &GDDragonBones::get_total_items_in_slot);
ClassDB::bind_method(D_METHOD("set_slot_display_color_multiplier","_slot_name","_color"), &GDDragonBones::set_slot_display_color_multiplier);
ClassDB::bind_method(D_METHOD("get_slot_display_color_multiplier","_slot_name"), &GDDragonBones::get_slot_display_color_multiplier);
ClassDB::bind_method(D_METHOD("cycle_next_item_in_slot","_slot_name"), &GDDragonBones::cycle_next_item_in_slot);
ClassDB::bind_method(D_METHOD("cycle_previous_item_in_slot","_slot_name"), &GDDragonBones::cycle_previous_item_in_slot);
ClassDB::bind_method(D_METHOD("play","_b_play"), &GDDragonBones::play);
ClassDB::bind_method(D_METHOD("play_from_time","_f_time"), &GDDragonBones::play_from_time);
ClassDB::bind_method(D_METHOD("play_from_progress","_f_progress"), &GDDragonBones::play_from_progress);
ClassDB::bind_method(D_METHOD("play_new_animation","_str_anim","_num_times"), &GDDragonBones::play_new_animation);
ClassDB::bind_method(D_METHOD("play_new_animation_from_progress","_str_anim","_num_times","_f_progress"), &GDDragonBones::play_new_animation_from_progress);
ClassDB::bind_method(D_METHOD("play_new_animation_from_time","_str_anim","_num_times","_f_time"), &GDDragonBones::play_new_animation_from_time);
ClassDB::bind_method(D_METHOD("flip_x", "enable_flip"), &GDDragonBones::flip_x);
ClassDB::bind_method(D_METHOD("is_fliped_x"), &GDDragonBones::is_fliped_x);
ClassDB::bind_method(D_METHOD("flip_y", "enable_flip"), &GDDragonBones::flip_y);
ClassDB::bind_method(D_METHOD("is_fliped_y"), &GDDragonBones::is_fliped_y);
ClassDB::bind_method(D_METHOD("set_speed", "speed"), &GDDragonBones::set_speed);
ClassDB::bind_method(D_METHOD("get_speed"), &GDDragonBones::get_speed);
ClassDB::bind_method(D_METHOD("seek", "pos"), &GDDragonBones::seek);
ClassDB::bind_method(D_METHOD("tell"), &GDDragonBones::tell);
ClassDB::bind_method(D_METHOD("get_progress"), &GDDragonBones::get_progress);
ClassDB::bind_method(D_METHOD("has", "name"), &GDDragonBones::has_anim);
ClassDB::bind_method(D_METHOD("is_playing"), &GDDragonBones::is_playing);
ClassDB::bind_method(D_METHOD("get_current_animation"), &GDDragonBones::get_current_animation);
ClassDB::bind_method(D_METHOD("get_current_animation_on_layer","_layer"), &GDDragonBones::get_current_animation_on_layer);
ClassDB::bind_method(D_METHOD("get_armature"), &GDDragonBones::get_armature);
/*
END OF BASE ARMATURE FUNCTIONS
*/
/*
Let's get into the business of playing with child armatures.
*/
ClassDB::bind_method(D_METHOD("set_active", "active"), &GDDragonBones::set_active);
ClassDB::bind_method(D_METHOD("is_active"), &GDDragonBones::is_active);
ClassDB::bind_method(D_METHOD("set_debug", "debug"), &GDDragonBones::set_debug);
ClassDB::bind_method(D_METHOD("is_debug"), &GDDragonBones::is_debug);
ClassDB::bind_method(D_METHOD("set_animation_process_mode","mode"),&GDDragonBones::set_animation_process_mode);
ClassDB::bind_method(D_METHOD("get_animation_process_mode"),&GDDragonBones::get_animation_process_mode);
// This is how we set top level properties
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"), _SCS("get_texture"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug"), _SCS("set_debug"), _SCS("is_debug"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flipX"), _SCS("flip_x"), _SCS("is_fliped_x"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flipY"), _SCS("flip_y"), _SCS("is_fliped_y"));
#if (VERSION_MAJOR >= 3)
#else
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), _SCS("set_modulate"), _SCS("get_modulate"));
#endif
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "GDDragonBonesResource"), _SCS("set_resource"), _SCS("get_resource"));
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_animation_process_mode"), _SCS("get_animation_process_mode"));
ADD_PROPERTY(PropertyInfo(REAL_VARIANT, "current_speed", PROPERTY_HINT_RANGE, "-10,10,0.01"), _SCS("set_speed"), _SCS("get_speed"));
ADD_PROPERTY(PropertyInfo(REAL_VARIANT, "current_progress", PROPERTY_HINT_RANGE, "-100,100,0.010"), _SCS("seek"), _SCS("get_progress"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current_play"), _SCS("play"), _SCS("is_playing"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "childs use this material"), _SCS("set_inherit_material"), _SCS("is_material_inherited"));
ADD_SIGNAL(MethodInfo("dragon_anim_start", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_anim_complete", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_anim_event", PropertyInfo(Variant::DICTIONARY, "event")));
ADD_SIGNAL(MethodInfo("dragon_anim_loop_complete", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_anim_snd_event", PropertyInfo(Variant::STRING, "anim"), PropertyInfo(Variant::STRING, "ev")));
ADD_SIGNAL(MethodInfo("dragon_fade_in", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_fade_in_complete", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_fade_out", PropertyInfo(Variant::STRING, "anim")));
ADD_SIGNAL(MethodInfo("dragon_fade_out_complete", PropertyInfo(Variant::STRING, "anim")));
}
void GDDragonBones::_get_property_list(List<PropertyInfo>* _p_list) const
{
List<String> __l_names;
if (b_inited && p_armature->getAnimation())
{
auto __names = p_armature->getAnimation()->getAnimationNames();
auto __it = __names.cbegin();
while(__it != __names.cend())
{
__l_names.push_back(__it->c_str());
++__it;
}
}
__l_names.sort();
__l_names.push_front("[none]");
String __str_hint;
for (List<String>::Element* __p_E = __l_names.front(); __p_E; __p_E = __p_E->next())
{
if (__p_E != __l_names.front())
__str_hint += ",";
__str_hint += __p_E->get();
}
_p_list->push_back(PropertyInfo(Variant::STRING, "current_animation", PROPERTY_HINT_ENUM, __str_hint));
_p_list->push_back(PropertyInfo(Variant::INT, "current_loop", PROPERTY_HINT_RANGE, "-1,100,1"));
}