|
@@ -132,16 +132,14 @@ void TileMapEditor::_menu_option(int p_option) {
|
|
|
if (!selection_active)
|
|
|
return;
|
|
|
|
|
|
- undo_redo->create_action(TTR("Erase Selection"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Erase Selection"));
|
|
|
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++) {
|
|
|
|
|
|
_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();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
selection_active = false;
|
|
|
copydata.clear();
|
|
@@ -200,6 +198,46 @@ void TileMapEditor::set_selected_tile(int p_tile) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) {
|
|
|
+
|
|
|
+ Dictionary cell_old;
|
|
|
+ Dictionary cell_new;
|
|
|
+
|
|
|
+ cell_old["id"] = p_cell_old.idx;
|
|
|
+ cell_old["flip_h"] = p_cell_old.xf;
|
|
|
+ cell_old["flip_y"] = p_cell_old.yf;
|
|
|
+ cell_old["transpose"] = p_cell_old.tr;
|
|
|
+ cell_old["auto_coord"] = p_cell_old.ac;
|
|
|
+
|
|
|
+ cell_new["id"] = p_cell_new.idx;
|
|
|
+ cell_new["flip_h"] = p_cell_new.xf;
|
|
|
+ cell_new["flip_y"] = p_cell_new.yf;
|
|
|
+ cell_new["transpose"] = p_cell_new.tr;
|
|
|
+ cell_new["auto_coord"] = p_cell_new.ac;
|
|
|
+
|
|
|
+ undo_redo->add_undo_method(node, "set_celld", p_vec, cell_old);
|
|
|
+ undo_redo->add_do_method(node, "set_celld", p_vec, cell_new);
|
|
|
+}
|
|
|
+
|
|
|
+void TileMapEditor::_start_undo(const String &p_action) {
|
|
|
+
|
|
|
+ undo_data.clear();
|
|
|
+ undo_redo->create_action(p_action);
|
|
|
+}
|
|
|
+
|
|
|
+void TileMapEditor::_finish_undo() {
|
|
|
+
|
|
|
+ if (undo_data.size()) {
|
|
|
+ for (Map<Point2i, CellOp>::Element *E = undo_data.front(); E; E = E->next()) {
|
|
|
+ _create_set_cell_undo(E->key(), E->get(), _get_op_from_cell(E->key()));
|
|
|
+ }
|
|
|
+
|
|
|
+ undo_data.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ undo_redo->commit_action();
|
|
|
+}
|
|
|
+
|
|
|
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);
|
|
@@ -213,6 +251,15 @@ 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)
|
|
|
return; //check that it's actually different
|
|
|
|
|
|
+ for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
|
|
|
+ for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
|
|
|
+ Point2i p = Point2i(x, y);
|
|
|
+ if (!undo_data.has(p)) {
|
|
|
+ undo_data[p] = _get_op_from_cell(p);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
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));
|
|
|
}
|
|
@@ -760,8 +807,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
tool = TOOL_PAINTING;
|
|
|
|
|
|
- undo_redo->create_action(TTR("Paint TileMap"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Paint TileMap"));
|
|
|
}
|
|
|
} else if (tool == TOOL_PICKING) {
|
|
|
|
|
@@ -785,8 +831,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
if (id != TileMap::INVALID_CELL) {
|
|
|
|
|
|
_set_cell(over_tile, id, flip_h, flip_v, transpose);
|
|
|
- undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
- undo_redo->commit_action();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
paint_undo.clear();
|
|
|
}
|
|
@@ -796,14 +841,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
if (id != TileMap::INVALID_CELL) {
|
|
|
|
|
|
- undo_redo->create_action(TTR("Line Draw"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Line Draw"));
|
|
|
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
|
|
|
|
|
|
_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();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
paint_undo.clear();
|
|
|
|
|
@@ -815,16 +858,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
if (id != TileMap::INVALID_CELL) {
|
|
|
|
|
|
- undo_redo->create_action(TTR("Rectangle Paint"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Rectangle Paint"));
|
|
|
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++) {
|
|
|
|
|
|
_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();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
canvas_item_editor->update();
|
|
|
}
|
|
@@ -832,14 +873,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
Point2 ofs = over_tile - rectangle.position;
|
|
|
|
|
|
- undo_redo->create_action(TTR("Duplicate"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Duplicate"));
|
|
|
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);
|
|
|
}
|
|
|
- undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
- undo_redo->commit_action();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
copydata.clear();
|
|
|
|
|
@@ -848,8 +887,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
Point2 ofs = over_tile - rectangle.position;
|
|
|
|
|
|
- undo_redo->create_action(TTR("Move"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
+ _start_undo(TTR("Move"));
|
|
|
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++) {
|
|
|
|
|
@@ -860,8 +898,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
_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();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
copydata.clear();
|
|
|
selection_active = false;
|
|
@@ -880,7 +917,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
return false;
|
|
|
|
|
|
undo_redo->create_action(TTR("Bucket Fill"));
|
|
|
- undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
|
|
|
Dictionary op;
|
|
|
op["id"] = get_selected_tile();
|
|
@@ -890,7 +926,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
_fill_points(points, op);
|
|
|
|
|
|
- undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
undo_redo->commit_action();
|
|
|
|
|
|
// We want to keep the bucket-tool active
|
|
@@ -942,8 +977,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
|
|
|
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"));
|
|
|
+ _start_undo(TTR("Erase TileMap"));
|
|
|
|
|
|
if (mb->get_shift()) {
|
|
|
#ifdef APPLE_STYLE_KEYS
|
|
@@ -970,8 +1004,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|
|
} else {
|
|
|
if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
|
|
|
|
|
|
- undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
|
|
|
- undo_redo->commit_action();
|
|
|
+ _finish_undo();
|
|
|
|
|
|
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
|
|
|
canvas_item_editor->update();
|
|
@@ -1534,6 +1567,7 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i &p_pos) {
|
|
|
op.yf = true;
|
|
|
if (node->is_cell_transposed(p_pos.x, p_pos.y))
|
|
|
op.tr = true;
|
|
|
+ op.ac = node->get_cell_autotile_coord(p_pos.x, p_pos.y);
|
|
|
}
|
|
|
return op;
|
|
|
}
|