Added dialogs for saving/loading maps directly, work on web support

This commit is contained in:
Anuken
2018-05-22 17:28:21 -04:00
parent f0fa126e7b
commit b20f026c7b
6 changed files with 123 additions and 87 deletions

View File

@ -164,6 +164,8 @@ text.editor.generate=Generate
text.editor.resize=Resize text.editor.resize=Resize
text.editor.loadmap=Load Map text.editor.loadmap=Load Map
text.editor.savemap=Save Map text.editor.savemap=Save Map
text.editor.importmap=Import Map
text.editor.exportmap=Export Map
text.editor.loadimage=Import Terrain text.editor.loadimage=Import Terrain
text.editor.saveimage=Export Terrain text.editor.saveimage=Export Terrain
text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit? text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit?

View File

@ -16,6 +16,7 @@ import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Listenable; import io.anuke.ucore.function.Listenable;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
@ -211,6 +212,14 @@ public class UI extends SceneModule{
} }
} }
public void loadAnd(Callable call){
loadfrag.show();
Timers.run(6f, () -> {
call.run();
loadfrag.hide();
});
}
public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){ public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
new Dialog(title, "dialog"){{ new Dialog(title, "dialog"){{
content().margin(30).add(text).padRight(6f); content().margin(30).add(text).padRight(6f);

View File

@ -8,10 +8,7 @@ import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.io.*;
import io.anuke.mindustry.io.MapMeta;
import io.anuke.mindustry.io.MapTileData;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.ui.dialogs.FileChooser; import io.anuke.mindustry.ui.dialogs.FileChooser;
import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@ -38,6 +35,7 @@ import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
@ -68,8 +66,7 @@ public class MapEditorDialog extends Dialog{
saveFile = new FileChooser("$text.saveimage", false, file -> { saveFile = new FileChooser("$text.saveimage", false, file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension); file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file; FileHandle result = file;
ui.loadfrag.show(); ui.loadAnd(() -> {
Timers.run(3f, () -> {
try{ try{
if(!editor.getTags().containsKey("name")){ if(!editor.getTags().containsKey("name")){
@ -80,13 +77,11 @@ public class MapEditorDialog extends Dialog{
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
} }
ui.loadfrag.hide();
}); });
}); });
openFile = new FileChooser("$text.loadimage", FileChooser.mapFilter, true, file -> { openFile = new FileChooser("$text.loadimage", FileChooser.mapFilter, true, file -> {
ui.loadfrag.show(); ui.loadAnd(() -> {
Timers.run(3f, () -> {
try{ try{
DataInputStream stream = new DataInputStream(file.read()); DataInputStream stream = new DataInputStream(file.read());
@ -99,28 +94,24 @@ public class MapEditorDialog extends Dialog{
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
} }
ui.loadfrag.hide();
}); });
}); });
saveImage = new FileChooser("$text.saveimage", false, file -> { saveImage = new FileChooser("$text.saveimage", false, file -> {
file = file.parent().child(file.nameWithoutExtension() + ".png"); file = file.parent().child(file.nameWithoutExtension() + ".png");
FileHandle result = file; FileHandle result = file;
ui.loadfrag.show(); ui.loadAnd(() -> {
Timers.run(3f, () -> {
try{ try{
Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result); Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result);
}catch (Exception e){ }catch (Exception e){
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
} }
ui.loadfrag.hide();
}); });
}); });
openImage = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> { openImage = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> {
ui.loadfrag.show(); ui.loadAnd(() -> {
Timers.run(3f, () -> {
try{ try{
MapTileData data = MapIO.readPixmap(new Pixmap(file)); MapTileData data = MapIO.readPixmap(new Pixmap(file));
@ -130,7 +121,6 @@ public class MapEditorDialog extends Dialog{
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false))); ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
} }
ui.loadfrag.hide();
}); });
}); });
@ -155,11 +145,23 @@ public class MapEditorDialog extends Dialog{
t.row(); t.row();
t.addImageTextButton("$text.editor.savemap", "icon-save-map", isize, () -> { t.addImageTextButton("$text.editor.savemap", "icon-save-map", isize, () -> {
saveFile.show(); saveDialog.show();
menu.hide(); menu.hide();
}); });
t.addImageTextButton("$text.editor.loadmap", "icon-load-map", isize, () -> { t.addImageTextButton("$text.editor.loadmap", "icon-load-map", isize, () -> {
loadDialog.show();
menu.hide();
});
t.row();
t.addImageTextButton("$text.editor.importmap", "icon-save-map", isize, () -> {
saveFile.show();
menu.hide();
});
t.addImageTextButton("$text.editor.exportmap", "icon-load-map", isize, () -> {
openFile.show(); openFile.show();
menu.hide(); menu.hide();
}); });
@ -190,64 +192,40 @@ public class MapEditorDialog extends Dialog{
menu.hide(); menu.hide();
}).size(470f, 60f); }).size(470f, 60f);
/*
loadDialog = new MapLoadDialog(map -> {
saveDialog.setFieldText(map.name);
ui.loadfrag.show();
Timers.run(3f, () -> {
Map copy = new Map();
copy.name = map.name;
copy.id = -1;
copy.pixmap = Pixmaps.copy(map.pixmap);
copy.texture = new Texture(copy.pixmap);
copy.oreGen = map.oreGen;
editor.beginEdit(copy);
ui.loadfrag.hide();
view.clearStack();
});
});*/
resizeDialog = new MapResizeDialog(editor, (x, y) -> { resizeDialog = new MapResizeDialog(editor, (x, y) -> {
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){ if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
ui.loadfrag.show(); ui.loadAnd(() -> {
Timers.run(10f, () -> {
editor.resize(x, y); editor.resize(x, y);
view.clearStack(); view.clearStack();
ui.loadfrag.hide();
}); });
} }
}); });
/* loadDialog = new MapLoadDialog(map -> {
saveDialog = new MapSaveDialog(name -> { saveDialog.setFieldText(map.name);
ui.loadfrag.show();
if(verifyMap()){ ui.loadAnd(() -> {
saved = true; try (DataInputStream stream = new DataInputStream(map.stream.get())){
String before = editor.getMap().name; MapMeta meta = MapIO.readMapMeta(stream);
editor.getMap().name = name; MapTileData data = MapIO.readTileData(stream, meta, false);
Timers.run(10f, () -> {
world.maps().saveAndReload(editor.getMap(), editor.pixmap()); editor.beginEdit(data, meta.tags);
loadDialog.rebuild();
ui.loadfrag.hide();
view.clearStack(); view.clearStack();
}catch (IOException e){
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
Log.err(e);
}
});
});
if(!name.equals(before)) {
Map map = new Map();
map.name = editor.getMap().name;
map.oreGen = editor.getMap().oreGen;
map.pixmap = Pixmaps.copy(editor.getMap().pixmap);
map.texture = new Texture(map.pixmap);
map.custom = true;
editor.beginEdit(map);
}
});
}else{ saveDialog = new MapSaveDialog(name -> {
ui.loadfrag.hide(); ui.loadAnd(() -> {
} saved = true;
});*/ world.maps().saveAndReload(editor.getTags().get("name", name), editor.getMap(), editor.getTags());
loadDialog.rebuild();
});
});
setFillParent(true); setFillParent(true);

