/*************************************************************************/ /* prop_2d_instance.cpp */ /*************************************************************************/ /* This file is part of: */ /* PANDEMONIUM ENGINE */ /* https://github.com/Relintai/pandemonium_engine */ /*************************************************************************/ /* Copyright (c) 2022-present Péter Magyar. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* Copyright (c) 2007-2022 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 "prop_2d_instance.h" #include "../mesh_data_resource/nodes/mesh_data_instance.h" #include "scene/3d/light.h" #include "modules/modules_enabled.gen.h" #ifdef MODULE_MESH_DATA_RESOURCE_ENABLED #include "../mesh_data_resource/props_2d/prop_2d_data_mesh_data.h" #endif #include "./props/prop_2d_data_entry.h" #include "./props/prop_2d_data_light.h" #include "./props/prop_2d_data_prop.h" #include "./props/prop_2d_data_scene.h" #include "./props/prop_2d_data_sprite.h" #include "./props/prop_2d_data_tiled_wall_2d.h" #include "tiled_wall/tiled_wall_2d.h" #include "tiled_wall/tiled_wall_2d_data.h" Ref Prop2DInstance::get_prop_data() { return _prop_data; } void Prop2DInstance::set_prop_data(const Ref &data) { if (_prop_data == data) return; _prop_data = data; if (_building) { queue_build(); } else { call_deferred("build"); } } uint32_t Prop2DInstance::get_collision_layer() const { return _collision_layer; } void Prop2DInstance::set_collision_layer(uint32_t p_layer) { _collision_layer = p_layer; collision_layer_changed(); } uint32_t Prop2DInstance::get_collision_mask() const { return _collision_mask; } void Prop2DInstance::set_collision_mask(uint32_t p_mask) { _collision_mask = p_mask; collision_mask_changed(); } void Prop2DInstance::collision_layer_changed() { } void Prop2DInstance::collision_mask_changed() { } void Prop2DInstance::init_materials() { call("_init_materials"); } void Prop2DInstance::_init_materials() { } void Prop2DInstance::build() { call("_build"); } void Prop2DInstance::queue_build() { _build_queued = true; } void Prop2DInstance::build_finished() { call("_build_finished"); } void Prop2DInstance::_build() { _building = true; _build_queued = false; if (!is_inside_tree()) { return; } for (int i = 0; i < get_child_count(); ++i) { Node *n = get_child(i); //this way we won't delete the user's nodes if (n->get_owner() == NULL) { n->queue_delete(); } } if (!_prop_data.is_valid()) return; prop_preprocess(Transform2D(), _prop_data); } void Prop2DInstance::_build_finished() { _building = false; if (_build_queued) { call_deferred("build"); } } void Prop2DInstance::prop_preprocess(Transform2D transform, const Ref &prop) { call("_prop_preprocess", transform, prop); } void Prop2DInstance::_prop_preprocess(Transform2D transform, const Ref &prop) { //don't set owners, to help working with the editor ERR_FAIL_COND(!prop.is_valid()); int count = prop->get_prop_count(); for (int i = 0; i < count; ++i) { Ref e = prop->get_prop(i); if (!e.is_valid()) continue; Transform2D t = transform * e->get_transform_2d(); Ref prop_entry_data = e; if (prop_entry_data.is_valid()) { Ref p = prop_entry_data->get_prop(); if (!p.is_valid()) continue; prop_preprocess(t, p); continue; } Ref tiled_wall_data = e; if (tiled_wall_data.is_valid()) { Node *twn = tiled_wall_data->_processor_get_node_for(t); add_child(twn); continue; } Ref scene_data = e; if (scene_data.is_valid()) { Ref sc = scene_data->get_scene(); if (!sc.is_valid()) continue; Node *n = sc->instance(); add_child(n); Node2D *n2d = Object::cast_to(n); if (n2d) { n2d->set_transform(t); } continue; } Ref light_data = e; if (light_data.is_valid()) { Node *light = light_data->_processor_get_node_for(t); add_child(light); continue; } Ref sprite_data = e; if (sprite_data.is_valid()) { Node *sp = sprite_data->_processor_get_node_for(t); add_child(sp); continue; } #ifdef MODULE_MESH_DATA_RESOURCE_ENABLED //TODO /* Ref mesh_data = e; if (mesh_data.is_valid()) { Ref mdr = mesh_data->get_mesh(); if (!mdr.is_valid()) continue; MeshDataInstance *mdi = memnew(MeshDataInstance); add_child(mdi); mdi->set_transform(t); if (_material.is_valid()) { //duplicate the material, so that textures will work Ref mat = _material->duplicate(); Ref texture = mdi->get_texture(); mdi->set_material(mat); } mdi->set_mesh_data(mdr); continue; } */ #endif } } Prop2DInstance::Prop2DInstance() { _build_queued = false; _building = false; _collision_layer = 1; _collision_mask = 1; } Prop2DInstance::~Prop2DInstance() { _prop_data.unref(); } void Prop2DInstance::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { if (_prop_data.is_valid()) { build(); } } case NOTIFICATION_EXIT_TREE: { } } } void Prop2DInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("get_prop_data"), &Prop2DInstance::get_prop_data); ClassDB::bind_method(D_METHOD("set_prop_data", "value"), &Prop2DInstance::set_prop_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop_data", PROPERTY_HINT_RESOURCE_TYPE, "Prop2DData"), "set_prop_data", "get_prop_data"); ClassDB::bind_method(D_METHOD("get_collision_layer"), &Prop2DInstance::get_collision_layer); ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &Prop2DInstance::set_collision_layer); ClassDB::bind_method(D_METHOD("get_collision_mask"), &Prop2DInstance::get_collision_mask); ClassDB::bind_method(D_METHOD("set_collision_mask", "layer"), &Prop2DInstance::set_collision_mask); ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); BIND_VMETHOD(MethodInfo("_prop_preprocess", PropertyInfo(Variant::TRANSFORM, "tarnsform"), PropertyInfo(Variant::OBJECT, "prop_data", PROPERTY_HINT_RESOURCE_TYPE, "Prop2DData"))); ClassDB::bind_method(D_METHOD("prop_preprocess", "tarnsform", "prop"), &Prop2DInstance::prop_preprocess); ClassDB::bind_method(D_METHOD("_prop_preprocess", "tarnsform", "prop"), &Prop2DInstance::_prop_preprocess); //--- BIND_VMETHOD(MethodInfo("_init_materials")); ClassDB::bind_method(D_METHOD("init_materials"), &Prop2DInstance::init_materials); ClassDB::bind_method(D_METHOD("_init_materials"), &Prop2DInstance::_init_materials); //--- ClassDB::bind_method(D_METHOD("build"), &Prop2DInstance::build); ClassDB::bind_method(D_METHOD("queue_build"), &Prop2DInstance::queue_build); ClassDB::bind_method(D_METHOD("build_finished"), &Prop2DInstance::build_finished); BIND_VMETHOD(MethodInfo("_build")); BIND_VMETHOD(MethodInfo("_build_finished")); ClassDB::bind_method(D_METHOD("_build"), &Prop2DInstance::_build); ClassDB::bind_method(D_METHOD("_build_finished"), &Prop2DInstance::_build_finished); }