Browse Source

TileMap Fixes

Mariano Suligoy 7 years ago
parent
commit
af719a90a7

+ 2 - 6
editor/plugins/spatial_editor_plugin.cpp

@@ -4753,9 +4753,9 @@ VSplitContainer *SpatialEditor::get_shader_split() {
 	return shader_split;
 	return shader_split;
 }
 }
 
 
-HBoxContainer *SpatialEditor::get_palette_split() {
+HSplitContainer *SpatialEditor::get_palette_split() {
 
 
-	return palette_split_container;
+	return palette_split;
 }
 }
 
 
 void SpatialEditor::_request_gizmo(Object *p_obj) {
 void SpatialEditor::_request_gizmo(Object *p_obj) {
@@ -5046,10 +5046,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
 	palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
 	vbc->add_child(palette_split);
 	vbc->add_child(palette_split);
 
 
-	palette_split_container = memnew(HBoxContainer);
-	palette_split_container->set_v_size_flags(SIZE_EXPAND_FILL);
-	palette_split->add_child(palette_split_container);
-
 	shader_split = memnew(VSplitContainer);
 	shader_split = memnew(VSplitContainer);
 	shader_split->set_h_size_flags(SIZE_EXPAND_FILL);
 	shader_split->set_h_size_flags(SIZE_EXPAND_FILL);
 	palette_split->add_child(shader_split);
 	palette_split->add_child(shader_split);

+ 1 - 2
editor/plugins/spatial_editor_plugin.h

@@ -413,7 +413,6 @@ private:
 	SpatialEditorViewport *viewports[VIEWPORTS_COUNT];
 	SpatialEditorViewport *viewports[VIEWPORTS_COUNT];
 	VSplitContainer *shader_split;
 	VSplitContainer *shader_split;
 	HSplitContainer *palette_split;
 	HSplitContainer *palette_split;
-	HBoxContainer *palette_split_container;
 
 
 	/////
 	/////
 
 
@@ -608,7 +607,7 @@ public:
 	void add_control_to_menu_panel(Control *p_control);
 	void add_control_to_menu_panel(Control *p_control);
 
 
 	VSplitContainer *get_shader_split();
 	VSplitContainer *get_shader_split();
-	HBoxContainer *get_palette_split();
+	HSplitContainer *get_palette_split();
 
 
 	Spatial *get_selected() { return selected; }
 	Spatial *get_selected() { return selected; }
 
 

+ 35 - 57
editor/plugins/tile_map_editor_plugin.cpp

@@ -123,12 +123,14 @@ void TileMapEditor::_menu_option(int p_option) {
 				return;
 				return;
 
 
 			undo_redo->create_action(TTR("Erase Selection"));
 			undo_redo->create_action(TTR("Erase Selection"));
+			undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
 			for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
 			for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
 				for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
 				for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
 
 
-					_set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true);
+					_set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false);
 				}
 				}
 			}
 			}
+			undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 			undo_redo->commit_action();
 			undo_redo->commit_action();
 
 
 			selection_active = false;
 			selection_active = false;
@@ -171,7 +173,7 @@ void TileMapEditor::set_selected_tile(int p_tile) {
 	}
 	}
 }
 }
 
 
-void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose, bool p_with_undo) {
+void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose) {
 
 
 	ERR_FAIL_COND(!node);
 	ERR_FAIL_COND(!node);
 
 
@@ -184,17 +186,8 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h,
 	if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose)
 	if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose)
 		return; //check that it's actually different
 		return; //check that it's actually different
 
 
