diff options
Diffstat (limited to 'scene/2d/tile_map.cpp')
-rw-r--r-- | scene/2d/tile_map.cpp | 365 |
1 files changed, 242 insertions, 123 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 91e4f061cb..fc53c9e4ac 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -30,9 +30,11 @@ #include "tile_map.h" +#include "collision_object_2d.h" #include "core/io/marshalls.h" #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" +#include "scene/2d/area_2d.h" #include "servers/physics_2d_server.h" int TileMap::_get_quadrant_size() const { @@ -60,14 +62,21 @@ void TileMap::_notification(int p_what) { c = Object::cast_to<Node2D>(c->get_parent()); } + if (use_parent) { + _clear_quadrants(); + collision_parent = Object::cast_to<CollisionObject2D>(get_parent()); + } + pending_update = true; _recreate_quadrants(); update_dirty_quadrants(); RID space = get_world_2d()->get_space(); _update_quadrant_transform(); _update_quadrant_space(space); + update_configuration_warning(); } break; + case NOTIFICATION_EXIT_TREE: { _update_quadrant_space(RID()); @@ -82,30 +91,46 @@ void TileMap::_notification(int p_what) { q.navpoly_ids.clear(); } + if (collision_parent) { + collision_parent->remove_shape_owner(q.shape_owner_id); + q.shape_owner_id = -1; + } + for (Map<PosKey, Quadrant::Occluder>::Element *F = q.occluder_instances.front(); F; F = F->next()) { VS::get_singleton()->free(F->get().id); } q.occluder_instances.clear(); } + collision_parent = NULL; navigation = NULL; } break; + case NOTIFICATION_TRANSFORM_CHANGED: { //move stuff _update_quadrant_transform(); } break; + case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { + + if (use_parent) { + _recreate_quadrants(); + } + + } break; } } void TileMap::_update_quadrant_space(const RID &p_space) { - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { + if (!use_parent) { + for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_space(q.body, p_space); + Quadrant &q = E->get(); + Physics2DServer::get_singleton()->body_set_space(q.body, p_space); + } } } @@ -116,6 +141,10 @@ void TileMap::_update_quadrant_transform() { Transform2D global_transform = get_global_transform(); + Transform2D local_transform; + if (collision_parent) + local_transform = get_transform(); + Transform2D nav_rel; if (navigation) nav_rel = get_relative_transform_to_parent(navigation); @@ -125,8 +154,11 @@ void TileMap::_update_quadrant_transform() { Quadrant &q = E->get(); Transform2D xform; xform.set_origin(q.pos); - xform = global_transform * xform; - Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + + if (!use_parent) { + xform = global_transform * xform; + Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + } if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { @@ -202,47 +234,55 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Size2 s = p_sc; Vector2 offset = p_offset; - if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) - offset.y += cell_size.y; - else if (tile_origin == TILE_ORIGIN_CENTER) { - offset += cell_size / 2; - } - - if (s.y > s.x) { - if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose)) - offset.y += s.y - s.x; - } else if (s.y < s.x) { - if ((p_cell.flip_v && (p_cell.flip_h || p_cell.transpose)) || (p_cell.flip_h && !p_cell.transpose)) - offset.x += s.x - s.y; - } - if (p_cell.transpose) { SWAP(xform.elements[0].x, xform.elements[0].y); SWAP(xform.elements[1].x, xform.elements[1].y); SWAP(offset.x, offset.y); SWAP(s.x, s.y); } + if (p_cell.flip_h) { xform.elements[0].x = -xform.elements[0].x; xform.elements[1].x = -xform.elements[1].x; - if (tile_origin == TILE_ORIGIN_TOP_LEFT || tile_origin == TILE_ORIGIN_BOTTOM_LEFT) - offset.x = s.x - offset.x; - else if (tile_origin == TILE_ORIGIN_CENTER) - offset.x = s.x - offset.x / 2; + offset.x = s.x - offset.x; } + if (p_cell.flip_v) { xform.elements[0].y = -xform.elements[0].y; xform.elements[1].y = -xform.elements[1].y; - if (tile_origin == TILE_ORIGIN_TOP_LEFT) - offset.y = s.y - offset.y; - else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { - offset.y += s.y; - } else if (tile_origin == TILE_ORIGIN_CENTER) { - offset.y += s.y; + offset.y = s.y - offset.y; + } + /* For a future CheckBox to Center Texture: + offset += cell_size / 2 - s / 2; */ + xform.elements[2] += offset; +} + +void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> &p_shape, const TileSet::ShapeData &p_shape_data, const Transform2D &p_xform, const Vector2 &p_metadata) { + Physics2DServer *ps = Physics2DServer::get_singleton(); + + if (!use_parent) { + ps->body_add_shape(p_q.body, p_shape->get_rid(), p_xform); + ps->body_set_shape_metadata(p_q.body, shape_idx, p_metadata); + ps->body_set_shape_as_one_way_collision(p_q.body, shape_idx, p_shape_data.one_way_collision, p_shape_data.one_way_collision_margin); + + } else if (collision_parent) { + Transform2D xform = p_xform; + xform.set_origin(xform.get_origin() + p_q.pos); + + collision_parent->shape_owner_add_shape(p_q.shape_owner_id, p_shape); + + int real_index = collision_parent->shape_owner_get_shape_index(p_q.shape_owner_id, shape_idx); + RID rid = collision_parent->get_rid(); + + if (Object::cast_to<Area2D>(collision_parent) != NULL) { + ps->area_set_shape_transform(rid, real_index, get_transform() * xform); + } else { + ps->body_set_shape_transform(rid, real_index, get_transform() * xform); + ps->body_set_shape_metadata(rid, real_index, p_metadata); + ps->body_set_shape_as_one_way_collision(rid, real_index, p_shape_data.one_way_collision, p_shape_data.one_way_collision_margin); } } - xform.elements[2].x += offset.x; - xform.elements[2].y += offset.y; + shape_idx++; } void TileMap::update_dirty_quadrants() { @@ -288,7 +328,11 @@ void TileMap::update_dirty_quadrants() { q.canvas_items.clear(); - ps->body_clear_shapes(q.body); + if (!use_parent) { + ps->body_clear_shapes(q.body); + } else if (collision_parent) { + collision_parent->shape_owner_clear_shapes(q.shape_owner_id); + } int shape_idx = 0; if (navigation) { @@ -390,64 +434,26 @@ void TileMap::update_dirty_quadrants() { rect.size.x += fp_adjust; rect.size.y += fp_adjust; - if (rect.size.y > rect.size.x) { - if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) - tile_ofs.y += rect.size.y - rect.size.x; - } else if (rect.size.y < rect.size.x) { - if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) - tile_ofs.x += rect.size.x - rect.size.y; - } - - /* rect.size.x+=fp_adjust; - rect.size.y+=fp_adjust;*/ - - if (c.transpose) + if (c.transpose) { SWAP(tile_ofs.x, tile_ofs.y); + /* For a future CheckBox to Center Texture: + rect.position.x += cell_size.x / 2 - rect.size.y / 2; + rect.position.y += cell_size.y / 2 - rect.size.x / 2; + } else { + rect.position += cell_size / 2 - rect.size / 2; */ + } if (c.flip_h) { rect.size.x = -rect.size.x; tile_ofs.x = -tile_ofs.x; } + if (c.flip_v) { rect.size.y = -rect.size.y; tile_ofs.y = -tile_ofs.y; } - Vector2 center_ofs; - - if (tile_origin == TILE_ORIGIN_TOP_LEFT) { - rect.position += tile_ofs; - - } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { - - rect.position += tile_ofs; - - if (c.transpose) { - if (c.flip_h) - rect.position.x -= cell_size.x; - else - rect.position.x += cell_size.x; - } else { - if (c.flip_v) - rect.position.y -= cell_size.y; - else - rect.position.y += cell_size.y; - } - - } else if (tile_origin == TILE_ORIGIN_CENTER) { - - rect.position += tile_ofs; - - if (c.flip_h) - rect.position.x -= cell_size.x / 2; - else - rect.position.x += cell_size.x / 2; - - if (c.flip_v) - rect.position.y -= cell_size.y / 2; - else - rect.position.y += cell_size.y / 2; - } + rect.position += tile_ofs; Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id); Color modulate = tile_set->tile_get_modulate(c.id); @@ -471,7 +477,7 @@ void TileMap::update_dirty_quadrants() { Vector2 shape_ofs = shapes[j].shape_transform.get_origin(); - _fix_cell_transform(xform, c, shape_ofs + center_ofs, s); + _fix_cell_transform(xform, c, shape_ofs, s); xform *= shapes[j].shape_transform.untranslated(); @@ -479,10 +485,22 @@ void TileMap::update_dirty_quadrants() { vs->canvas_item_add_set_transform(debug_canvas_item, xform); shape->draw(debug_canvas_item, debug_collision_color); } - ps->body_add_shape(q.body, shape->get_rid(), xform); - ps->body_set_shape_metadata(q.body, shape_idx, Vector2(E->key().x, E->key().y)); - ps->body_set_shape_as_one_way_collision(q.body, shape_idx, shapes[j].one_way_collision, shapes[j].one_way_collision_margin); - shape_idx++; + + if (shape->has_meta("decomposed")) { + Array _shapes = shape->get_meta("decomposed"); + for (int k = 0; k < _shapes.size(); k++) { + Ref<ConvexPolygonShape2D> convex = _shapes[k]; + if (convex.is_valid()) { + _add_shape(shape_idx, q, convex, shapes[j], xform, Vector2(E->key().x, E->key().y)); +#ifdef DEBUG_ENABLED + } else { + print_error("The TileSet assigned to the TileMap " + get_name() + " has an invalid convex shape."); +#endif + } + } + } else { + _add_shape(shape_idx, q, shape, shapes[j], xform, Vector2(E->key().x, E->key().y)); + } } } } @@ -505,7 +523,7 @@ void TileMap::update_dirty_quadrants() { if (navpoly.is_valid()) { Transform2D xform; xform.set_origin(offset.floor() + q.pos); - _fix_cell_transform(xform, c, npoly_ofs + center_ofs, s); + _fix_cell_transform(xform, c, npoly_ofs, s); int pid = navigation->navpoly_add(navpoly, nav_rel * xform); @@ -555,7 +573,7 @@ void TileMap::update_dirty_quadrants() { } Transform2D navxform; navxform.set_origin(offset.floor()); - _fix_cell_transform(navxform, c, npoly_ofs + center_ofs, s); + _fix_cell_transform(navxform, c, npoly_ofs, s); vs->canvas_item_set_transform(debug_navigation_item, navxform); vs->canvas_item_add_triangle_array(debug_navigation_item, indices, vertices, colors); @@ -575,7 +593,7 @@ void TileMap::update_dirty_quadrants() { Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id); Transform2D xform; xform.set_origin(offset.floor() + q.pos); - _fix_cell_transform(xform, c, occluder_ofs + center_ofs, s); + _fix_cell_transform(xform, c, occluder_ofs, s); RID orid = VS::get_singleton()->canvas_light_occluder_create(); VS::get_singleton()->canvas_light_occluder_set_transform(orid, get_global_transform() * xform); @@ -656,22 +674,29 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons xform.set_origin(q.pos); //q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); - q.body = Physics2DServer::get_singleton()->body_create(); - Physics2DServer::get_singleton()->body_set_mode(q.body, use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC); - - Physics2DServer::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id()); - Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); - Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce); - - if (is_inside_tree()) { - xform = get_global_transform() * xform; - RID space = get_world_2d()->get_space(); - Physics2DServer::get_singleton()->body_set_space(q.body, space); - } + if (!use_parent) { + q.body = Physics2DServer::get_singleton()->body_create(); + Physics2DServer::get_singleton()->body_set_mode(q.body, use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC); + + Physics2DServer::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id()); + Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); + Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction); + Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce); + + if (is_inside_tree()) { + xform = get_global_transform() * xform; + RID space = get_world_2d()->get_space(); + Physics2DServer::get_singleton()->body_set_space(q.body, space); + } - Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform); + } else if (collision_parent) { + xform = get_transform() * xform; + q.shape_owner_id = collision_parent->create_shape_owner(this); + } else { + q.shape_owner_id = -1; + } rect_cache_dirty = true; quadrant_order_dirty = true; @@ -681,7 +706,12 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { Quadrant &q = Q->get(); - Physics2DServer::get_singleton()->free(q.body); + if (!use_parent) { + Physics2DServer::get_singleton()->free(q.body); + } else if (collision_parent) { + collision_parent->remove_shape_owner(q.shape_owner_id); + } + for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { VisualServer::get_singleton()->free(E->get()); @@ -731,7 +761,10 @@ void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { - set_cell(p_pos.x, p_pos.y, p_data["id"], p_data["flip_h"], p_data["flip_y"], p_data["transpose"], p_data["auto_coord"]); + Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"]; + const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; + Variant::CallError ce; + call("set_cell", args, 7, ce); } void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) { @@ -755,6 +788,7 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ else _make_quadrant_dirty(Q); + used_size_cache_dirty = true; return; } @@ -905,8 +939,17 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { _make_quadrant_dirty(Q); } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) { + E->get().autotile_coord_x = 0; E->get().autotile_coord_y = 0; + } else if (tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) { + + if (tile_set->autotile_get_bitmask(id, Vector2(p_x, p_y)) == TileSet::BIND_CENTER) { + Vector2 coord = tile_set->atlastile_get_subtile_by_priority(id, this, Vector2(p_x, p_y)); + + E->get().autotile_coord_x = (int)coord.x; + E->get().autotile_coord_y = (int)coord.y; + } } } } @@ -1162,20 +1205,24 @@ Rect2 TileMap::_edit_get_rect() const { void TileMap::set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { + if (!use_parent) { + for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); + Quadrant &q = E->get(); + Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); + } } } void TileMap::set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { + if (!use_parent) { + for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); + Quadrant &q = E->get(); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); + } } } @@ -1211,13 +1258,40 @@ void TileMap::set_collision_use_kinematic(bool p_use_kinematic) { _recreate_quadrants(); } +bool TileMap::get_collision_use_parent() const { + + return use_parent; +} + +void TileMap::set_collision_use_parent(bool p_use_parent) { + + if (use_parent == p_use_parent) return; + + _clear_quadrants(); + + use_parent = p_use_parent; + set_notify_local_transform(use_parent); + + if (use_parent && is_inside_tree()) { + collision_parent = Object::cast_to<CollisionObject2D>(get_parent()); + } else { + collision_parent = NULL; + } + + _recreate_quadrants(); + _change_notify(); + update_configuration_warning(); +} + void TileMap::set_collision_friction(float p_friction) { friction = p_friction; - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { + if (!use_parent) { + for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, p_friction); + Quadrant &q = E->get(); + Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, p_friction); + } } } @@ -1229,10 +1303,12 @@ float TileMap::get_collision_friction() const { void TileMap::set_collision_bounce(float p_bounce) { bounce = p_bounce; - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { + if (!use_parent) { + for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, p_bounce); + Quadrant &q = E->get(); + Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, p_bounce); + } } } float TileMap::get_collision_bounce() const { @@ -1373,18 +1449,21 @@ Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { if (!p_ignore_ofs) { switch (half_offset) { - case HALF_OFFSET_X: { + case HALF_OFFSET_X: + case HALF_OFFSET_NEGATIVE_X: { if (ABS(p_y) & 1) { - ret += get_cell_transform()[0] * 0.5; + ret += get_cell_transform()[0] * (half_offset == HALF_OFFSET_X ? 0.5 : -0.5); } } break; - case HALF_OFFSET_Y: { + case HALF_OFFSET_Y: + case HALF_OFFSET_NEGATIVE_Y: { if (ABS(p_x) & 1) { - ret += get_cell_transform()[1] * 0.5; + ret += get_cell_transform()[1] * (half_offset == HALF_OFFSET_Y ? 0.5 : -0.5); } } break; - default: {} + default: { + } } } return ret; @@ -1428,6 +1507,12 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(p); } +void TileMap::_validate_property(PropertyInfo &property) const { + if (use_parent && property.name != "collision_use_parent" && property.name.begins_with("collision_")) { + property.usage = PROPERTY_USAGE_NOEDITOR; + } +} + Vector2 TileMap::map_to_world(const Vector2 &p_pos, bool p_ignore_ofs) const { return _map_to_world(p_pos.x, p_pos.y, p_ignore_ofs); @@ -1444,12 +1529,23 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { ret.x -= 0.5; } } break; + case HALF_OFFSET_NEGATIVE_X: { + if (ret.y > 0 ? int(ret.y) & 1 : (int(ret.y) - 1) & 1) { + ret.x += 0.5; + } + } break; case HALF_OFFSET_Y: { if (ret.x > 0 ? int(ret.x) & 1 : (int(ret.x) - 1) & 1) { ret.y -= 0.5; } } break; - default: {} + case HALF_OFFSET_NEGATIVE_Y: { + if (ret.x > 0 ? int(ret.x) & 1 : (int(ret.x) - 1) & 1) { + ret.y += 0.5; + } + } break; + default: { + } } // Account for precision errors on the border (GH-23250). @@ -1565,6 +1661,20 @@ bool TileMap::get_clip_uv() const { return clip_uv; } +String TileMap::get_configuration_warning() const { + + String warning = Node2D::get_configuration_warning(); + + if (use_parent && !collision_parent) { + if (!warning.empty()) { + warning += "\n"; + } + return TTR("TileMap with Use Parent on needs a parent CollisionObject2D to give shapes to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."); + } + + return warning; +} + void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset); @@ -1600,6 +1710,9 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_use_kinematic", "use_kinematic"), &TileMap::set_collision_use_kinematic); ClassDB::bind_method(D_METHOD("get_collision_use_kinematic"), &TileMap::get_collision_use_kinematic); + ClassDB::bind_method(D_METHOD("set_collision_use_parent", "use_parent"), &TileMap::set_collision_use_parent); + ClassDB::bind_method(D_METHOD("get_collision_use_parent"), &TileMap::get_collision_use_parent); + ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &TileMap::set_collision_layer); ClassDB::bind_method(D_METHOD("get_collision_layer"), &TileMap::get_collision_layer); @@ -1659,12 +1772,13 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cell_size", PROPERTY_HINT_RANGE, "1,8192,1"), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "cell_custom_transform"), "set_custom_transform", "get_custom_transform"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled"), "set_half_offset", "get_half_offset"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv"); ADD_GROUP("Collision", "collision_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_parent", PROPERTY_HINT_NONE, ""), "set_collision_use_parent", "get_collision_use_parent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); @@ -1685,6 +1799,8 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(HALF_OFFSET_X); BIND_ENUM_CONSTANT(HALF_OFFSET_Y); BIND_ENUM_CONSTANT(HALF_OFFSET_DISABLED); + BIND_ENUM_CONSTANT(HALF_OFFSET_NEGATIVE_X); + BIND_ENUM_CONSTANT(HALF_OFFSET_NEGATIVE_Y); BIND_ENUM_CONSTANT(TILE_ORIGIN_TOP_LEFT); BIND_ENUM_CONSTANT(TILE_ORIGIN_CENTER); @@ -1711,6 +1827,8 @@ TileMap::TileMap() { bounce = 0; mode = MODE_SQUARE; half_offset = HALF_OFFSET_DISABLED; + use_parent = false; + collision_parent = NULL; use_kinematic = false; navigation = NULL; y_sort_mode = false; @@ -1721,6 +1839,7 @@ TileMap::TileMap() { fp_adjust = 0.00001; tile_origin = TILE_ORIGIN_TOP_LEFT; set_notify_transform(true); + set_notify_local_transform(false); } TileMap::~TileMap() { |