Editor<->world data merging

This commit is contained in:
Anuken
2019-05-06 17:03:53 -04:00
parent 51f9ad5a2c
commit 3035d569cc
13 changed files with 108 additions and 160 deletions

View File

@@ -18,7 +18,7 @@ import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.input.*; import io.anuke.mindustry.input.*;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -207,6 +207,23 @@ public class Control implements ApplicationListener{
}); });
} }
public void playZone(Zone zone){
ui.loadAnd(() -> {
logic.reset();
state.rules = zone.rules.get();
state.rules.zone = zone;
world.loadGenerator(zone.generator);
for(Tile core : state.teams.get(defaultTeam).cores){
for(ItemStack stack : zone.getStartingItems()){
core.entity.items.add(stack.item, stack.amount);
}
}
state.set(State.playing);
control.saves.zoneSave();
logic.play();
});
}
public boolean isHighScore(){ public boolean isHighScore(){
return hiscore; return hiscore;
} }

View File

@@ -202,24 +202,6 @@ public class World implements ApplicationListener{
return state.rules.zone; return state.rules.zone;
} }
//TODO move to Control
public void playZone(Zone zone){
ui.loadAnd(() -> {
logic.reset();
state.rules = zone.rules.get();
state.rules.zone = zone;
loadGenerator(zone.generator);
for(Tile core : state.teams.get(defaultTeam).cores){
for(ItemStack stack : zone.getStartingItems()){
core.entity.items.add(stack.item, stack.amount);
}
}
state.set(State.playing);
control.saves.zoneSave();
logic.play();
});
}
public void loadGenerator(Generator generator){ public void loadGenerator(Generator generator){
beginMapLoad(); beginMapLoad();
@@ -231,18 +213,9 @@ public class World implements ApplicationListener{
} }
public void loadMap(Map map){ public void loadMap(Map map){
beginMapLoad();
this.currentMap = map;
try{ try{
createTiles(map.width, map.height); MapIO.loadMap(map);
for(int x = 0; x < map.width; x++){
for(int y = 0; y < map.height; y++){
tiles[x][y] = new Tile(x, y);
}
}
MapIO.readTiles(map, tiles);
prepareTiles(tiles);
}catch(Exception e){ }catch(Exception e){
Log.err(e); Log.err(e);
if(!headless){ if(!headless){
@@ -254,7 +227,7 @@ public class World implements ApplicationListener{
return; return;
} }
endMapLoad(); this.currentMap = map;
invalidMap = false; invalidMap = false;
@@ -503,7 +476,7 @@ public class World implements ApplicationListener{
} }
} }
//update cliffs, occlusion data //update occlusion data
for(int x = 0; x < tiles.length; x++){ for(int x = 0; x < tiles.length; x++){
for(int y = 0; y < tiles[0].length; y++){ for(int y = 0; y < tiles[0].length; y++){
Tile tile = tiles[x][y]; Tile tile = tiles[x][y];

View File

@@ -60,9 +60,8 @@ public class DrawOperation{
class TileOpStruct{ class TileOpStruct{
short x; short x;
short y; short y;
short value;
byte type; byte type;
byte from;
byte to;
} }
public enum OpType{ public enum OpType{

View File

@@ -11,10 +11,11 @@ import io.anuke.mindustry.world.modules.*;
import static io.anuke.mindustry.Vars.ui; import static io.anuke.mindustry.Vars.ui;
//TODO somehow remove or replace this class with a more flexible solution
public class EditorTile extends Tile{ public class EditorTile extends Tile{
public EditorTile(int x, int y, byte floor, byte wall){ public EditorTile(int x, int y, short floor, short overlay, short wall){
super(x, y, floor, wall); super(x, y, floor, overlay, wall);
} }
@Override @Override

View File

@@ -1,9 +1,9 @@
package io.anuke.mindustry.editor; package io.anuke.mindustry.editor;
import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.collection.StringMap;
import io.anuke.arc.files.FileHandle; import io.anuke.arc.files.FileHandle;
import io.anuke.arc.math.Mathf; import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Pack;
import io.anuke.arc.util.Structs; import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
@@ -12,16 +12,18 @@ import io.anuke.mindustry.io.MapIO;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BlockPart;
import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.Floor;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.world;
public class MapEditor{ public class MapEditor{
public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15, 20}; public static final int[] brushSizes = {1, 2, 3, 4, 5, 9, 15, 20};
private ObjectMap<String, String> tags = new ObjectMap<>(); private StringMap tags = new StringMap();
private MapRenderer renderer = new MapRenderer(this); private MapRenderer renderer = new MapRenderer(this);
private Tile[][] tiles;
private OperationStack stack = new OperationStack(); private OperationStack stack = new OperationStack();
private DrawOperation currentOp; private DrawOperation currentOp;
@@ -32,7 +34,7 @@ public class MapEditor{
public Block drawBlock = Blocks.stone; public Block drawBlock = Blocks.stone;
public Team drawTeam = Team.blue; public Team drawTeam = Team.blue;
public ObjectMap<String, String> getTags(){ public StringMap getTags(){
return tags; return tags;
} }
@@ -40,7 +42,7 @@ public class MapEditor{
reset(); reset();
loading = true; loading = true;
tiles = createTiles(width, height); createTiles(width, height);
renderer.resize(width(), height()); renderer.resize(width(), height());
loading = false; loading = false;
} }
@@ -49,30 +51,25 @@ public class MapEditor{
reset(); reset();
loading = true; loading = true;
tiles = createTiles(map.width, map.height); //TODO redundant and does nothing since tiles are overwritten
createTiles(map.width, map.height);
tags.putAll(map.tags); tags.putAll(map.tags);
MapIO.readTiles(map, tiles); //TODO this actually creates the tiles, which are not editor tiles
MapIO.loadMap(map);
checkLinkedTiles(); checkLinkedTiles();
renderer.resize(width(), height()); renderer.resize(width(), height());
loading = false; loading = false;
} }
public void beginEdit(Tile[][] tiles){
reset();
this.tiles = tiles;
checkLinkedTiles();
renderer.resize(width(), height());
}
//adds missing blockparts //adds missing blockparts
public void checkLinkedTiles(){ public void checkLinkedTiles(){
Tile[][] tiles = world.getTiles();
//clear block parts first //clear block parts first
for(int x = 0; x < width(); x++){ for(int x = 0; x < width(); x++){
for(int y = 0; y < height(); y++){ for(int y = 0; y < height(); y++){
if(tiles[x][y].block() == Blocks.part){ if(tiles[x][y].block() instanceof BlockPart){
tiles[x][y].setBlock(Blocks.air); tiles[x][y].setBlock(Blocks.air);
tiles[x][y].setLinkByte((byte)0);
} }
} }
} }
@@ -80,22 +77,8 @@ public class MapEditor{
//set up missing blockparts //set up missing blockparts
for(int x = 0; x < width(); x++){ for(int x = 0; x < width(); x++){
for(int y = 0; y < height(); y++){ for(int y = 0; y < height(); y++){
Block drawBlock = tiles[x][y].block(); if(tiles[x][y].block().isMultiblock()){
if(drawBlock.isMultiblock()){ world.setBlock(tiles[x][y], tiles[x][y].block(), tiles[x][y].getTeam());
int offsetx = -(drawBlock.size - 1) / 2;
int offsety = -(drawBlock.size - 1) / 2;
for(int dx = 0; dx < drawBlock.size; dx++){
for(int dy = 0; dy < drawBlock.size; dy++){
int worldx = dx + offsetx + x;
int worldy = dy + offsety + y;
if(Structs.inBounds(worldx, worldy, width(), height()) && !(dx + offsetx == 0 && dy + offsety == 0)){
Tile tile = tiles[worldx][worldy];
tile.setBlock(Blocks.part);
tile.setLinkByte(Pack.byteByte((byte)(dx + offsetx + 8), (byte)(dy + offsety + 8)));
}
}
}
} }
} }
} }
@@ -108,15 +91,14 @@ public class MapEditor{
} }
/** Creates a 2-D array of EditorTiles with stone as the floor block. */ /** Creates a 2-D array of EditorTiles with stone as the floor block. */
public Tile[][] createTiles(int width, int height){ private void createTiles(int width, int height){
tiles = new Tile[width][height]; Tile[][] tiles = world.createTiles(width, height);
for(int x = 0; x < width; x++){ for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){ for(int y = 0; y < height; y++){
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (byte)0); tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
} }
} }
return tiles;
} }
public Map createMap(FileHandle file){ public Map createMap(FileHandle file){
@@ -131,40 +113,19 @@ public class MapEditor{
} }
public Tile[][] tiles(){ public Tile[][] tiles(){
return tiles; return world.getTiles();
} }
public Tile tile(int x, int y){ public Tile tile(int x, int y){
return tiles[x][y]; return world.rawTile(x, y);
} }
public int width(){ public int width(){
return tiles.length; return world.width();
} }
public int height(){ public int height(){
return tiles[0].length; return world.height();
}
public void updateLinks(Block block, int x, int y){
int offsetx = -(block.size - 1) / 2;
int offsety = -(block.size - 1) / 2;
for(int dx = 0; dx < block.size; dx++){
for(int dy = 0; dy < block.size; dy++){
int worldx = dx + offsetx + x;
int worldy = dy + offsety + y;
if(Structs.inBounds(worldx, worldy, width(), height())){
Tile tile = tiles[worldx][worldy];
if(!(worldx == x && worldy == y)){
tile.setBlock(Blocks.part);
tile.setLinkByte(Pack.byteByte((byte)(dx + offsetx + 8), (byte)(dy + offsety + 8)));
}
}
}
}
} }
public void draw(int x, int y, boolean paint){ public void draw(int x, int y, boolean paint){
@@ -177,45 +138,34 @@ public class MapEditor{
public void draw(int x, int y, boolean paint, Block drawBlock, double chance){ public void draw(int x, int y, boolean paint, Block drawBlock, double chance){
boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air; boolean isfloor = drawBlock instanceof Floor && drawBlock != Blocks.air;
Tile[][] tiles = world.getTiles();
if(drawBlock.isMultiblock()){ if(drawBlock.isMultiblock()){
x = Mathf.clamp(x, (drawBlock.size - 1) / 2, width() - drawBlock.size / 2 - 1); x = Mathf.clamp(x, (drawBlock.size - 1) / 2, width() - drawBlock.size / 2 - 1);
y = Mathf.clamp(y, (drawBlock.size - 1) / 2, height() - drawBlock.size / 2 - 1); y = Mathf.clamp(y, (drawBlock.size - 1) / 2, height() - drawBlock.size / 2 - 1);
int offsetx = -(drawBlock.size - 1) / 2; int offsetx = -(drawBlock.size - 1) / 2;
int offsety = -(drawBlock.size - 1) / 2; int offsety = -(drawBlock.size - 1) / 2;
for(int i = 0; i < 2; i++){ for(int dx = 0; dx < drawBlock.size; dx++){
for(int dx = 0; dx < drawBlock.size; dx++){ for(int dy = 0; dy < drawBlock.size; dy++){
for(int dy = 0; dy < drawBlock.size; dy++){ int worldx = dx + offsetx + x;
int worldx = dx + offsetx + x; int worldy = dy + offsety + y;
int worldy = dy + offsety + y;
if(Structs.inBounds(worldx, worldy, width(), height())){ if(Structs.inBounds(worldx, worldy, width(), height())){
Tile tile = tiles[worldx][worldy]; Tile tile = tiles[worldx][worldy];
if(i == 1){ Block block = tile.block();
tile.setBlock(Blocks.part);
tile.setLinkByte(Pack.byteByte((byte)(dx + offsetx + 8), (byte)(dy + offsety + 8)));
}else{
byte link = tile.getLinkByte();
Block block = tile.block();
if(link != 0){ //bail out if there's anything blocking the way
removeLinked(worldx - (Pack.leftByte(link) - 8), worldy - (Pack.rightByte(link) - 8)); if(block.isMultiblock() || block instanceof BlockPart){
}else if(block.isMultiblock()){ return;
removeLinked(worldx, worldy);
}
}
} }
} }
} }
} }
Tile tile = tiles[x][y]; world.setBlock(tiles[x][y], drawBlock, drawTeam);
tile.setBlock(drawBlock);
tile.setTeam(drawTeam);
}else{ }else{
for(int rx = -brushSize; rx <= brushSize; rx++){ for(int rx = -brushSize; rx <= brushSize; rx++){
for(int ry = -brushSize; ry <= brushSize; ry++){ for(int ry = -brushSize; ry <= brushSize; ry++){
@@ -228,14 +178,8 @@ public class MapEditor{
Tile tile = tiles[wx][wy]; Tile tile = tiles[wx][wy];
if(!isfloor){ if(!isfloor && (tile.isLinked() || tile.block().isMultiblock())){
byte link = tile.getLinkByte(); world.removeBlock(tile.link());
if(tile.block().isMultiblock()){
removeLinked(wx, wy);
}else if(link != 0 && tiles[wx][wy].block() == Blocks.part){
removeLinked(wx - (Pack.leftByte(link) - 8), wy - (Pack.rightByte(link) - 8));
}
} }
if(isfloor){ if(isfloor){
@@ -255,22 +199,6 @@ public class MapEditor{
} }
} }
private void removeLinked(int x, int y){
Block block = tiles[x][y].block();
int offsetx = -(block.size - 1) / 2;
int offsety = -(block.size - 1) / 2;
for(int dx = 0; dx < block.size; dx++){
for(int dy = 0; dy < block.size; dy++){
int worldx = x + dx + offsetx, worldy = y + dy + offsety;
if(Structs.inBounds(worldx, worldy, width(), height())){
tiles[worldx][worldy].setTeam(Team.none);
tiles[worldx][worldy].setBlock(Blocks.air);
}
}
}
}
public MapRenderer renderer(){ public MapRenderer renderer(){
return renderer; return renderer;
} }
@@ -278,11 +206,11 @@ public class MapEditor{
public void resize(int width, int height){ public void resize(int width, int height){
clearOp(); clearOp();
Tile[][] previous = tiles; Tile[][] previous = world.getTiles();
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2; int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
loading = true; loading = true;
tiles = new Tile[width][height]; Tile[][] tiles = world.createTiles(width, height);
for(int x = 0; x < width; x++){ for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){ for(int y = 0; y < height; y++){
int px = offsetX + x, py = offsetY + y; int px = offsetX + x, py = offsetY + y;
@@ -291,7 +219,7 @@ public class MapEditor{
tiles[x][y].x = (short)x; tiles[x][y].x = (short)x;
tiles[x][y].y = (short)y; tiles[x][y].y = (short)y;
}else{ }else{
tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (byte)0); tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
} }
} }
} }

View File

@@ -91,7 +91,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Platform.instance.showFileChooser("$editor.loadmap", "Map Files", file -> ui.loadAnd(() -> { Platform.instance.showFileChooser("$editor.loadmap", "Map Files", file -> ui.loadAnd(() -> {
try{ try{
//TODO what if it's an image? users should be warned for their stupidity //TODO what if it's an image? users should be warned for their stupidity
editor.beginEdit(MapIO.readMap(file, true)); editor.beginEdit(MapIO.createMap(file, true));
}catch(Exception e){ }catch(Exception e){
ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false)));
Log.err(e); Log.err(e);
@@ -216,7 +216,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
if(map != null && !map.custom){ if(map != null && !map.custom){
ui.showError("$editor.save.overwrite"); ui.showError("$editor.save.overwrite");
}else{ }else{
world.maps.saveMap(editor.getTags(), editor.tiles()); world.maps.saveMap(editor.getTags());
ui.showInfoFade("$editor.saved"); ui.showInfoFade("$editor.saved");
} }
} }

View File

@@ -1,18 +1,23 @@
package io.anuke.mindustry.io; package io.anuke.mindustry.io;
import io.anuke.arc.collection.StringMap;
import io.anuke.arc.files.FileHandle; import io.anuke.arc.files.FileHandle;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Pixmap; import io.anuke.arc.graphics.Pixmap;
import io.anuke.arc.graphics.Pixmap.Format; import io.anuke.arc.graphics.Pixmap.Format;
import io.anuke.arc.util.Time; import io.anuke.arc.util.Time;
import io.anuke.arc.util.io.CounterInputStream;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.Version;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.world.*; import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.Floor;
import java.io.IOException; import java.io.*;
import java.io.InputStream; import java.util.zip.InflaterInputStream;
import static io.anuke.mindustry.Vars.bufferSize;
/** Reads and writes map files. */ /** Reads and writes map files. */
public class MapIO{ public class MapIO{
@@ -31,6 +36,21 @@ public class MapIO{
} }
} }
public static Map createMap(FileHandle file, boolean custom) throws IOException{
try(InputStream is = new InflaterInputStream(file.read(bufferSize)); CounterInputStream counter = new CounterInputStream(is); DataInputStream stream = new DataInputStream(counter)){
SaveIO.readHeader(stream);
int version = stream.readInt();
SaveVersion ver = SaveIO.getSaveWriter(version);
StringMap tags = new StringMap();
ver.region("meta", stream, counter, in -> tags.putAll(ver.readStringMap(in)));
return new Map(file, tags.getInt("width"), tags.getInt("height"), tags, custom, version, Version.build);
}
}
public static void loadMap(Map map){
SaveIO.load(map.file);
}
public static Pixmap generatePreview(Map map) throws IOException{ public static Pixmap generatePreview(Map map) throws IOException{
Time.mark(); Time.mark();
Pixmap floors = new Pixmap(map.width, map.height, Format.RGBA8888); Pixmap floors = new Pixmap(map.width, map.height, Format.RGBA8888);

View File

@@ -67,8 +67,12 @@ public abstract class SaveFileReader{
return length; return length;
} }
/** Skip a chunk completely. */ public void skipRegion(DataInput input) throws IOException{
public void skipChunk(DataInput input, boolean isByte) throws IOException{ skipRegion(input, false);
}
/** Skip a region completely. */
public void skipRegion(DataInput input, boolean isByte) throws IOException{
int length = readChunk(input, isByte, t -> {}); int length = readChunk(input, isByte, t -> {});
int skipped = input.skipBytes(length); int skipped = input.skipBytes(length);
if(length != skipped){ if(length != skipped){

View File

@@ -30,6 +30,10 @@ public class SaveIO{
return versionArray.peek(); return versionArray.peek();
} }
public static SaveVersion getSaveWriter(int version){
return versions.get(version);
}
public static void saveToSlot(int slot){ public static void saveToSlot(int slot){
FileHandle file = fileFor(slot); FileHandle file = fileFor(slot);
boolean exists = file.exists(); boolean exists = file.exists();

View File

@@ -53,7 +53,9 @@ public abstract class SaveVersion extends SaveFileReader{
"wave", state.wave, "wave", state.wave,
"wavetime", state.wavetime, "wavetime", state.wavetime,
"stats", Serialization.writeStatsJson(state.stats), "stats", Serialization.writeStatsJson(state.stats),
"rules", Serialization.writeRulesJson(state.rules) "rules", Serialization.writeRulesJson(state.rules),
"width", world.width(),
"height", world.height()
)); ));
} }

View File

@@ -52,7 +52,7 @@ public class Maps implements Disposable{
FileHandle file = Core.files.internal("maps/" + name + "." + mapExtension); FileHandle file = Core.files.internal("maps/" + name + "." + mapExtension);
try{ try{
return MapIO.readMap(file, false); return MapIO.createMap(file, false);
}catch(IOException e){ }catch(IOException e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -81,13 +81,12 @@ public class Maps implements Disposable{
* Save a custom map to the directory. This updates all values and stored data necessary. * Save a custom map to the directory. This updates all values and stored data necessary.
* The tags are copied to prevent mutation later. * The tags are copied to prevent mutation later.
*/ */
public void saveMap(ObjectMap<String, String> baseTags, Tile[][] data){ public void saveMap(ObjectMap<String, String> baseTags){
try{ try{
ObjectMap<String, String> tags = new ObjectMap<>(baseTags); ObjectMap<String, String> tags = new ObjectMap<>(baseTags);
String name = tags.get("name"); String name = tags.get("name");
if(name == null) throw new IllegalArgumentException("Can't save a map with no name. How did this happen?"); if(name == null) throw new IllegalArgumentException("Can't save a map with no name. How did this happen?");
//FileHandle file = customMapDirectory.child(name + "." + mapExtension);
FileHandle file; FileHandle file;
//find map with the same exact display name //find map with the same exact display name
@@ -106,7 +105,7 @@ public class Maps implements Disposable{
} }
//create map, write it, etc etc etc //create map, write it, etc etc etc
Map map = new Map(file, data.length, data[0].length, tags, true); Map map = new Map(file, world.width(), world.height(), tags, true);
MapIO.writeMap(file, map, data); MapIO.writeMap(file, map, data);
if(!headless){ if(!headless){
@@ -171,7 +170,7 @@ public class Maps implements Disposable{
} }
private void loadMap(FileHandle file, boolean custom) throws IOException{ private void loadMap(FileHandle file, boolean custom) throws IOException{
Map map = MapIO.readMap(file, custom); Map map = MapIO.createMap(file, custom);
if(map.name() == null){ if(map.name() == null){
throw new IOException("Map name cannot be empty! File: " + file); throw new IOException("Map name cannot be empty! File: " + file);

View File

@@ -24,7 +24,7 @@ public class MapsDialog extends FloatingDialog{
buttons.addImageTextButton("$editor.importmap", "icon-add", 14 * 2, () -> { buttons.addImageTextButton("$editor.importmap", "icon-add", 14 * 2, () -> {
Platform.instance.showFileChooser("$editor.importmap", "Map File", file -> { Platform.instance.showFileChooser("$editor.importmap", "Map File", file -> {
try{ try{
Map map = MapIO.readMap(file, true); Map map = MapIO.createMap(file, true);
String name = map.tags.get("name"); String name = map.tags.get("name");
if(name == null){ if(name == null){
ui.showError("$editor.errorname"); ui.showError("$editor.errorname");

View File

@@ -27,6 +27,7 @@ if(!hasProperty("release")){
use(':Arc:extensions:freetype', '../Arc/extensions/freetype') use(':Arc:extensions:freetype', '../Arc/extensions/freetype')
use(':Arc:extensions:recorder', '../Arc/extensions/recorder') use(':Arc:extensions:recorder', '../Arc/extensions/recorder')
use(':Arc:extensions:arcnet', '../Arc/extensions/arcnet') use(':Arc:extensions:arcnet', '../Arc/extensions/arcnet')
use(':Arc:extensions:packer', '../Arc/extensions/packer')
use(':Arc:backends', '../Arc/backends') use(':Arc:backends', '../Arc/backends')
use(':Arc:backends:backend-lwjgl3', '../Arc/backends/backend-lwjgl3') use(':Arc:backends:backend-lwjgl3', '../Arc/backends/backend-lwjgl3')
use(':Arc:backends:backend-android', '../Arc/backends/backend-android') use(':Arc:backends:backend-android', '../Arc/backends/backend-android')