-	if (p_with_undo) {
-
-		undo_redo->add_do_method(node, "set_cellv", Point2(p_pos), p_value, p_flip_h, p_flip_v, p_transpose);
-		undo_redo->add_do_method(node, "make_bitmask_area_dirty", Point2(p_pos));
-		undo_redo->add_undo_method(node, "set_cellv", Point2(p_pos), prev_val, prev_flip_h, prev_flip_v, prev_transpose);
-		undo_redo->add_undo_method(node, "make_bitmask_area_dirty", Point2(p_pos));
-	} else {
-
-		node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
-		node->update_bitmask_area(Point2(p_pos));
-	}
+	node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
+	node->update_bitmask_area(Point2(p_pos));
 }
 }
 
 
 void TileMapEditor::_text_entered(const String &p_text) {
 void TileMapEditor::_text_entered(const String &p_text) {
@@ -404,6 +397,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
 	}
 	}
 
 
 	PoolVector<Vector2> points;
 	PoolVector<Vector2> points;
+	Vector<Vector2> non_preview_cache;
 	int count = 0;
 	int count = 0;
 	int limit = 0;
 	int limit = 0;
 
 
@@ -432,8 +426,10 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
 				bucket_cache_visited[loc] = true;
 				bucket_cache_visited[loc] = true;
 				bucket_cache.push_back(n);
 				bucket_cache.push_back(n);
 			} else {
 			} else {
-				node->set_cellv(n, id, flip_h, flip_v, transpose);
+				if (non_preview_cache.find(n) >= 0)
+					continue;
 				points.push_back(n);
 				points.push_back(n);
+				non_preview_cache.push_back(n);
 			}
 			}
 
 
 			bucket_queue.push_back(Point2i(n.x, n.y + 1));
 			bucket_queue.push_back(Point2i(n.x, n.y + 1));
@@ -462,9 +458,10 @@ void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dicti
 	bool tr = p_op["transpose"];
 	bool tr = p_op["transpose"];
 
 
 	for (int i = 0; i < len; i++) {
 	for (int i = 0; i < len; i++) {
-
 		_set_cell(pr[i], id, xf, yf, tr);
 		_set_cell(pr[i], id, xf, yf, tr);
+		node->make_bitmask_area_dirty(pr[i]);
 	}
 	}
+	node->update_dirty_bitmask();
 }
 }
 
 
 void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) {
 void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) {
@@ -730,10 +727,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 						tool = TOOL_PAINTING;
 						tool = TOOL_PAINTING;
 
 
-						paint_undo.clear();
-						paint_undo[over_tile] = _get_op_from_cell(over_tile);
-
-						_set_cell(over_tile, id, flip_h, flip_v, transpose);
+						undo_redo->create_action(TTR("Paint TileMap"));
+						undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
 					}
 					}
 				} else if (tool == TOOL_PICKING) {
 				} else if (tool == TOOL_PICKING) {
 
 
@@ -754,15 +749,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 						int id = get_selected_tile();
 						int id = get_selected_tile();
 
 
-						if (id != TileMap::INVALID_CELL && paint_undo.size()) {
-
-							undo_redo->create_action(TTR("Paint TileMap"));
-							for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+						if (id != TileMap::INVALID_CELL) {
 
 
-								Point2 p = E->key();
-								undo_redo->add_do_method(node, "set_cellv", p, id, flip_h, flip_v, transpose);
-								undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
-							}
+							undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 							undo_redo->commit_action();
 							undo_redo->commit_action();
 
 
 							paint_undo.clear();
 							paint_undo.clear();
@@ -774,10 +763,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 						if (id != TileMap::INVALID_CELL) {
 						if (id != TileMap::INVALID_CELL) {
 
 
 							undo_redo->create_action(TTR("Line Draw"));
 							undo_redo->create_action(TTR("Line Draw"));
+							undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
 							for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 							for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
 
 
-								_set_cell(E->key(), id, flip_h, flip_v, transpose, true);
+								_set_cell(E->key(), id, flip_h, flip_v, transpose);
 							}
 							}
+							undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 							undo_redo->commit_action();
 							undo_redo->commit_action();
 
 
 							paint_undo.clear();
 							paint_undo.clear();
@@ -791,12 +782,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 						if (id != TileMap::INVALID_CELL) {
 						if (id != TileMap::INVALID_CELL) {
 
 
 							undo_redo->create_action(TTR("Rectangle Paint"));
 							undo_redo->create_action(TTR("Rectangle Paint"));
+							undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
 							for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
 							for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
 								for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
 								for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
 
 
-									_set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
+									_set_cell(Point2i(j, i), id, flip_h, flip_v, transpose);
 								}
 								}
 							}
 							}
