Editor<->world data merging
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user