View File

@ -1,6 +1,9 @@
package io.anuke.mindustry.io; package io.anuke.mindustry.io;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import io.anuke.ucore.function.Supplier;
import java.io.InputStream;
public class Map { public class Map {
/**Internal map name. This is the filename, without any extensions.*/ /**Internal map name. This is the filename, without any extensions.*/
@ -9,12 +12,15 @@ public class Map {
public final boolean custom; public final boolean custom;
/**Metadata. Author description, display name, etc.*/ /**Metadata. Author description, display name, etc.*/
public final MapMeta meta; public final MapMeta meta;
/**Supplies a new input stream with the data of this map.*/
public final Supplier<InputStream> stream;
/**Preview texture.*/ /**Preview texture.*/
public Texture texture; public Texture texture;
public Map(String name, MapMeta meta, boolean custom){ public Map(String name, MapMeta meta, boolean custom, Supplier<InputStream> streamSupplier){
this.name = name; this.name = name;
this.custom = custom; this.custom = custom;
this.meta = meta; this.meta = meta;
this.stream = streamSupplier;
} }
} }

View File

@ -5,15 +5,18 @@ import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Log;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import static io.anuke.mindustry.Vars.customMapDirectory; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.mapExtension;
public class Maps implements Disposable{ public class Maps implements Disposable{
/**List of all built-in maps.*/ /**List of all built-in maps.*/
@ -21,16 +24,25 @@ public class Maps implements Disposable{
/**Tile format version.*/ /**Tile format version.*/
private static final int version = 0; private static final int version = 0;
/**Maps map names to the real maps.*/
private ObjectMap<String, Map> maps = new ObjectMap<>(); private ObjectMap<String, Map> maps = new ObjectMap<>();
/**All maps stored in an ordered array.*/
private Array<Map> allMaps = new Array<>(); private Array<Map> allMaps = new Array<>();
/**Temporary array used for returning things.*/
private Array<Map> returnArray = new Array<>(); private Array<Map> returnArray = new Array<>();
/**Used for writing a list of custom map names on GWT.*/
private Json json = new Json();
public Maps(){
}
/**Returns a list of all maps, including custom ones.*/ /**Returns a list of all maps, including custom ones.*/
public Array<Map> all(){ public Array<Map> all(){
return allMaps; return allMaps;
} }
/**Returns a list of only custo maps.*/ /**Returns a list of only custom maps.*/
public Array<Map> customMaps(){ public Array<Map> customMaps(){
returnArray.clear(); returnArray.clear();
for(Map map : allMaps){ for(Map map : allMaps){
@ -57,32 +69,61 @@ public class Maps implements Disposable{
public void load(){ public void load(){
try { try {
for (String name : defaultMapNames) { for (String name : defaultMapNames) {
loadMap(Gdx.files.internal("maps/" + name + "." + mapExtension), false); FileHandle file = Gdx.files.internal("maps/" + name + "." + mapExtension);
loadMap(file.nameWithoutExtension(), file::read, false);
} }
}catch (IOException e){ }catch (IOException e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
for(FileHandle file : customMapDirectory.list()){ loadCustomMaps();
try{
if(file.extension().toLowerCase().equals(mapExtension)) loadMap(file, true);
}catch (IOException e){
Log.err("Failed to load custom map file '{0}'!", file);
Log.err(e);
}
}
} }
private void loadMap(FileHandle file, boolean custom) throws IOException{ public void saveAndReload(String name, MapTileData data, ObjectMap<String, String> tags){
DataInputStream ds = new DataInputStream(file.read()); FileHandle file = customMapDirectory.child(name + "." + mapExtension);
MapMeta meta = MapIO.readMapMeta(ds); //todo implement
Map map = new Map(file.nameWithoutExtension(), meta, custom);
if(!headless) map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true)));
maps.put(map.name, map);
allMaps.add(map);
} }
private void loadMap(String name, Supplier<InputStream> supplier, boolean custom) throws IOException{
try(DataInputStream ds = new DataInputStream(supplier.get())) {
MapMeta meta = MapIO.readMapMeta(ds);
Map map = new Map(name, meta, custom, supplier);
if (!headless) map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true)));
maps.put(map.name, map);
allMaps.add(map);
}
}
private void loadCustomMaps(){
if(!gwt){
for(FileHandle file : customMapDirectory.list()){
try{
if(file.extension().equalsIgnoreCase(mapExtension)){
loadMap(file.nameWithoutExtension(), file::read, true);
}
}catch (Exception e){
Log.err("Failed to load custom map file '{0}'!", file);
Log.err(e);
}
}
}else{
Array<String> maps = json.fromJson(Array.class, Settings.getString("custom-maps", "{}"));
for(String name : maps){
try{
String data = Settings.getString("map-data-" + name);
byte[] bytes = data.getBytes();
loadMap(name, () -> new ByteArrayInputStream(bytes), true);
}catch (Exception e){
Log.err("Failed to load custom map '{0}'!", name);
Log.err(e);
}
}
}
}
@Override @Override
public void dispose() { public void dispose() {

View File

@ -51,7 +51,7 @@ public class DebugFragment implements Fragment {
abottom().aleft(); abottom().aleft();
new table("pane"){{ new table("pane"){{
defaults().fillX(); defaults().fillX().width(100f);
new label("Debug"); new label("Debug");
row(); row();