+							undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 							undo_redo->commit_action();
 							undo_redo->commit_action();
 
 
 							canvas_item_editor->update();
 							canvas_item_editor->update();
@@ -806,10 +799,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 						Point2 ofs = over_tile - rectangle.position;
 						Point2 ofs = over_tile - rectangle.position;
 
 
 						undo_redo->create_action(TTR("Duplicate"));
 						undo_redo->create_action(TTR("Duplicate"));
+						undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 						for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
 
 
-							_set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose, true);
+							_set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose);
 						}
 						}
+						undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 						undo_redo->commit_action();
 						undo_redo->commit_action();
 
 
 						copydata.clear();
 						copydata.clear();
@@ -822,28 +817,23 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 					} else if (tool == TOOL_BUCKET) {
 					} else if (tool == TOOL_BUCKET) {
 
 
-						Dictionary pop;
-						pop["id"] = node->get_cell(over_tile.x, over_tile.y);
-						pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
-						pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
-						pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
-
 						PoolVector<Vector2> points = _bucket_fill(over_tile);
 						PoolVector<Vector2> points = _bucket_fill(over_tile);
 
 
 						if (points.size() == 0)
 						if (points.size() == 0)
 							return false;
 							return false;
 
 
+						undo_redo->create_action(TTR("Bucket Fill"));
+						undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
+
 						Dictionary op;
 						Dictionary op;
 						op["id"] = get_selected_tile();
 						op["id"] = get_selected_tile();
 						op["flip_h"] = flip_h;
 						op["flip_h"] = flip_h;
 						op["flip_v"] = flip_v;
 						op["flip_v"] = flip_v;
 						op["transpose"] = transpose;
 						op["transpose"] = transpose;
 
 
-						undo_redo->create_action(TTR("Bucket Fill"));
-
-						undo_redo->add_do_method(this, "_fill_points", points, op);
-						undo_redo->add_undo_method(this, "_fill_points", points, pop);
+						_fill_points(points, op);
 
 
+						undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
 						undo_redo->commit_action();
 						undo_redo->commit_action();
 
 
 						// We want to keep the bucket-tool active
 						// We want to keep the bucket-tool active
@@ -885,6 +875,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 					Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
 					Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
 
 
+					undo_redo->create_action(TTR("Erase TileMap"));
+					undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
+
 					if (mb->get_shift()) {
 					if (mb->get_shift()) {
 
 
 						if (mb->get_control())
 						if (mb->get_control())
@@ -898,7 +891,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 						tool = TOOL_ERASING;
 						tool = TOOL_ERASING;
 
 
-						paint_undo[local] = _get_op_from_cell(local);
 						_set_cell(local, TileMap::INVALID_CELL);
 						_set_cell(local, TileMap::INVALID_CELL);
 					}
 					}
 
 
@@ -908,18 +900,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 			} else {
 			} else {
 				if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
 				if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
 
 
-					if (paint_undo.size()) {
-						undo_redo->create_action(TTR("Erase TileMap"));
-						for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
-							Point2 p = E->key();
-							undo_redo->add_do_method(node, "set_cellv", p, TileMap::INVALID_CELL, false, false, false);
-							undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
-						}
-
-						undo_redo->commit_action();
-						paint_undo.clear();
-					}
+					undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
+					undo_redo->commit_action();
 
 
 					if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
 					if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
 						canvas_item_editor->update();
 						canvas_item_editor->update();
@@ -1006,10 +988,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 				Point2i pos = points[i];
 				Point2i pos = points[i];
 
 
