summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scene/2d/tile_map.cpp60
-rw-r--r--scene/2d/tile_map.h6
-rw-r--r--scene/2d/tile_map_layer.cpp338
-rw-r--r--scene/2d/tile_map_layer.h64
-rw-r--r--scene/2d/tile_map_layer_group.cpp8
5 files changed, 294 insertions, 182 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 48fe2afccc..f8737730ba 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -105,7 +105,7 @@ void TileMap::set_rendering_quadrant_size(int p_size) {
rendering_quadrant_size = p_size;
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE);
+ layer->set_rendering_quadrant_size(p_size);
}
_emit_changed();
}
@@ -214,11 +214,10 @@ void TileMap::add_layer(int p_to_pos) {
TileMapLayer *new_layer = memnew(TileMapLayer);
layers.insert(p_to_pos, new_layer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
- new_layer->force_parent_owned();
new_layer->set_name(vformat("Layer%d", p_to_pos));
move_child(new_layer, p_to_pos);
for (uint32_t i = 0; i < layers.size(); i++) {
- layers[i]->set_layer_index_in_tile_map_node(i);
+ layers[i]->set_as_tile_map_internal_node(i);
}
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
@@ -239,7 +238,7 @@ void TileMap::move_layer(int p_layer, int p_to_pos) {
layers.remove_at(p_to_pos < p_layer ? p_layer + 1 : p_layer);
for (uint32_t i = 0; i < layers.size(); i++) {
move_child(layers[i], i);
- layers[i]->set_layer_index_in_tile_map_node(i);
+ layers[i]->set_as_tile_map_internal_node(i);
}
notify_property_list_changed();
@@ -255,7 +254,7 @@ void TileMap::remove_layer(int p_layer) {
layers[p_layer]->queue_free();
layers.remove_at(p_layer);
for (uint32_t i = 0; i < layers.size(); i++) {
- layers[i]->set_layer_index_in_tile_map_node(i);
+ layers[i]->set_as_tile_map_internal_node(i);
}
notify_property_list_changed();
@@ -350,7 +349,7 @@ void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_colli
}
collision_visibility_mode = p_show_collision;
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE);
+ layer->set_collision_visibility_mode(TileMapLayer::VisibilityMode(p_show_collision));
}
_emit_changed();
}
@@ -365,7 +364,7 @@ void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navi
}
navigation_visibility_mode = p_show_navigation;
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE);
+ layer->set_navigation_visibility_mode(TileMapLayer::VisibilityMode(p_show_navigation));
}
_emit_changed();
}
@@ -380,7 +379,7 @@ void TileMap::set_y_sort_enabled(bool p_enable) {
}
Node2D::set_y_sort_enabled(p_enable);
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED);
+ layer->set_y_sort_enabled(p_enable);
}
_emit_changed();
update_configuration_warnings();
@@ -497,10 +496,10 @@ void TileMap::update_internals() {
void TileMap::notify_runtime_tile_data_update(int p_layer) {
if (p_layer >= 0) {
- TILEMAP_CALL_FOR_LAYER(p_layer, notify_tile_map_change, TileMapLayer::DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE);
+ TILEMAP_CALL_FOR_LAYER(p_layer, notify_runtime_tile_data_update);
} else {
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE);
+ layer->notify_runtime_tile_data_update();
}
}
}
@@ -539,9 +538,8 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
if (layers.size() == 0) {
TileMapLayer *new_layer = memnew(TileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
- new_layer->force_parent_owned();
+ new_layer->set_as_tile_map_internal_node(0);
new_layer->set_name("Layer0");
- new_layer->set_layer_index_in_tile_map_node(0);
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
layers.push_back(new_layer);
}
@@ -565,9 +563,8 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
while (index >= (int)layers.size()) {
TileMapLayer *new_layer = memnew(TileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
- new_layer->force_parent_owned();
+ new_layer->set_as_tile_map_internal_node(index);
new_layer->set_name(vformat("Layer%d", index));
- new_layer->set_layer_index_in_tile_map_node(index);
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
layers.push_back(new_layer);
}
@@ -795,46 +792,34 @@ Rect2i TileMap::get_used_rect() const {
// --- Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems ---
void TileMap::set_light_mask(int p_light_mask) {
- // Occlusion: set light mask.
+ // Set light mask for occlusion and applies it to all layers too.
CanvasItem::set_light_mask(p_light_mask);
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_LIGHT_MASK);
+ layer->set_light_mask(p_light_mask);
}
}
-void TileMap::set_material(const Ref<Material> &p_material) {
- // Set material for the whole tilemap.
- CanvasItem::set_material(p_material);
-
- // Update material for the whole tilemap.
+void TileMap::set_self_modulate(const Color &p_self_modulate) {
+ // Set self_modulation and applies it to all layers too.
+ CanvasItem::set_self_modulate(p_self_modulate);
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_MATERIAL);
- }
-}
-
-void TileMap::set_use_parent_material(bool p_use_parent_material) {
- // Set use_parent_material for the whole tilemap.
- CanvasItem::set_use_parent_material(p_use_parent_material);
-
- // Update use_parent_material for the whole tilemap.
- for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL);
+ layer->set_self_modulate(p_self_modulate);
}
}
void TileMap::set_texture_filter(TextureFilter p_texture_filter) {
- // Set a default texture filter for the whole tilemap.
+ // Set a default texture filter and applies it to all layers too.
CanvasItem::set_texture_filter(p_texture_filter);
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER);
+ layer->set_texture_filter(p_texture_filter);
}
}
void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
- // Set a default texture repeat for the whole tilemap.
+ // Set a default texture repeat and applies it to all layers too.
CanvasItem::set_texture_repeat(p_texture_repeat);
for (TileMapLayer *layer : layers) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT);
+ layer->set_texture_repeat(p_texture_repeat);
}
}
@@ -1003,11 +988,10 @@ void TileMap::_bind_methods() {
TileMap::TileMap() {
TileMapLayer *new_layer = memnew(TileMapLayer);
add_child(new_layer, false, INTERNAL_MODE_FRONT);
+ new_layer->set_as_tile_map_internal_node(0);
new_layer->set_name("Layer0");
- new_layer->set_layer_index_in_tile_map_node(0);
new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed));
layers.push_back(new_layer);
-
default_layer = memnew(TileMapLayer);
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index c9844f29af..edea90fa95 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -46,9 +46,10 @@ enum TileMapDataFormat {
};
class TileMap : public TileMapLayerGroup {
- GDCLASS(TileMap, TileMapLayerGroup);
+ GDCLASS(TileMap, TileMapLayerGroup)
public:
+ // Kept for compatibility, but should use TileMapLayer::VisibilityMode instead.
enum VisibilityMode {
VISIBILITY_MODE_DEFAULT,
VISIBILITY_MODE_FORCE_SHOW,
@@ -187,8 +188,7 @@ public:
// Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems.
virtual void set_light_mask(int p_light_mask) override;
- virtual void set_material(const Ref<Material> &p_material) override;
- virtual void set_use_parent_material(bool p_use_parent_material) override;
+ virtual void set_self_modulate(const Color &p_self_modulate) override;
virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter) override;
virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) override;
diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp
index c9431f53d8..c7aa4c2be4 100644
--- a/scene/2d/tile_map_layer.cpp
+++ b/scene/2d/tile_map_layer.cpp
@@ -40,10 +40,6 @@
#include "servers/navigation_server_3d.h"
#endif // DEBUG_ENABLED
-TileMap *TileMapLayer::_fetch_tilemap() const {
- return TileMap::cast_to<TileMap>(get_parent());
-}
-
#ifdef DEBUG_ENABLED
/////////////////////////////// Debug //////////////////////////////////////////
constexpr int TILE_MAP_DEBUG_QUADRANT_SIZE = 16;
@@ -183,7 +179,6 @@ void TileMapLayer::_debug_quadrants_update_cell(CellData &r_cell_data, SelfList<
/////////////////////////////// Rendering //////////////////////////////////////
void TileMapLayer::_rendering_update() {
- const TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
RenderingServer *rs = RenderingServer::get_singleton();
@@ -192,24 +187,23 @@ void TileMapLayer::_rendering_update() {
// ----------- Layer level processing -----------
if (!forced_cleanup) {
- // Update the layer's CanvasItem.
- set_use_parent_material(true);
- set_light_mask(tile_map_node->get_light_mask());
-
// Modulate the layer.
Color layer_modulate = get_modulate();
#ifdef TOOLS_ENABLED
- const Vector<StringName> selected_layers = tile_map_node->get_selected_layers();
- if (tile_map_node->is_highlighting_selected_layer() && selected_layers.size() == 1 && get_name() != selected_layers[0]) {
- TileMapLayer *selected_layer = Object::cast_to<TileMapLayer>(tile_map_node->get_node_or_null(String(selected_layers[0])));
- if (selected_layer) {
- int z_selected = selected_layer->get_z_index();
- int layer_z_index = get_z_index();
- if (layer_z_index < z_selected || (layer_z_index == z_selected && get_index() < selected_layer->get_index())) {
- layer_modulate = layer_modulate.darkened(0.5);
- } else if (layer_z_index > z_selected || (layer_z_index == z_selected && get_index() > selected_layer->get_index())) {
- layer_modulate = layer_modulate.darkened(0.5);
- layer_modulate.a *= 0.3;
+ const TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(get_parent());
+ if (tile_map_layer_group) {
+ const Vector<StringName> selected_layers = tile_map_layer_group->get_selected_layers();
+ if (tile_map_layer_group->is_highlighting_selected_layer() && selected_layers.size() == 1 && get_name() != selected_layers[0]) {
+ TileMapLayer *selected_layer = Object::cast_to<TileMapLayer>(tile_map_layer_group->get_node_or_null(String(selected_layers[0])));
+ if (selected_layer) {
+ int z_selected = selected_layer->get_z_index();
+ int layer_z_index = get_z_index();
+ if (layer_z_index < z_selected || (layer_z_index == z_selected && get_index() < selected_layer->get_index())) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ } else if (layer_z_index > z_selected || (layer_z_index == z_selected && get_index() > selected_layer->get_index())) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ layer_modulate.a *= 0.3;
+ }
}
}
}
@@ -224,8 +218,8 @@ void TileMapLayer::_rendering_update() {
// Check if anything changed that might change the quadrant shape.
// If so, recreate everything.
- bool quandrant_shape_changed = dirty.flags[DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE] ||
- (is_y_sort_enabled() && (dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] || dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] || dirty.flags[DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED] || dirty.flags[DIRTY_FLAGS_LAYER_LOCAL_TRANSFORM] || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET]));
+ bool quandrant_shape_changed = dirty.flags[DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE] ||
+ (is_y_sort_enabled() && (dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] || dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] || dirty.flags[DIRTY_FLAGS_LAYER_LOCAL_TRANSFORM] || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET]));
// Free all quadrants.
if (forced_cleanup || quandrant_shape_changed) {
@@ -330,7 +324,7 @@ void TileMapLayer::_rendering_update() {
Transform2D xform(0, rendering_quadrant->canvas_items_position);
rs->canvas_item_set_transform(ci, xform);
- rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
+ rs->canvas_item_set_light_mask(ci, get_light_mask());
rs->canvas_item_set_z_as_relative_to_parent(ci, true);
rs->canvas_item_set_z_index(ci, tile_z_index);
@@ -398,17 +392,15 @@ void TileMapLayer::_rendering_update() {
}
}
- // Updates on TileMap changes.
- if (dirty.flags[DIRTY_FLAGS_TILE_MAP_LIGHT_MASK] ||
- dirty.flags[DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL] ||
- dirty.flags[DIRTY_FLAGS_TILE_MAP_MATERIAL] ||
- dirty.flags[DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER] ||
- dirty.flags[DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT] ||
+ // Updates on rendering changes.
+ if (dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] ||
+ dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] ||
+ dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] ||
dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE]) {
for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
Ref<RenderingQuadrant> &rendering_quadrant = kv.value;
for (const RID &ci : rendering_quadrant->canvas_items) {
- rs->canvas_item_set_light_mask(ci, tile_map_node->get_light_mask());
+ rs->canvas_item_set_light_mask(ci, get_light_mask());
rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree()));
rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree()));
rs->canvas_item_set_self_modulate(ci, get_self_modulate());
@@ -465,7 +457,6 @@ void TileMapLayer::_rendering_notification(int p_what) {
}
void TileMapLayer::_rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list) {
- const TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
// Check if the cell is valid and retrieve its y_sort_origin.
@@ -495,14 +486,13 @@ void TileMapLayer::_rendering_quadrants_update_cell(CellData &r_cell_data, SelfL
canvas_items_position = Vector2(0, tile_set->map_to_local(r_cell_data.coords).y + tile_y_sort_origin + y_sort_origin);
quadrant_coords = canvas_items_position * 100;
} else {
- int quad_size = tile_map_node->get_rendering_quadrant_size();
const Vector2i &coords = r_cell_data.coords;
// Rounding down, instead of simply rounding towards zero (truncating).
quadrant_coords = Vector2i(
- coords.x > 0 ? coords.x / quad_size : (coords.x - (quad_size - 1)) / quad_size,
- coords.y > 0 ? coords.y / quad_size : (coords.y - (quad_size - 1)) / quad_size);
- canvas_items_position = tile_set->map_to_local(quad_size * quadrant_coords);
+ coords.x > 0 ? coords.x / rendering_quadrant_size : (coords.x - (rendering_quadrant_size - 1)) / rendering_quadrant_size,
+ coords.y > 0 ? coords.y / rendering_quadrant_size : (coords.y - (rendering_quadrant_size - 1)) / rendering_quadrant_size);
+ canvas_items_position = tile_set->map_to_local(rendering_quadrant_size * quadrant_coords);
}
Ref<RenderingQuadrant> rendering_quadrant;
@@ -767,7 +757,6 @@ void TileMapLayer::_physics_clear_cell(CellData &r_cell_data) {
}
void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
- const TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
Transform2D gl_transform = get_global_transform();
RID space = get_world_2d()->get_space();
@@ -825,7 +814,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
body = ps->body_create();
}
bodies_coords[body] = r_cell_data.coords;
- ps->body_set_mode(body, tile_map_node->is_collision_animatable() ? PhysicsServer2D::BODY_MODE_KINEMATIC : PhysicsServer2D::BODY_MODE_STATIC);
+ ps->body_set_mode(body, use_kinematic_bodies ? PhysicsServer2D::BODY_MODE_KINEMATIC : PhysicsServer2D::BODY_MODE_STATIC);
ps->body_set_space(body, space);
Transform2D xform;
@@ -833,7 +822,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
xform = gl_transform * xform;
ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
- ps->body_attach_object_instance_id(body, tile_map_node->get_instance_id());
+ ps->body_attach_object_instance_id(body, tile_map_node ? tile_map_node->get_instance_id() : get_instance_id());
ps->body_set_collision_layer(body, physics_layer);
ps->body_set_collision_mask(body, physics_mask);
ps->body_set_pickable(body, false);
@@ -885,7 +874,6 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
#ifdef DEBUG_ENABLED
void TileMapLayer::_physics_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data) {
// Draw the debug collision shapes.
- TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
ERR_FAIL_COND(!tile_set.is_valid());
@@ -894,14 +882,14 @@ void TileMapLayer::_physics_draw_cell_debug(const RID &p_canvas_item, const Vect
}
bool show_collision = false;
- switch (tile_map_node->get_collision_visibility_mode()) {
- case TileMap::VISIBILITY_MODE_DEFAULT:
+ switch (collision_visibility_mode) {
+ case TileMapLayer::VISIBILITY_MODE_DEFAULT:
show_collision = !Engine::get_singleton()->is_editor_hint() && get_tree()->is_debugging_collisions_hint();
break;
- case TileMap::VISIBILITY_MODE_FORCE_HIDE:
+ case TileMapLayer::VISIBILITY_MODE_FORCE_HIDE:
show_collision = false;
break;
- case TileMap::VISIBILITY_MODE_FORCE_SHOW:
+ case TileMapLayer::VISIBILITY_MODE_FORCE_SHOW:
show_collision = true;
break;
}
@@ -942,32 +930,32 @@ void TileMapLayer::_physics_draw_cell_debug(const RID &p_canvas_item, const Vect
void TileMapLayer::_navigation_update() {
ERR_FAIL_NULL(NavigationServer2D::get_singleton());
- const Ref<TileSet> &tile_set = get_effective_tile_set();
NavigationServer2D *ns = NavigationServer2D::get_singleton();
+ const Ref<TileSet> &tile_set = get_effective_tile_set();
// Check if we should cleanup everything.
bool forced_cleanup = in_destructor || !enabled || !navigation_enabled || !is_inside_tree() || !tile_set.is_valid();
// ----------- Layer level processing -----------
- if (forced_cleanup) {
- if (navigation_map.is_valid() && !uses_world_navigation_map) {
- ns->free(navigation_map);
- navigation_map = RID();
- }
- } else {
- // Update navigation maps.
- if (!navigation_map.is_valid()) {
- if (layer_index_in_tile_map_node == 0) {
- // Use the default World2D navigation map for the first layer when empty.
- navigation_map = get_world_2d()->get_navigation_map();
- uses_world_navigation_map = true;
- } else {
- RID new_layer_map = ns->map_create();
- // Set the default NavigationPolygon cell_size on the new map as a mismatch causes an error.
- ns->map_set_cell_size(new_layer_map, 1.0);
- ns->map_set_active(new_layer_map, true);
- navigation_map = new_layer_map;
- uses_world_navigation_map = false;
+ // All this processing is kept for compatibility with the TileMap node.
+ // Otherwise, layers shall use the World2D navigation map or define a custom one with set_navigation_map(...).
+ if (tile_map_node) {
+ if (forced_cleanup) {
+ if (navigation_map_override.is_valid()) {
+ ns->free(navigation_map_override);
+ navigation_map_override = RID();
+ }
+ } else {
+ // Update navigation maps.
+ if (!navigation_map_override.is_valid()) {
+ if (layer_index_in_tile_map_node > 0) {
+ // Create a dedicated map for each layer.
+ RID new_layer_map = ns->map_create();
+ // Set the default NavigationPolygon cell_size on the new map as a mismatch causes an error.
+ ns->map_set_cell_size(new_layer_map, 1.0);
+ ns->map_set_active(new_layer_map, true);
+ navigation_map_override = new_layer_map;
+ }
}
}
}
@@ -979,7 +967,7 @@ void TileMapLayer::_navigation_update() {
_navigation_clear_cell(kv.value);
}
} else {
- if (_navigation_was_cleaned_up || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET] || dirty.flags[DIRTY_FLAGS_LAYER_IN_TREE]) {
+ if (_navigation_was_cleaned_up || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET] || dirty.flags[DIRTY_FLAGS_LAYER_IN_TREE] || dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_MAP]) {
// Update all cells.
for (KeyValue<Vector2i, CellData> &kv : tile_map) {
_navigation_update_cell(kv.value);
@@ -1033,10 +1021,11 @@ void TileMapLayer::_navigation_clear_cell(CellData &r_cell_data) {
}
void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
- const TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
NavigationServer2D *ns = NavigationServer2D::get_singleton();
Transform2D gl_xform = get_global_transform();
+ RID navigation_map = navigation_map_override.is_valid() ? navigation_map_override : get_world_2d()->get_navigation_map();
+ ERR_FAIL_COND(navigation_map.is_null());
// Get the navigation polygons and create regions.
TileMapCell &c = r_cell_data.cell;
@@ -1084,7 +1073,7 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
if (!region.is_valid()) {
region = ns->region_create();
}
- ns->region_set_owner_id(region, tile_map_node->get_instance_id());
+ ns->region_set_owner_id(region, tile_map_node ? tile_map_node->get_instance_id() : get_instance_id());
ns->region_set_map(region, navigation_map);
ns->region_set_transform(region, gl_xform * tile_transform);
ns->region_set_navigation_layers(region, tile_set->get_navigation_layer_layers(navigation_layer_index));
@@ -1111,16 +1100,15 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
#ifdef DEBUG_ENABLED
void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data) {
// Draw the debug collision shapes.
- const TileMap *tile_map_node = _fetch_tilemap();
bool show_navigation = false;
- switch (tile_map_node->get_navigation_visibility_mode()) {
- case TileMap::VISIBILITY_MODE_DEFAULT:
+ switch (navigation_visibility_mode) {
+ case TileMapLayer::VISIBILITY_MODE_DEFAULT:
show_navigation = !Engine::get_singleton()->is_editor_hint() && get_tree()->is_debugging_navigation_hint();
break;
- case TileMap::VISIBILITY_MODE_FORCE_HIDE:
+ case TileMapLayer::VISIBILITY_MODE_FORCE_HIDE:
show_navigation = false;
break;
- case TileMap::VISIBILITY_MODE_FORCE_SHOW:
+ case TileMapLayer::VISIBILITY_MODE_FORCE_SHOW:
show_navigation = true;
break;
}
@@ -1250,13 +1238,14 @@ void TileMapLayer::_scenes_update() {
}
void TileMapLayer::_scenes_clear_cell(CellData &r_cell_data) {
- const TileMap *tile_map_node = _fetch_tilemap();
- if (!tile_map_node) {
- return;
- }
-
// Cleanup existing scene.
- Node *node = tile_map_node->get_node_or_null(r_cell_data.scene);
+ Node *node = nullptr;
+ if (tile_map_node) {
+ // Compatibility with TileMap.
+ node = tile_map_node->get_node_or_null(r_cell_data.scene);
+ } else {
+ node = get_node_or_null(r_cell_data.scene);
+ }
if (node) {
node->queue_free();
}
@@ -1264,7 +1253,6 @@ void TileMapLayer::_scenes_clear_cell(CellData &r_cell_data) {
}
void TileMapLayer::_scenes_update_cell(CellData &r_cell_data) {
- TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
// Clear the scene in any case.
@@ -1292,7 +1280,12 @@ void TileMapLayer::_scenes_update_cell(CellData &r_cell_data) {
xform.set_origin(tile_set->map_to_local(r_cell_data.coords));
scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
}
- tile_map_node->add_child(scene);
+ if (tile_map_node) {
+ // Compatibility with TileMap.
+ tile_map_node->add_child(scene);
+ } else {
+ add_child(scene);
+ }
r_cell_data.scene = scene->get_name();
}
}
@@ -1352,26 +1345,28 @@ void TileMapLayer::_scenes_draw_cell_debug(const RID &p_canvas_item, const Vecto
/////////////////////////////////////////////////////////////////////
void TileMapLayer::_build_runtime_update_tile_data() {
- const TileMap *tile_map_node = _fetch_tilemap();
const Ref<TileSet> &tile_set = get_effective_tile_set();
// Check if we should cleanup everything.
bool forced_cleanup = in_destructor || !enabled || !tile_set.is_valid() || !is_visible_in_tree();
if (!forced_cleanup) {
- if (tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) && tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update)) {
+ bool valid_runtime_update = GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) && GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update);
+ bool valid_runtime_update_for_tilemap = tile_map_node && tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) && tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update); // For keeping compatibility.
+ if (valid_runtime_update || valid_runtime_update_for_tilemap) {
+ bool use_tilemap_for_runtime = valid_runtime_update_for_tilemap && !valid_runtime_update;
if (_runtime_update_tile_data_was_cleaned_up || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET]) {
_runtime_update_needs_all_cells_cleaned_up = true;
for (KeyValue<Vector2i, CellData> &E : tile_map) {
- _build_runtime_update_tile_data_for_cell(E.value);
+ _build_runtime_update_tile_data_for_cell(E.value, use_tilemap_for_runtime);
}
- } else if (dirty.flags[DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE]) {
+ } else if (dirty.flags[DIRTY_FLAGS_LAYER_RUNTIME_UPDATE]) {
for (KeyValue<Vector2i, CellData> &E : tile_map) {
- _build_runtime_update_tile_data_for_cell(E.value, true);
+ _build_runtime_update_tile_data_for_cell(E.value, use_tilemap_for_runtime, true);
}
} else {
for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
CellData &cell_data = *cell_data_list_element->self();
- _build_runtime_update_tile_data_for_cell(cell_data);
+ _build_runtime_update_tile_data_for_cell(cell_data, use_tilemap_for_runtime);
}
}
}
@@ -1382,8 +1377,7 @@ void TileMapLayer::_build_runtime_update_tile_data() {
_runtime_update_tile_data_was_cleaned_up = forced_cleanup;
}
-void TileMapLayer::_build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_auto_add_to_dirty_list) {
- TileMap *tile_map_node = _fetch_tilemap();
+void TileMapLayer::_build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_use_tilemap_for_runtime, bool p_auto_add_to_dirty_list) {
const Ref<TileSet> &tile_set = get_effective_tile_set();
TileMapCell &c = r_cell_data.cell;
@@ -1395,18 +1389,37 @@ void TileMapLayer::_build_runtime_update_tile_data_for_cell(CellData &r_cell_dat
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
bool ret = false;
- if (tile_map_node->GDVIRTUAL_CALL(_use_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, ret) && ret) {
- TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
- // Create the runtime TileData.
- TileData *tile_data_runtime_use = tile_data->duplicate();
- tile_data_runtime_use->set_allow_transform(true);
- r_cell_data.runtime_tile_data_cache = tile_data_runtime_use;
+ if (p_use_tilemap_for_runtime) {
+ // Compatibility with TileMap.
+ if (tile_map_node->GDVIRTUAL_CALL(_use_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, ret) && ret) {
+ TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+
+ // Create the runtime TileData.
+ TileData *tile_data_runtime_use = tile_data->duplicate();
+ tile_data_runtime_use->set_allow_transform(true);
+ r_cell_data.runtime_tile_data_cache = tile_data_runtime_use;
- tile_map_node->GDVIRTUAL_CALL(_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, tile_data_runtime_use);
+ tile_map_node->GDVIRTUAL_CALL(_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, tile_data_runtime_use);
- if (p_auto_add_to_dirty_list) {
- dirty.cell_list.add(&r_cell_data.dirty_list_element);
+ if (p_auto_add_to_dirty_list) {
+ dirty.cell_list.add(&r_cell_data.dirty_list_element);
+ }
+ }
+ } else {
+ if (GDVIRTUAL_CALL(_use_tile_data_runtime_update, r_cell_data.coords, ret) && ret) {
+ TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
+
+ // Create the runtime TileData.
+ TileData *tile_data_runtime_use = tile_data->duplicate();
+ tile_data_runtime_use->set_allow_transform(true);
+ r_cell_data.runtime_tile_data_cache = tile_data_runtime_use;
+
+ GDVIRTUAL_CALL(_tile_data_runtime_update, r_cell_data.coords, tile_data_runtime_use);
+
+ if (p_auto_add_to_dirty_list) {
+ dirty.cell_list.add(&r_cell_data.dirty_list_element);
+ }
}
}
}
@@ -1611,8 +1624,7 @@ void TileMapLayer::_renamed() {
}
void TileMapLayer::_update_notify_local_transform() {
- TileMap *tile_map_node = _fetch_tilemap();
- bool notify = tile_map_node->is_collision_animatable() || is_y_sort_enabled();
+ bool notify = is_using_kinematic_bodies() || is_y_sort_enabled();
if (!notify) {
if (is_y_sort_enabled()) {
notify = true;
@@ -1727,16 +1739,23 @@ void TileMapLayer::_notification(int p_what) {
void TileMapLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMapLayer::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(0));
+ GDVIRTUAL_BIND(_use_tile_data_runtime_update, "coords");
+ GDVIRTUAL_BIND(_tile_data_runtime_update, "coords", "tile_data");
+
ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed));
}
-void TileMapLayer::set_layer_index_in_tile_map_node(int p_index) {
- if (p_index == layer_index_in_tile_map_node) {
- return;
+void TileMapLayer::set_as_tile_map_internal_node(int p_index) {
+ // Compatibility with TileMap.
+ ERR_FAIL_NULL(get_parent());
+ tile_map_node = Object::cast_to<TileMap>(get_parent());
+ set_use_parent_material(true);
+ force_parent_owned();
+ if (layer_index_in_tile_map_node != p_index) {
+ layer_index_in_tile_map_node = p_index;
+ dirty.flags[DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE] = true;
+ _queue_internal_update();
}
- layer_index_in_tile_map_node = p_index;
- dirty.flags[DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE] = true;
- _queue_internal_update();
}
Rect2 TileMapLayer::get_rect(bool &r_changed) const {
@@ -2085,7 +2104,7 @@ void TileMapLayer::set_tile_data(TileMapDataFormat p_format, const Vector<int> &
clear();
#ifdef DISABLE_DEPRECATED
- ERR_FAIL_COND_MSG(p_format != TileMapDataFormat::FORMAT_3, vformat("Cannot handle deprecated TileMap data format version %d. This Godot version was compiled with no support for deprecated data.", p_format));
+ ERR_FAIL_COND_MSG(p_format != TileMapDataFormat::FORMAT_3, vformat("Cannot handle deprecated TileMapLayer data format version %d. This Godot version was compiled with no support for deprecated data.", p_format));
#endif
for (int i = 0; i < c; i += offset) {
@@ -2176,7 +2195,7 @@ Vector<int> TileMapLayer::get_tile_data() const {
return tile_data;
}
-void TileMapLayer::notify_tile_map_change(DirtyFlags p_what) {
+void TileMapLayer::notify_tile_map_layer_group_change(DirtyFlags p_what) {
if (p_what == DIRTY_FLAGS_LAYER_GROUP_SELECTED_LAYERS ||
p_what == DIRTY_FLAGS_LAYER_GROUP_HIGHLIGHT_SELECTED ||
p_what == DIRTY_FLAGS_LAYER_GROUP_TILE_SET) {
@@ -2192,6 +2211,12 @@ void TileMapLayer::update_internals() {
_deferred_internal_update();
}
+void TileMapLayer::notify_runtime_tile_data_update() {
+ dirty.flags[TileMapLayer::DIRTY_FLAGS_LAYER_RUNTIME_UPDATE] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
// Set the current cell tile (using integer position).
Vector2i pk(p_coords);
@@ -2532,8 +2557,9 @@ void TileMapLayer::set_enabled(bool p_enabled) {
_queue_internal_update();
emit_signal(CoreStringNames::get_singleton()->changed);
- TileMap *tile_map_node = _fetch_tilemap();
- tile_map_node->update_configuration_warnings();
+ if (tile_map_node) {
+ tile_map_node->update_configuration_warnings();
+ }
}
bool TileMapLayer::is_enabled() const {
@@ -2559,8 +2585,9 @@ void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) {
_queue_internal_update();
emit_signal(CoreStringNames::get_singleton()->changed);
- TileMap *tile_map_node = _fetch_tilemap();
- tile_map_node->update_configuration_warnings();
+ if (tile_map_node) {
+ tile_map_node->update_configuration_warnings();
+ }
_update_notify_local_transform();
}
@@ -2587,8 +2614,51 @@ void TileMapLayer::set_z_index(int p_z_index) {
_queue_internal_update();
emit_signal(CoreStringNames::get_singleton()->changed);
- TileMap *tile_map_node = _fetch_tilemap();
- tile_map_node->update_configuration_warnings();
+ if (tile_map_node) {
+ tile_map_node->update_configuration_warnings();
+ }
+}
+
+void TileMapLayer::set_light_mask(int p_light_mask) {
+ if (get_light_mask() == p_light_mask) {
+ return;
+ }
+ CanvasItem::set_light_mask(p_light_mask);
+ dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+void TileMapLayer::set_texture_filter(TextureFilter p_texture_filter) {
+ // Set a default texture filter for the whole tilemap.
+ CanvasItem::set_texture_filter(p_texture_filter);
+ dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+void TileMapLayer::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
+ // Set a default texture repeat for the whole tilemap.
+ CanvasItem::set_texture_repeat(p_texture_repeat);
+ dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+void TileMapLayer::set_rendering_quadrant_size(int p_size) {
+ if (rendering_quadrant_size == p_size) {
+ return;
+ }
+ dirty.flags[DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE] = true;
+ ERR_FAIL_COND_MSG(p_size < 1, "TileMapQuadrant size cannot be smaller than 1.");
+
+ rendering_quadrant_size = p_size;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+int TileMapLayer::get_rendering_quadrant_size() const {
+ return rendering_quadrant_size;
}
void TileMapLayer::set_use_kinematic_bodies(bool p_use_kinematic_bodies) {
@@ -2602,6 +2672,20 @@ bool TileMapLayer::is_using_kinematic_bodies() const {
return use_kinematic_bodies;
}
+void TileMapLayer::set_collision_visibility_mode(TileMapLayer::VisibilityMode p_show_collision) {
+ if (collision_visibility_mode == p_show_collision) {
+ return;
+ }
+ collision_visibility_mode = p_show_collision;
+ dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_VISIBILITY_MODE] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+TileMapLayer::VisibilityMode TileMapLayer::get_collision_visibility_mode() const {
+ return collision_visibility_mode;
+}
+
void TileMapLayer::set_navigation_enabled(bool p_enabled) {
if (navigation_enabled == p_enabled) {
return;
@@ -2617,18 +2701,38 @@ bool TileMapLayer::is_navigation_enabled() const {
}
void TileMapLayer::set_navigation_map(RID p_map) {
- ERR_FAIL_COND_MSG(!is_inside_tree(), "A TileMap navigation map can only be changed while inside the SceneTree.");
- navigation_map = p_map;
- uses_world_navigation_map = p_map == get_world_2d()->get_navigation_map();
+ if (navigation_map_override == p_map) {
+ return;
+ }
+ navigation_map_override = p_map;
+ dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_MAP] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
}
RID TileMapLayer::get_navigation_map() const {
- if (navigation_map.is_valid()) {
- return navigation_map;
+ if (navigation_map_override.is_valid()) {
+ return navigation_map_override;
+ } else if (is_inside_tree()) {
+ return get_world_2d()->get_navigation_map();
}
return RID();
}
+void TileMapLayer::set_navigation_visibility_mode(TileMapLayer::VisibilityMode p_show_navigation) {
+ if (navigation_visibility_mode == p_show_navigation) {
+ return;
+ }
+ navigation_visibility_mode = p_show_navigation;
+ dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE] = true;
+ _queue_internal_update();
+ emit_signal(CoreStringNames::get_singleton()->changed);
+}
+
+TileMapLayer::VisibilityMode TileMapLayer::get_navigation_visibility_mode() const {
+ return navigation_visibility_mode;
+}
+
void TileMapLayer::fix_invalid_tiles() {
Ref<TileSet> tileset = get_effective_tile_set();
ERR_FAIL_COND_MSG(tileset.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet.");
diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h
index 5a0c51d7e5..c58c72949c 100644
--- a/scene/2d/tile_map_layer.h
+++ b/scene/2d/tile_map_layer.h
@@ -218,6 +218,12 @@ class TileMapLayer : public Node2D {
GDCLASS(TileMapLayer, Node2D);
public:
+ enum VisibilityMode {
+ VISIBILITY_MODE_DEFAULT,
+ VISIBILITY_MODE_FORCE_SHOW,
+ VISIBILITY_MODE_FORCE_HIDE,
+ };
+
enum DirtyFlags {
DIRTY_FLAGS_LAYER_ENABLED = 0,
DIRTY_FLAGS_LAYER_IN_TREE,
@@ -228,24 +234,23 @@ public:
DIRTY_FLAGS_LAYER_Y_SORT_ENABLED,
DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN,
DIRTY_FLAGS_LAYER_Z_INDEX,
+ DIRTY_FLAGS_LAYER_LIGHT_MASK,
+ DIRTY_FLAGS_LAYER_TEXTURE_FILTER,
+ DIRTY_FLAGS_LAYER_TEXTURE_REPEAT,
+ DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE,
DIRTY_FLAGS_LAYER_USE_KINEMATIC_BODIES,
+ DIRTY_FLAGS_LAYER_COLLISION_VISIBILITY_MODE,
DIRTY_FLAGS_LAYER_NAVIGATION_ENABLED,
- DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE,
+ DIRTY_FLAGS_LAYER_NAVIGATION_MAP,
+ DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE,
+ DIRTY_FLAGS_LAYER_RUNTIME_UPDATE,
+
+ DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE, // For compatibility.
DIRTY_FLAGS_LAYER_GROUP_SELECTED_LAYERS,
DIRTY_FLAGS_LAYER_GROUP_HIGHLIGHT_SELECTED,
DIRTY_FLAGS_LAYER_GROUP_TILE_SET,
- DIRTY_FLAGS_TILE_MAP_LIGHT_MASK,
- DIRTY_FLAGS_TILE_MAP_MATERIAL,
- DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL,
- DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER,
- DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT,
- DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE,
- DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE,
- DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE,
- DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED,
- DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE,
DIRTY_FLAGS_MAX,
};
@@ -253,16 +258,23 @@ private:
// Exposed properties.
bool enabled = true;
int y_sort_origin = 0;
+ int rendering_quadrant_size = 16;
+
bool use_kinematic_bodies = false;
+ VisibilityMode collision_visibility_mode = VISIBILITY_MODE_DEFAULT;
+
bool navigation_enabled = true;
- RID navigation_map;
- bool uses_world_navigation_map = false;
+ RID navigation_map_override;
+ VisibilityMode navigation_visibility_mode = VISIBILITY_MODE_DEFAULT;
// Internal.
- int layer_index_in_tile_map_node = -1;
HashMap<Vector2i, CellData> tile_map;
bool pending_update = false;
+ // For keeping compatibility with TileMap.
+ TileMap *tile_map_node = nullptr;
+ int layer_index_in_tile_map_node = -1;
+
// Dirty flag. Allows knowing what was modified since the last update.
struct {
bool flags[DIRTY_FLAGS_MAX] = { false };
@@ -276,13 +288,10 @@ private:
mutable Rect2i used_rect_cache;
mutable bool used_rect_cache_dirty = true;
- // Method to fetch the TileSet to use
- TileMap *_fetch_tilemap() const;
-
// Runtime tile data.
bool _runtime_update_tile_data_was_cleaned_up = false;
void _build_runtime_update_tile_data();
- void _build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_auto_add_to_dirty_list = false);
+ void _build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_use_tilemap_for_runtime, bool p_auto_add_to_dirty_list = false);
bool _runtime_update_needs_all_cells_cleaned_up = false;
void _clear_runtime_update_tile_data();
void _clear_runtime_update_tile_data_for_cell(CellData &r_cell_data);
@@ -353,7 +362,7 @@ protected:
public:
// TileMap node.
- void set_layer_index_in_tile_map_node(int p_index);
+ void set_as_tile_map_internal_node(int p_index);
// Rect caching.
Rect2 get_rect(bool &r_changed) const;
@@ -370,9 +379,10 @@ public:
// For TileMap node's use.
void set_tile_data(TileMapDataFormat p_format, const Vector<int> &p_data);
Vector<int> get_tile_data() const;
- void notify_tile_map_change(DirtyFlags p_what);
+ void notify_tile_map_layer_group_change(DirtyFlags p_what);
void update_internals();
+ void notify_runtime_tile_data_update();
// --- Exposed in TileMap ---
// Cells manipulation.
@@ -406,12 +416,23 @@ public:
void set_y_sort_origin(int p_y_sort_origin);
int get_y_sort_origin() const;
virtual void set_z_index(int p_z_index) override;
+ virtual void set_light_mask(int p_light_mask) override;
+ virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter) override;
+ virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) override;
+ void set_rendering_quadrant_size(int p_size);
+ int get_rendering_quadrant_size() const;
+
void set_use_kinematic_bodies(bool p_use_kinematic_bodies);
bool is_using_kinematic_bodies() const;
+ void set_collision_visibility_mode(VisibilityMode p_show_collision);
+ VisibilityMode get_collision_visibility_mode() const;
+
void set_navigation_enabled(bool p_enabled);
bool is_navigation_enabled() const;
void set_navigation_map(RID p_map);
RID get_navigation_map() const;
+ void set_navigation_visibility_mode(VisibilityMode p_show_navigation);
+ VisibilityMode get_navigation_visibility_mode() const;
// Fixing and clearing methods.
void fix_invalid_tiles();
@@ -423,6 +444,9 @@ public:
// Helper.
Ref<TileSet> get_effective_tile_set() const;
+ // Virtual function to modify the TileData at runtime.
+ GDVIRTUAL1R(bool, _use_tile_data_runtime_update, Vector2i);
+ GDVIRTUAL2(_tile_data_runtime_update, Vector2i, TileData *);
// ---
TileMapLayer();
diff --git a/scene/2d/tile_map_layer_group.cpp b/scene/2d/tile_map_layer_group.cpp
index c596534474..132b4bbba5 100644
--- a/scene/2d/tile_map_layer_group.cpp
+++ b/scene/2d/tile_map_layer_group.cpp
@@ -53,7 +53,7 @@ void TileMapLayerGroup::_tile_set_changed() {
for (int i = 0; i < get_child_count(); i++) {
TileMapLayer *layer = Object::cast_to<TileMapLayer>(get_child(i));
if (layer) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_TILE_SET);
+ layer->notify_tile_map_layer_group_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_TILE_SET);
}
}
@@ -70,7 +70,7 @@ void TileMapLayerGroup::set_selected_layers(Vector<StringName> p_layer_names) {
for (int i = 0; i < get_child_count(); i++) {
TileMapLayer *layer = Object::cast_to<TileMapLayer>(get_child(i));
if (layer) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_SELECTED_LAYERS);
+ layer->notify_tile_map_layer_group_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_SELECTED_LAYERS);
}
}
}
@@ -89,7 +89,7 @@ void TileMapLayerGroup::set_highlight_selected_layer(bool p_highlight_selected_l
for (int i = 0; i < get_child_count(); i++) {
TileMapLayer *layer = Object::cast_to<TileMapLayer>(get_child(i));
if (layer) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_HIGHLIGHT_SELECTED);
+ layer->notify_tile_map_layer_group_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_HIGHLIGHT_SELECTED);
}
}
}
@@ -132,7 +132,7 @@ void TileMapLayerGroup::set_tileset(const Ref<TileSet> &p_tileset) {
for (int i = 0; i < get_child_count(); i++) {
TileMapLayer *layer = Object::cast_to<TileMapLayer>(get_child(i));
if (layer) {
- layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_TILE_SET);
+ layer->notify_tile_map_layer_group_change(TileMapLayer::DIRTY_FLAGS_LAYER_GROUP_TILE_SET);
}
}
}