diff options
Diffstat (limited to 'scene/2d/tile_map.cpp')
| -rw-r--r-- | scene/2d/tile_map.cpp | 134 |
1 files changed, 121 insertions, 13 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1f70d4b558..6381526f58 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -686,6 +686,8 @@ void TileMapLayer::_physics_update() { void TileMapLayer::_physics_notify_tilemap_change(TileMapLayer::DirtyFlags p_what) { Transform2D gl_transform = tile_map_node->get_global_transform(); + PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); + bool in_editor = false; #ifdef TOOLS_ENABLED in_editor = Engine::get_singleton()->is_editor_hint(); @@ -693,6 +695,7 @@ void TileMapLayer::_physics_notify_tilemap_change(TileMapLayer::DirtyFlags p_wha if (p_what == DIRTY_FLAGS_TILE_MAP_XFORM) { if (tile_map_node->is_inside_tree() && (!tile_map_node->is_collision_animatable() || in_editor)) { + // Move the collisison shapes along with the TileMap. for (KeyValue<Vector2i, CellData> &kv : tile_map) { const CellData &cell_data = kv.value; @@ -700,12 +703,13 @@ void TileMapLayer::_physics_notify_tilemap_change(TileMapLayer::DirtyFlags p_wha if (body.is_valid()) { Transform2D xform(0, tile_map_node->map_to_local(bodies_coords[body])); xform = gl_transform * xform; - PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } } } } } else if (p_what == DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM) { + // With collisions animatable, move the collisison shapes along with the TileMap only on local xform change (they are synchornized on physics tick instead). if (tile_map_node->is_inside_tree() && tile_map_node->is_collision_animatable() && !in_editor) { for (KeyValue<Vector2i, CellData> &kv : tile_map) { const CellData &cell_data = kv.value; @@ -714,7 +718,22 @@ void TileMapLayer::_physics_notify_tilemap_change(TileMapLayer::DirtyFlags p_wha if (body.is_valid()) { Transform2D xform(0, tile_map_node->map_to_local(bodies_coords[body])); xform = gl_transform * xform; - PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + } + } + } + } + } else if (p_what == DIRTY_FLAGS_TILE_MAP_IN_TREE) { + // Changes in the tree may cause the space to change (e.g. when reparenting to a SubViewport). + if (tile_map_node->is_inside_tree()) { + RID space = tile_map_node->get_world_2d()->get_space(); + + for (KeyValue<Vector2i, CellData> &kv : tile_map) { + const CellData &cell_data = kv.value; + + for (RID body : cell_data.bodies) { + if (body.is_valid()) { + ps->body_set_space(body, space); } } } @@ -2498,6 +2517,11 @@ Vector2i TileMapLayer::get_coords_for_body_rid(RID p_physics_body) const { } TileMapLayer::~TileMapLayer() { + if (!tile_map_node) { + // Temporary layer. + return; + } + in_destructor = true; clear(); internal_update(); @@ -3599,8 +3623,9 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { format = (TileMapLayer::DataFormat)(p_value.operator int64_t()); // Set format used for loading. return true; } + } #ifndef DISABLE_DEPRECATED - } else if (p_name == "tile_data") { // Kept for compatibility reasons. + else if (p_name == "tile_data") { // Kept for compatibility reasons. if (p_value.is_array()) { if (layers.size() == 0) { Ref<TileMapLayer> new_layer; @@ -3614,10 +3639,12 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { return true; } return false; - } else if (p_name == "rendering_quadrant_size") { + } else if (p_name == "cell_quadrant_size") { set_rendering_quadrant_size(p_value); + return true; + } #endif // DISABLE_DEPRECATED - } else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { + else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { int index = components[0].trim_prefix("layer_").to_int(); if (index < 0) { return false; @@ -3674,7 +3701,14 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { if (p_name == "format") { r_ret = TileMapLayer::FORMAT_MAX - 1; // When saving, always save highest format. return true; - } else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { + } +#ifndef DISABLE_DEPRECATED + else if (p_name == "cell_quadrant_size") { // Kept for compatibility reasons. + r_ret = get_rendering_quadrant_size(); + return true; + } +#endif + else if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) { int index = components[0].trim_prefix("layer_").to_int(); if (index < 0 || index >= (int)layers.size()) { return false; @@ -3714,16 +3748,88 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::NIL, "Layers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + +#define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \ + { \ + const String property_name = vformat("layer_%d/" m_name, i); \ + p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, (get(property_name) == property_get_revert(property_name)) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT)); \ + } + for (unsigned int i = 0; i < layers.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("layer_%d/name", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/enabled", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::COLOR, vformat("layer_%d/modulate", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/y_sort_enabled", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::INT, vformat("layer_%d/y_sort_origin", i), PROPERTY_HINT_NONE, "suffix:px")); - p_list->push_back(PropertyInfo(Variant::INT, vformat("layer_%d/z_index", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/navigation_enabled", i), PROPERTY_HINT_NONE)); + MAKE_LAYER_PROPERTY(Variant::STRING, "name", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "enabled", ""); + MAKE_LAYER_PROPERTY(Variant::COLOR, "modulate", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "y_sort_enabled", ""); + MAKE_LAYER_PROPERTY(Variant::INT, "y_sort_origin", "suffix:px"); + MAKE_LAYER_PROPERTY(Variant::INT, "z_index", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "navigation_enabled", ""); p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("layer_%d/tile_data", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } + +#undef MAKE_LAYER_PROPERTY +} + +bool TileMap::_property_can_revert(const StringName &p_name) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() == 2 && components[0].begins_with("layer_")) { + int index = components[0].trim_prefix("layer_").to_int(); + if (index <= 0 || index >= (int)layers.size()) { + return false; + } + + if (components[1] == "name") { + return layers[index]->get_name() != default_layer->get_name(); + } else if (components[1] == "enabled") { + return layers[index]->is_enabled() != default_layer->is_enabled(); + } else if (components[1] == "modulate") { + return layers[index]->get_modulate() != default_layer->get_modulate(); + } else if (components[1] == "y_sort_enabled") { + return layers[index]->is_y_sort_enabled() != default_layer->is_y_sort_enabled(); + } else if (components[1] == "y_sort_origin") { + return layers[index]->get_y_sort_origin() != default_layer->get_y_sort_origin(); + } else if (components[1] == "z_index") { + return layers[index]->get_z_index() != default_layer->get_z_index(); + } else if (components[1] == "navigation_enabled") { + return layers[index]->is_navigation_enabled() != default_layer->is_navigation_enabled(); + } + } + + return false; +} + +bool TileMap::_property_get_revert(const StringName &p_name, Variant &r_property) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() == 2 && components[0].begins_with("layer_")) { + int index = components[0].trim_prefix("layer_").to_int(); + if (index <= 0 || index >= (int)layers.size()) { + return false; + } + + if (components[1] == "name") { + r_property = default_layer->get_name(); + return true; + } else if (components[1] == "enabled") { + r_property = default_layer->is_enabled(); + return true; + } else if (components[1] == "modulate") { + r_property = default_layer->get_modulate(); + return true; + } else if (components[1] == "y_sort_enabled") { + r_property = default_layer->is_y_sort_enabled(); + return true; + } else if (components[1] == "y_sort_origin") { + r_property = default_layer->get_y_sort_origin(); + return true; + } else if (components[1] == "z_index") { + r_property = default_layer->get_z_index(); + return true; + } else if (components[1] == "navigation_enabled") { + r_property = default_layer->is_navigation_enabled(); + return true; + } + } + + return false; } Vector2 TileMap::map_to_local(const Vector2i &p_pos) const { @@ -4747,6 +4853,8 @@ TileMap::TileMap() { new_layer->set_tile_map(this); new_layer->set_layer_index_in_tile_map_node(0); layers.push_back(new_layer); + + default_layer.instantiate(); } TileMap::~TileMap() { |