-				if (!paint_undo.has(pos)) {
-					paint_undo[pos] = _get_op_from_cell(pos);
-				}
-
 				_set_cell(pos, TileMap::INVALID_CELL);
 				_set_cell(pos, TileMap::INVALID_CELL);
 			}
 			}
 
 

+ 1 - 1
editor/plugins/tile_map_editor_plugin.h

@@ -167,7 +167,7 @@ class TileMapEditor : public VBoxContainer {
 	void _update_palette();
 	void _update_palette();
 	void _menu_option(int p_option);
 	void _menu_option(int p_option);
 
 
-	void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, bool p_with_undo = false);
+	void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false);
 
 
 	void _canvas_mouse_enter();
 	void _canvas_mouse_enter();
 	void _canvas_mouse_exit();
 	void _canvas_mouse_exit();

+ 41 - 15
editor/plugins/tile_set_editor_plugin.cpp

@@ -1015,21 +1015,47 @@ void AutotileEditor::_on_tool_clicked(int p_tool) {
 		tile_set->autotile_clear_bitmask_map(get_current_tile());
 		tile_set->autotile_clear_bitmask_map(get_current_tile());
 		workspace->update();
 		workspace->update();
 	} else if (p_tool == SHAPE_DELETE) {
 	} else if (p_tool == SHAPE_DELETE) {
-		if (!edited_collision_shape.is_null()) {
-			Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(get_current_tile());
-			int index;
-			for (int i = 0; i < sd.size(); i++) {
-				if (sd[i].shape == edited_collision_shape) {
-					index = i;
-					break;
-				}
-			}
-			if (index >= 0) {
-				sd.remove(index);
-				tile_set->tile_set_shapes(get_current_tile(), sd);
-				edited_collision_shape.unref();
-				current_shape.resize(0);
-				workspace->update();
+		if (creating_shape) {
+			creating_shape = false;
+			current_shape.resize(0);
+			workspace->update();
+		} else {
+			switch (edit_mode) {
+				case EDITMODE_COLLISION: {
+					if (!edited_collision_shape.is_null()) {
+						Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(get_current_tile());
+						int index;
+						for (int i = 0; i < sd.size(); i++) {
+							if (sd[i].shape == edited_collision_shape) {
+								index = i;
+								break;
+							}
+						}
+						if (index >= 0) {
+							sd.remove(index);
+							tile_set->tile_set_shapes(get_current_tile(), sd);
+							edited_collision_shape = Ref<ConcavePolygonShape2D>();
+							current_shape.resize(0);
+							workspace->update();
+						}
+					}
+				} break;
+				case EDITMODE_NAVIGATION: {
+					if (!edited_navigation_shape.is_null()) {
+						tile_set->autotile_set_navigation_polygon(get_current_tile(), Ref<NavigationPolygon>(), edited_shape_coord);
+						edited_navigation_shape = Ref<NavigationPolygon>();
+						current_shape.resize(0);
+						workspace->update();
+					}
+				} break;
+				case EDITMODE_OCCLUSION: {
+					if (!edited_occlusion_shape.is_null()) {
+						tile_set->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+						edited_occlusion_shape = Ref<OccluderPolygon2D>();
+						current_shape.resize(0);
+						workspace->update();
+					}
+				} break;
 			}
 			}
 		}
 		}
 	} else if (p_tool == ZOOM_OUT) {
 	} else if (p_tool == ZOOM_OUT) {

+ 16 - 8
scene/2d/tile_map.cpp

@@ -716,7 +716,7 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
 	} else {
 	} else {
 		ERR_FAIL_COND(!Q); // quadrant should exist...
 		ERR_FAIL_COND(!Q); // quadrant should exist...
 
 
-		if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose)
+		if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y)
 			return; //nothing changed
 			return; //nothing changed
 	}
 	}
 
 
