mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-08 23:07:33 +07:00
Added dialogs for saving/loading maps directly, work on web support
This commit is contained in:
@ -164,6 +164,8 @@ text.editor.generate=Generate
|
||||
text.editor.resize=Resize
|
||||
text.editor.loadmap=Load Map
|
||||
text.editor.savemap=Save Map
|
||||
text.editor.importmap=Import Map
|
||||
text.editor.exportmap=Export Map
|
||||
text.editor.loadimage=Import Terrain
|
||||
text.editor.saveimage=Export Terrain
|
||||
text.editor.unsaved=[scarlet]You have unsaved changes![]\nAre you sure you want to exit?
|
||||
|
@ -16,6 +16,7 @@ import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Graphics;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.function.Consumer;
|
||||
import io.anuke.ucore.function.Listenable;
|
||||
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){
|
||||
new Dialog(title, "dialog"){{
|
||||
content().margin(30).add(text).padRight(6f);
|
||||
|
@ -8,10 +8,7 @@ import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.io.MapIO;
|
||||
import io.anuke.mindustry.io.MapMeta;
|
||||
import io.anuke.mindustry.io.MapTileData;
|
||||
import io.anuke.mindustry.io.Platform;
|
||||
import io.anuke.mindustry.io.*;
|
||||
import io.anuke.mindustry.ui.dialogs.FileChooser;
|
||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
@ -38,6 +35,7 @@ import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Strings;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@ -68,8 +66,7 @@ public class MapEditorDialog extends Dialog{
|
||||
saveFile = new FileChooser("$text.saveimage", false, file -> {
|
||||
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
|
||||
FileHandle result = file;
|
||||
ui.loadfrag.show();
|
||||
Timers.run(3f, () -> {
|
||||
ui.loadAnd(() -> {
|
||||
|
||||
try{
|
||||
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)));
|
||||
Log.err(e);
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
});
|
||||
|
||||
openFile = new FileChooser("$text.loadimage", FileChooser.mapFilter, true, file -> {
|
||||
ui.loadfrag.show();
|
||||
Timers.run(3f, () -> {
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
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)));
|
||||
Log.err(e);
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
});
|
||||
|
||||
saveImage = new FileChooser("$text.saveimage", false, file -> {
|
||||
file = file.parent().child(file.nameWithoutExtension() + ".png");
|
||||
FileHandle result = file;
|
||||
ui.loadfrag.show();
|
||||
Timers.run(3f, () -> {
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
Pixmaps.write(MapIO.generatePixmap(editor.getMap()), result);
|
||||
}catch (Exception e){
|
||||
ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false)));
|
||||
Log.err(e);
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
});
|
||||
|
||||
openImage = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, file -> {
|
||||
ui.loadfrag.show();
|
||||
Timers.run(3f, () -> {
|
||||
ui.loadAnd(() -> {
|
||||
try{
|
||||
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)));
|
||||
Log.err(e);
|
||||
}
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
});
|
||||
|
||||
@ -155,11 +145,23 @@ public class MapEditorDialog extends Dialog{
|
||||
t.row();
|
||||
|
||||
t.addImageTextButton("$text.editor.savemap", "icon-save-map", isize, () -> {
|
||||
saveFile.show();
|
||||
saveDialog.show();
|
||||
menu.hide();
|
||||
});
|
||||
|
||||
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();
|
||||
menu.hide();
|
||||
});
|
||||
@ -190,64 +192,40 @@ public class MapEditorDialog extends Dialog{
|
||||
menu.hide();
|
||||
}).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) -> {
|
||||
if(!(editor.getMap().width() == x && editor.getMap().height() == y)){
|
||||
ui.loadfrag.show();
|
||||
Timers.run(10f, () -> {
|
||||
ui.loadAnd(() -> {
|
||||
editor.resize(x, y);
|
||||
view.clearStack();
|
||||
ui.loadfrag.hide();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
saveDialog = new MapSaveDialog(name -> {
|
||||
ui.loadfrag.show();
|
||||
if(verifyMap()){
|
||||
saved = true;
|
||||
String before = editor.getMap().name;
|
||||
editor.getMap().name = name;
|
||||
Timers.run(10f, () -> {
|
||||
world.maps().saveAndReload(editor.getMap(), editor.pixmap());
|
||||
loadDialog.rebuild();
|
||||
ui.loadfrag.hide();
|
||||
loadDialog = new MapLoadDialog(map -> {
|
||||
saveDialog.setFieldText(map.name);
|
||||
|
||||
ui.loadAnd(() -> {
|
||||
try (DataInputStream stream = new DataInputStream(map.stream.get())){
|
||||
MapMeta meta = MapIO.readMapMeta(stream);
|
||||
MapTileData data = MapIO.readTileData(stream, meta, false);
|
||||
|
||||
editor.beginEdit(data, meta.tags);
|
||||
view.clearStack();
|
||||
|
||||
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);
|
||||
}catch (IOException e){
|
||||
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
|
||||
Log.err(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}else{
|
||||
ui.loadfrag.hide();
|
||||
}
|
||||
});*/
|
||||
|
||||
saveDialog = new MapSaveDialog(name -> {
|
||||
ui.loadAnd(() -> {
|
||||
saved = true;
|
||||
world.maps().saveAndReload(editor.getTags().get("name", name), editor.getMap(), editor.getTags());
|
||||
loadDialog.rebuild();
|
||||
});
|
||||
});
|
||||
|
||||
setFillParent(true);
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
package io.anuke.mindustry.io;
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import io.anuke.ucore.function.Supplier;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class Map {
|
||||
/**Internal map name. This is the filename, without any extensions.*/
|
||||
@ -9,12 +12,15 @@ public class Map {
|
||||
public final boolean custom;
|
||||
/**Metadata. Author description, display name, etc.*/
|
||||
public final MapMeta meta;
|
||||
/**Supplies a new input stream with the data of this map.*/
|
||||
public final Supplier<InputStream> stream;
|
||||
/**Preview 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.custom = custom;
|
||||
this.meta = meta;
|
||||
this.stream = streamSupplier;
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,18 @@ import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
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 java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static io.anuke.mindustry.Vars.customMapDirectory;
|
||||
import static io.anuke.mindustry.Vars.headless;
|
||||
import static io.anuke.mindustry.Vars.mapExtension;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Maps implements Disposable{
|
||||
/**List of all built-in maps.*/
|
||||
@ -21,16 +24,25 @@ public class Maps implements Disposable{
|
||||
/**Tile format version.*/
|
||||
private static final int version = 0;
|
||||
|
||||
/**Maps map names to the real maps.*/
|
||||
private ObjectMap<String, Map> maps = new ObjectMap<>();
|
||||
/**All maps stored in an ordered array.*/
|
||||
private Array<Map> allMaps = new Array<>();
|
||||
/**Temporary array used for returning things.*/
|
||||
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.*/
|
||||
public Array<Map> all(){
|
||||
return allMaps;
|
||||
}
|
||||
|
||||
/**Returns a list of only custo maps.*/
|
||||
/**Returns a list of only custom maps.*/
|
||||
public Array<Map> customMaps(){
|
||||
returnArray.clear();
|
||||
for(Map map : allMaps){
|
||||
@ -57,30 +69,59 @@ public class Maps implements Disposable{
|
||||
public void load(){
|
||||
try {
|
||||
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){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
loadCustomMaps();
|
||||
}
|
||||
|
||||
public void saveAndReload(String name, MapTileData data, ObjectMap<String, String> tags){
|
||||
FileHandle file = customMapDirectory.child(name + "." + mapExtension);
|
||||
//todo implement
|
||||
}
|
||||
|
||||
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().toLowerCase().equals(mapExtension)) loadMap(file, true);
|
||||
}catch (IOException e){
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMap(FileHandle file, boolean custom) throws IOException{
|
||||
DataInputStream ds = new DataInputStream(file.read());
|
||||
MapMeta meta = MapIO.readMapMeta(ds);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,7 +51,7 @@ public class DebugFragment implements Fragment {
|
||||
abottom().aleft();
|
||||
|
||||
new table("pane"){{
|
||||
defaults().fillX();
|
||||
defaults().fillX().width(100f);
|
||||
|
||||
new label("Debug");
|
||||
row();
|
||||
|
Reference in New Issue
Block a user