Added undoing for map editor

This commit is contained in:
Anuken
2018-05-22 00:02:43 -04:00
parent 2d65c9734c
commit d97a585eba
7 changed files with 113 additions and 35 deletions

View File

@@ -1,38 +1,68 @@
package io.anuke.mindustry.editor;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.io.MapTileData;
import java.nio.ByteBuffer;
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
import io.anuke.ucore.util.Bits;
public class DrawOperation implements Disposable{
/**Data to apply operation to.*/
MapTileData data;
/**Format:
* position (int)
* packed data FROM (use TileDataMarker's read/write methods)
* packed data TO (use TileDataMarker's read/write methods)
*/
ByteBuffer operation;
//TileDataMarker writer = new TileDataMarker();
private MapTileData data;
/**List of per-tile operations that occurred.*/
private Array<TileOperation> operations = new Array<>();
/**Checks for duplicate operations, useful for brushes.*/
private IntSet checks = new IntSet();
public DrawOperation(MapTileData data){
this.data = data;
}
public void set(ByteBuffer operation) {
this.operation = operation;
public boolean isEmpty(){
return operations.size == 0;
}
public void undo() {
//TODO implement
public boolean checkDuplicate(short x, short y){
int i = Bits.packInt(x, y);
if(checks.contains(i)) return true;
checks.add(i);
return false;
}
public void redo() {
//TODO implement
public void addOperation(TileOperation op){
operations.add(op);
}
public void undo(MapEditor editor) {
for(int i = operations.size - 1; i >= 0; i --){
TileOperation op = operations.get(i);
data.write(op.x, op.y, op.from);
editor.renderer().updatePoint(op.x, op.y);
}
}
public void redo(MapEditor editor) {
for(TileOperation op : operations){
data.write(op.x, op.y, op.to);
editor.renderer().updatePoint(op.x, op.y);
}
}
@Override
public void dispose() {}
public static class TileOperation{
public short x, y;
public TileDataMarker from;
public TileDataMarker to;
public TileOperation(short x, short y, TileDataMarker from, TileDataMarker to) {
this.x = x;
this.y = y;
this.from = from;
this.to = to;
}
}
}

View File

@@ -67,7 +67,7 @@ public enum EditorTool{
else
writer.wall = (byte)editor.getDrawBlock().id;
editor.getMap().write(px, py, writer);
editor.write(px, py, writer, false);
editor.renderer().updatePoint(px, py);
if(px > 0 && !set.contains(asInt(px - 1, py, width))) points.add(asInt(px - 1, py, width));

View File

@@ -1,6 +1,8 @@
package io.anuke.mindustry.editor;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.editor.DrawOperation.TileOperation;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.MapTileData;
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
@@ -111,7 +113,7 @@ public class MapEditor{
writer.team = (byte)drawTeam.ordinal();
writer.floor = floor;
writer.link = Bits.packByte((byte) (dx + offsetx + 8), (byte) (dy + offsety + 8));
map.write(worldx, worldy, writer);
write(worldx, worldy, writer, false);
renderer.updatePoint(worldx, worldy);
}
@@ -129,7 +131,7 @@ public class MapEditor{
writer.team = (byte)drawTeam.ordinal();
writer.rotation = 0;
writer.link = 0;
map.write(x, y, writer);
write(x, y, writer, false);
renderer.updatePoint(x, y);
}else{
@@ -140,7 +142,7 @@ public class MapEditor{
if (x + rx < 0 || y + ry < 0 || x + rx >= map.width() || y + ry >= map.height()) {
continue;
}
map.write(x + rx, y + ry, writer);
write(x + rx, y + ry, writer, true);
renderer.updatePoint(x + rx, y + ry);
}
}
@@ -163,7 +165,7 @@ public class MapEditor{
marker.wall = 0;
marker.rotation = 0;
marker.team = 0;
map.write(worldx, worldy, marker);
write(worldx, worldy, marker, false);
if(worldx == x && worldy == y){
renderer.updatePoint(worldx, worldy);
@@ -173,6 +175,27 @@ public class MapEditor{
}
}
public void write(int x, int y, TileDataMarker writer, boolean checkDupes){
boolean dupe = checkDupes && Vars.ui.editor.getView().checkForDuplicates((short) x, (short) y);
TileDataMarker prev = null;
if(!dupe) {
prev = map.new TileDataMarker();
map.position(x, y);
map.read(prev);
}
map.write(x, y, writer);
if(!dupe) {
TileDataMarker current = map.new TileDataMarker();
map.position(x, y);
map.read(current);
Vars.ui.editor.getView().addTileOp(new TileOperation((short) x, (short) y, prev, current));
}
}
public MapRenderer renderer() {
return renderer;
}

View File

@@ -420,6 +420,14 @@ public class MapEditorDialog extends Dialog{
}
}
if(Inputs.keyTap(Input.R)){
editor.setDrawRotation((editor.getDrawRotation() + 1)%4);
}
if(Inputs.keyTap(Input.E)){
editor.setDrawRotation(Mathf.mod((editor.getDrawRotation() + 1), 4));
}
//ctrl keys (undo, redo, save)
if(UIUtils.ctrl()){
if(Inputs.keyTap(Input.Z)){
@@ -434,14 +442,6 @@ public class MapEditorDialog extends Dialog{
saveDialog.save();
}
if(Inputs.keyTap(Input.R)){
editor.setDrawRotation((editor.getDrawRotation() + 1)%4);
}
if(Inputs.keyTap(Input.E)){
editor.setDrawRotation(Mathf.mod((editor.getDrawRotation() + 1), 4));
}
if(Inputs.keyTap(Input.G)){
view.setGrid(!view.isGrid());
}

View File

@@ -10,6 +10,7 @@ import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.editor.DrawOperation.TileOperation;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.ui.GridImage;
import io.anuke.ucore.core.Core;
@@ -77,16 +78,24 @@ public class MapView extends Element implements GestureListener{
public void undo(){
if(stack.canUndo()){
stack.undo();
stack.undo(editor);
}
}
public void redo(){
if(stack.canRedo()){
stack.redo();
stack.redo(editor);
}
}
public void addTileOp(TileOperation t){
op.addOperation(t);
}
public boolean checkForDuplicates(short x, short y){
return op.checkDuplicate(x, y);
}
public MapView(MapEditor editor){
this.editor = editor;
@@ -114,6 +123,8 @@ public class MapView extends Element implements GestureListener{
return false;
}
op = new DrawOperation(editor.getMap());
updated = false;
GridPoint2 p = project(x, y);
@@ -146,6 +157,14 @@ public class MapView extends Element implements GestureListener{
}
updated = true;
}
if(op != null && updated){
if(!op.isEmpty()){
stack.add(op);
}
op = null;
}
}
@Override

View File

@@ -37,18 +37,18 @@ public class OperationStack{
return !(index > -1 || stack.size + index < 0);
}
public void undo(){
public void undo(MapEditor editor){
if(!canUndo()) return;
stack.get(stack.size - 1 + index).undo();
stack.get(stack.size - 1 + index).undo(editor);
index --;
}
public void redo(){
public void redo(MapEditor editor){
if(!canRedo()) return;
index ++;
stack.get(stack.size - 1 + index).redo();
stack.get(stack.size - 1 + index).redo(editor);
}
}

View File

@@ -68,6 +68,12 @@ public class MapTileData {
return tile;
}
/**Reads and returns the next tile data.*/
public TileDataMarker read(TileDataMarker marker){
marker.read(buffer);
return marker;
}
/**Reads and returns the next tile data.*/
public TileDataMarker readAt(int x, int y){
position(x, y);