/**************************************************************************/ /* skeleton_modification_stack_2d.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /**************************************************************************/ /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ #include "skeleton_modification_stack_2d.h" #include "scene/2d/skeleton_2d.h" void SkeletonModificationStack2D::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < modifications.size(); i++) { p_list->push_back( PropertyInfo(Variant::OBJECT, "modifications/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModification2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); } } bool SkeletonModificationStack2D::_set(const StringName &p_path, const Variant &p_value) { String path = p_path; if (path.begins_with("modifications/")) { int mod_idx = path.get_slicec('/', 1).to_int(); set_modification(mod_idx, p_value); return true; } return true; } bool SkeletonModificationStack2D::_get(const StringName &p_path, Variant &r_ret) const { String path = p_path; if (path.begins_with("modifications/")) { int mod_idx = path.get_slicec('/', 1).to_int(); r_ret = get_modification(mod_idx); return true; } return true; } void SkeletonModificationStack2D::setup() { if (is_setup) { return; } if (skeleton != nullptr) { is_setup = true; for (int i = 0; i < modifications.size(); i++) { if (!modifications[i].is_valid()) { continue; } modifications.get(i)->_setup_modification(this); } #ifdef TOOLS_ENABLED set_editor_gizmos_dirty(true); #endif // TOOLS_ENABLED } else { WARN_PRINT("Cannot setup SkeletonModificationStack2D: no Skeleton2D set!"); } } void SkeletonModificationStack2D::execute(float p_delta, int p_execution_mode) { ERR_FAIL_COND_MSG(!is_setup || skeleton == nullptr || is_queued_for_deletion(), "Modification stack is not properly setup and therefore cannot execute!"); if (!skeleton->is_inside_tree()) { ERR_PRINT_ONCE("Skeleton is not inside SceneTree! Cannot execute modification!"); return; } if (!enabled) { return; } for (int i = 0; i < modifications.size(); i++) { if (!modifications[i].is_valid()) { continue; } if (modifications[i]->get_execution_mode() == p_execution_mode) { modifications.get(i)->_execute(p_delta); } } } void SkeletonModificationStack2D::draw_editor_gizmos() { if (!is_setup) { return; } if (editor_gizmo_dirty) { for (int i = 0; i < modifications.size(); i++) { if (!modifications[i].is_valid()) { continue; } if (modifications[i]->editor_draw_gizmo) { modifications.get(i)->_draw_editor_gizmo(); } } skeleton->draw_set_transform(Vector2(0, 0)); editor_gizmo_dirty = false; } } void SkeletonModificationStack2D::set_editor_gizmos_dirty(bool p_dirty) { if (!is_setup) { return; } if (!editor_gizmo_dirty && p_dirty) { editor_gizmo_dirty = p_dirty; if (skeleton) { skeleton->queue_redraw(); } } else { editor_gizmo_dirty = p_dirty; } } void SkeletonModificationStack2D::enable_all_modifications(bool p_enabled) { for (int i = 0; i < modifications.size(); i++) { if (!modifications[i].is_valid()) { continue; } modifications.get(i)->set_enabled(p_enabled); } } Ref<SkeletonModification2D> SkeletonModificationStack2D::get_modification(int p_mod_idx) const { ERR_FAIL_INDEX_V(p_mod_idx, modifications.size(), nullptr); return modifications[p_mod_idx]; } void SkeletonModificationStack2D::add_modification(Ref<SkeletonModification2D> p_mod) { ERR_FAIL_COND(!p_mod.is_valid()); p_mod->_setup_modification(this); modifications.push_back(p_mod); #ifdef TOOLS_ENABLED set_editor_gizmos_dirty(true); #endif // TOOLS_ENABLED } void SkeletonModificationStack2D::delete_modification(int p_mod_idx) { ERR_FAIL_INDEX(p_mod_idx, modifications.size()); modifications.remove_at(p_mod_idx); #ifdef TOOLS_ENABLED set_editor_gizmos_dirty(true); #endif // TOOLS_ENABLED } void SkeletonModificationStack2D::set_modification(int p_mod_idx, Ref<SkeletonModification2D> p_mod) { ERR_FAIL_INDEX(p_mod_idx, modifications.size()); if (p_mod.is_null()) { modifications.write[p_mod_idx] = Ref<SkeletonModification2D>(); } else { modifications.write[p_mod_idx] = p_mod; p_mod->_setup_modification(this); } #ifdef TOOLS_ENABLED set_editor_gizmos_dirty(true); #endif // TOOLS_ENABLED } void SkeletonModificationStack2D::set_modification_count(int p_count) { ERR_FAIL_COND_MSG(p_count < 0, "Modification count cannot be less than zero."); modifications.resize(p_count); notify_property_list_changed(); #ifdef TOOLS_ENABLED set_editor_gizmos_dirty(true); #endif // TOOLS_ENABLED } int SkeletonModificationStack2D::get_modification_count() const { return modifications.size(); } void SkeletonModificationStack2D::set_skeleton(Skeleton2D *p_skeleton) { skeleton = p_skeleton; } Skeleton2D *SkeletonModificationStack2D::get_skeleton() const { return skeleton; } bool SkeletonModificationStack2D::get_is_setup() const { return is_setup; } void SkeletonModificationStack2D::set_enabled(bool p_enabled) { enabled = p_enabled; } bool SkeletonModificationStack2D::get_enabled() const { return enabled; } void SkeletonModificationStack2D::set_strength(float p_strength) { ERR_FAIL_COND_MSG(p_strength < 0, "Strength cannot be less than zero!"); ERR_FAIL_COND_MSG(p_strength > 1, "Strength cannot be more than one!"); strength = p_strength; } float SkeletonModificationStack2D::get_strength() const { return strength; } void SkeletonModificationStack2D::_bind_methods() { ClassDB::bind_method(D_METHOD("setup"), &SkeletonModificationStack2D::setup); ClassDB::bind_method(D_METHOD("execute", "delta", "execution_mode"), &SkeletonModificationStack2D::execute); ClassDB::bind_method(D_METHOD("enable_all_modifications", "enabled"), &SkeletonModificationStack2D::enable_all_modifications); ClassDB::bind_method(D_METHOD("get_modification", "mod_idx"), &SkeletonModificationStack2D::get_modification); ClassDB::bind_method(D_METHOD("add_modification", "modification"), &SkeletonModificationStack2D::add_modification); ClassDB::bind_method(D_METHOD("delete_modification", "mod_idx"), &SkeletonModificationStack2D::delete_modification); ClassDB::bind_method(D_METHOD("set_modification", "mod_idx", "modification"), &SkeletonModificationStack2D::set_modification); ClassDB::bind_method(D_METHOD("set_modification_count", "count"), &SkeletonModificationStack2D::set_modification_count); ClassDB::bind_method(D_METHOD("get_modification_count"), &SkeletonModificationStack2D::get_modification_count); ClassDB::bind_method(D_METHOD("get_is_setup"), &SkeletonModificationStack2D::get_is_setup); ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &SkeletonModificationStack2D::set_enabled); ClassDB::bind_method(D_METHOD("get_enabled"), &SkeletonModificationStack2D::get_enabled); ClassDB::bind_method(D_METHOD("set_strength", "strength"), &SkeletonModificationStack2D::set_strength); ClassDB::bind_method(D_METHOD("get_strength"), &SkeletonModificationStack2D::get_strength); ClassDB::bind_method(D_METHOD("get_skeleton"), &SkeletonModificationStack2D::get_skeleton); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "0, 1, 0.001"), "set_strength", "get_strength"); ADD_PROPERTY(PropertyInfo(Variant::INT, "modification_count", PROPERTY_HINT_RANGE, "0, 100, 1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Modifications,modifications/"), "set_modification_count", "get_modification_count"); } SkeletonModificationStack2D::SkeletonModificationStack2D() { }