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