mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 21:22:48 +00:00
Merge pull request #88966 from groud/remove_tilemap_layer_dependencies_to_tilemap
Remove almost all remaining dependencies of TileMapLayer on TileMap
This commit is contained in:
commit
8328d9a647
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
tile_map_node->GDVIRTUAL_CALL(_tile_data_runtime_update, layer_index_in_tile_map_node, r_cell_data.coords, tile_data_runtime_use);
|
||||
// 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_auto_add_to_dirty_list) {
|
||||
dirty.cell_list.add(&r_cell_data.dirty_list_element);
|
||||
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);
|
||||
}
|
||||
}
|
||||
} 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.");
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user