@@ -741,7 +741,7 @@ int TileMap::get_cellv(const Vector2 &p_pos) const {
 void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
 void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
 
 
 	for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
 	for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
-		for (int y = p_pos.y - 1; x <= p_pos.y + 1; y++) {
+		for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
 			PosKey p(x, y);
 			PosKey p(x, y);
 			if (dirty_bitmask.find(p) == NULL) {
 			if (dirty_bitmask.find(p) == NULL) {
 				dirty_bitmask.push_back(p);
 				dirty_bitmask.push_back(p);
@@ -810,6 +810,10 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
 			Vector2 coord = tile_set->autotile_get_subtile_for_bitmask(id, mask, this, Vector2(p_x, p_y));
 			Vector2 coord = tile_set->autotile_get_subtile_for_bitmask(id, mask, this, Vector2(p_x, p_y));
 			E->get().autotile_coord_x = (int)coord.x;
 			E->get().autotile_coord_x = (int)coord.x;
 			E->get().autotile_coord_y = (int)coord.y;
 			E->get().autotile_coord_y = (int)coord.y;
+
+			PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size());
+			Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
+			_make_quadrant_dirty(Q);
 		} else {
 		} else {
 			E->get().autotile_coord_x = 0;
 			E->get().autotile_coord_x = 0;
 			E->get().autotile_coord_y = 0;
 			E->get().autotile_coord_y = 0;
@@ -870,28 +874,31 @@ bool TileMap::is_cell_transposed(int p_x, int p_y) const {
 	return E->get().transpose;
 	return E->get().transpose;
 }
 }
 
 
-int TileMap::get_cell_autotile_coord_x(int p_x, int p_y) const {
+void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) {
 
 
 	PosKey pk(p_x, p_y);
 	PosKey pk(p_x, p_y);
 
 
 	const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
 	const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
 
 
 	if (!E)
 	if (!E)
-		return 0;
+		return;
 
 
-	return E->get().autotile_coord_x;
+	Cell c = E->get();
+	c.autotile_coord_x = p_coord.x;
+	c.autotile_coord_y = p_coord.y;
+	tile_map[pk] = c;
 }
 }
 
 
-int TileMap::get_cell_autotile_coord_y(int p_x, int p_y) const {
+Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const {
 
 
 	PosKey pk(p_x, p_y);
 	PosKey pk(p_x, p_y);
 
 
 	const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
 	const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
 
 
 	if (!E)
 	if (!E)
-		return 0;
+		return Vector2();
 
 
-	return E->get().autotile_coord_y;
+	return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y);
 }
 }
 
 
 void TileMap::_recreate_quadrants() {
 void TileMap::_recreate_quadrants() {
@@ -963,6 +970,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
 
 
 	int offset = (format == FORMAT_2_1_5) ? 3 : 2;
 	int offset = (format == FORMAT_2_1_5) ? 3 : 2;
 
 
+	clear();
 	for (int i = 0; i < c; i += offset) {
 	for (int i = 0; i < c; i += offset) {
 
 
 		const uint8_t *ptr = (const uint8_t *)&r[i];
 		const uint8_t *ptr = (const uint8_t *)&r[i];

+ 2 - 2
scene/2d/tile_map.h

@@ -241,8 +241,8 @@ public:
 	bool is_cell_x_flipped(int p_x, int p_y) const;
 	bool is_cell_x_flipped(int p_x, int p_y) const;
 	bool is_cell_y_flipped(int p_x, int p_y) const;
 	bool is_cell_y_flipped(int p_x, int p_y) const;
 	bool is_cell_transposed(int p_x, int p_y) const;
 	bool is_cell_transposed(int p_x, int p_y) const;
-	int get_cell_autotile_coord_x(int p_x, int p_y) const;
-	int get_cell_autotile_coord_y(int p_x, int p_y) const;
+	void set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord);
+	Vector2 get_cell_autotile_coord(int p_x, int p_y) const;
 
 
 	void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false);
 	void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false);
 	int get_cellv(const Vector2 &p_pos) const;
 	int get_cellv(const Vector2 &p_pos) const;