Implemented correct map loading, legacy format support
This commit is contained in:
@@ -30,6 +30,8 @@ import java.util.Locale;
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class Vars{
|
public class Vars{
|
||||||
|
/**IO buffer size.*/
|
||||||
|
public static final int bufferSize = 8192;
|
||||||
/**global charset*/
|
/**global charset*/
|
||||||
public static final Charset charset = Charset.forName("UTF-8");
|
public static final Charset charset = Charset.forName("UTF-8");
|
||||||
/**main application name, capitalized*/
|
/**main application name, capitalized*/
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ public class World implements ApplicationListener{
|
|||||||
|
|
||||||
try{
|
try{
|
||||||
createTiles(map.width, map.height);
|
createTiles(map.width, map.height);
|
||||||
tiles = MapIO.readTiles(map, tiles);
|
MapIO.readTiles(map, tiles);
|
||||||
prepareTiles(tiles);
|
prepareTiles(tiles);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ package io.anuke.mindustry.editor;
|
|||||||
|
|
||||||
import io.anuke.annotations.Annotations.Struct;
|
import io.anuke.annotations.Annotations.Struct;
|
||||||
import io.anuke.arc.collection.LongArray;
|
import io.anuke.arc.collection.LongArray;
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
|
import io.anuke.mindustry.gen.TileOp;
|
||||||
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.content;
|
||||||
|
|
||||||
public class DrawOperation{
|
public class DrawOperation{
|
||||||
private LongArray array = new LongArray();
|
private LongArray array = new LongArray();
|
||||||
@@ -17,12 +23,28 @@ public class DrawOperation{
|
|||||||
public void undo(MapEditor editor){
|
public void undo(MapEditor editor){
|
||||||
for(int i = 0; i < array.size; i++){
|
for(int i = 0; i < array.size; i++){
|
||||||
long l = array.get(i);
|
long l = array.get(i);
|
||||||
|
set(editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.from(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redo(MapEditor editor){
|
public void redo(MapEditor editor){
|
||||||
for(int i = 0; i < array.size; i++){
|
for(int i = 0; i < array.size; i++){
|
||||||
long l = array.get(i);
|
long l = array.get(i);
|
||||||
|
set(editor.tile(TileOp.x(l), TileOp.y(l)), TileOp.type(l), TileOp.to(l));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(Tile tile, byte type, byte to){
|
||||||
|
if(type == OpType.floor.ordinal()){
|
||||||
|
tile.setFloor((Floor)content.block(to));
|
||||||
|
}else if(type == OpType.block.ordinal()){
|
||||||
|
tile.setBlock(content.block(to));
|
||||||
|
}else if(type == OpType.rotation.ordinal()){
|
||||||
|
tile.setRotation(to);
|
||||||
|
}else if(type == OpType.team.ordinal()){
|
||||||
|
tile.setTeam(Team.all[to]);
|
||||||
|
}else if(type == OpType.ore.ordinal()){
|
||||||
|
tile.setOre(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +61,7 @@ public class DrawOperation{
|
|||||||
floor,
|
floor,
|
||||||
block,
|
block,
|
||||||
rotation,
|
rotation,
|
||||||
team
|
team,
|
||||||
|
ore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import io.anuke.mindustry.gen.TileOp;
|
|||||||
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.Floor;
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
import io.anuke.mindustry.world.modules.ConsumeModule;
|
||||||
|
import io.anuke.mindustry.world.modules.ItemModule;
|
||||||
|
import io.anuke.mindustry.world.modules.LiquidModule;
|
||||||
|
import io.anuke.mindustry.world.modules.PowerModule;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.ui;
|
import static io.anuke.mindustry.Vars.ui;
|
||||||
|
|
||||||
@@ -28,7 +32,7 @@ public class EditorTile extends Tile{
|
|||||||
Block previous = block();
|
Block previous = block();
|
||||||
if(previous == type) return;
|
if(previous == type) return;
|
||||||
super.setBlock(type);
|
super.setBlock(type);
|
||||||
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));
|
op(TileOp.get(x, y, (byte)OpType.block.ordinal(), previous.id, type.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,7 +40,7 @@ public class EditorTile extends Tile{
|
|||||||
byte previous = getTeamID();
|
byte previous = getTeamID();
|
||||||
if(previous == team.ordinal()) return;
|
if(previous == team.ordinal()) return;
|
||||||
super.setTeam(team);
|
super.setTeam(team);
|
||||||
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous, (byte)team.ordinal()));
|
op(TileOp.get(x, y, (byte)OpType.team.ordinal(), previous, (byte)team.ordinal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,7 +48,35 @@ public class EditorTile extends Tile{
|
|||||||
byte previous = getRotation();
|
byte previous = getRotation();
|
||||||
if(previous == rotation) return;
|
if(previous == rotation) return;
|
||||||
super.setRotation(rotation);
|
super.setRotation(rotation);
|
||||||
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous, rotation));
|
op(TileOp.get(x, y, (byte)OpType.rotation.ordinal(), previous, rotation));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOre(byte ore){
|
||||||
|
byte previous = getRotation();
|
||||||
|
if(previous == ore) return;
|
||||||
|
super.setOre(ore);
|
||||||
|
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), previous, ore));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preChanged(){
|
||||||
|
super.setTeam(Team.none);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void changed(){
|
||||||
|
entity = null;
|
||||||
|
|
||||||
|
Block block = block();
|
||||||
|
|
||||||
|
if(block.hasEntity()){
|
||||||
|
entity = block.newEntity();
|
||||||
|
entity.cons = new ConsumeModule(entity);
|
||||||
|
if(block.hasItems) entity.items = new ItemModule();
|
||||||
|
if(block.hasLiquids) entity.liquids = new LiquidModule();
|
||||||
|
if(block.hasPower) entity.power = new PowerModule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void op(long op){
|
private static void op(long op){
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.anuke.mindustry.editor;
|
|||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.ObjectMap;
|
||||||
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.Log;
|
||||||
import io.anuke.arc.util.Pack;
|
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;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.io;
|
package io.anuke.mindustry.io;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.IntIntMap;
|
||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.ObjectMap;
|
||||||
import io.anuke.arc.collection.ObjectMap.Entry;
|
import io.anuke.arc.collection.ObjectMap.Entry;
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
@@ -13,26 +14,40 @@ import io.anuke.mindustry.game.MappableContent;
|
|||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.game.Version;
|
import io.anuke.mindustry.game.Version;
|
||||||
import io.anuke.mindustry.maps.Map;
|
import io.anuke.mindustry.maps.Map;
|
||||||
|
import io.anuke.mindustry.type.ContentType;
|
||||||
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.mindustry.world.CachedTile;
|
||||||
import io.anuke.mindustry.world.LegacyColorMapper;
|
import io.anuke.mindustry.world.LegacyColorMapper;
|
||||||
import io.anuke.mindustry.world.LegacyColorMapper.LegacyBlock;
|
import io.anuke.mindustry.world.LegacyColorMapper.LegacyBlock;
|
||||||
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.BlockPart;
|
||||||
|
import io.anuke.mindustry.world.blocks.Floor;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.bufferSize;
|
||||||
import static io.anuke.mindustry.Vars.content;
|
import static io.anuke.mindustry.Vars.content;
|
||||||
import static io.anuke.mindustry.Vars.world;
|
|
||||||
|
|
||||||
/** Reads and writes map files.*/
|
/** Reads and writes map files.*/
|
||||||
public class MapIO{
|
public class MapIO{
|
||||||
private static final int version = 1;
|
public static final int version = 1;
|
||||||
|
|
||||||
private static final int[] pngHeader = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
private static final int[] pngHeader = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||||
|
private static ObjectMap<String, Block> missingBlocks;
|
||||||
|
|
||||||
|
private static void initBlocks(){
|
||||||
|
if(missingBlocks != null) return;
|
||||||
|
|
||||||
|
missingBlocks = ObjectMap.of(
|
||||||
|
"stained-stone", Blocks.moss
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isImage(FileHandle file){
|
public static boolean isImage(FileHandle file){
|
||||||
try(InputStream stream = file.read()){
|
try(InputStream stream = file.read(32)){
|
||||||
for(int i1 : pngHeader){
|
for(int i1 : pngHeader){
|
||||||
if(stream.read() != i1){
|
if(stream.read() != i1){
|
||||||
return false;
|
return false;
|
||||||
@@ -45,8 +60,20 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO implement
|
//TODO implement
|
||||||
public static Pixmap generatePreview(Map map){
|
public static Pixmap generatePreview(Map map) throws IOException{
|
||||||
return null;
|
Pixmap pixmap = new Pixmap(map.width, map.height, Format.RGBA8888);
|
||||||
|
CachedTile tile = new CachedTile(){
|
||||||
|
@Override
|
||||||
|
protected void changed(){
|
||||||
|
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(floor(), block(), getTeam()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
readTiles(map, (x, y) -> {
|
||||||
|
tile.x = (short)x;
|
||||||
|
tile.y = (short)y;
|
||||||
|
return tile;
|
||||||
|
});
|
||||||
|
return pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pixmap generatePreview(Tile[][] tiles){
|
public static Pixmap generatePreview(Tile[][] tiles){
|
||||||
@@ -60,6 +87,222 @@ public class MapIO{
|
|||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int colorFor(Block floor, Block wall, Team team){
|
||||||
|
if(wall.synthetic()){
|
||||||
|
return team.intColor;
|
||||||
|
}
|
||||||
|
return Color.rgba8888(wall.solid ? wall.color : floor.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeMap(FileHandle file, Map map, Tile[][] tiles) throws IOException{
|
||||||
|
OutputStream output = file.write(false, bufferSize);
|
||||||
|
|
||||||
|
{
|
||||||
|
DataOutputStream stream = new DataOutputStream(output);
|
||||||
|
stream.writeInt(version);
|
||||||
|
stream.writeInt(Version.build);
|
||||||
|
stream.writeShort(tiles.length);
|
||||||
|
stream.writeShort(tiles[0].length);
|
||||||
|
stream.writeByte((byte)map.tags.size);
|
||||||
|
|
||||||
|
for(Entry<String, String> entry : map.tags.entries()){
|
||||||
|
stream.writeUTF(entry.key);
|
||||||
|
stream.writeUTF(entry.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try(DataOutputStream stream = new DataOutputStream(new DeflaterOutputStream(output))){
|
||||||
|
int width = map.width, height = map.height;
|
||||||
|
|
||||||
|
SaveIO.getSaveWriter().writeContentHeader(stream);
|
||||||
|
|
||||||
|
//floor first
|
||||||
|
for(int i = 0; i < tiles.length * tiles[0].length; i++){
|
||||||
|
Tile tile = tiles[i % width][i / width];
|
||||||
|
stream.writeByte(tile.getFloorID());
|
||||||
|
stream.writeByte(tile.getOre());
|
||||||
|
int consecutives = 0;
|
||||||
|
|
||||||
|
for(int j = i + 1; j < width * height && consecutives < 255; j++){
|
||||||
|
Tile nextTile = tiles[j % width][j / width];
|
||||||
|
|
||||||
|
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getOre() != tile.getOre()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
consecutives++;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.writeByte(consecutives);
|
||||||
|
i += consecutives;
|
||||||
|
}
|
||||||
|
|
||||||
|
//then blocks
|
||||||
|
for(int i = 0; i < tiles.length * tiles[0].length; i++){
|
||||||
|
Tile tile = tiles[i % width][i / width];
|
||||||
|
stream.writeByte(tile.getBlockID());
|
||||||
|
|
||||||
|
if(tile.block() instanceof BlockPart){
|
||||||
|
stream.writeByte(tile.link);
|
||||||
|
}else if(tile.entity != null){
|
||||||
|
stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.getRotation())); //team + rotation
|
||||||
|
stream.writeShort((short)tile.entity.health); //health
|
||||||
|
tile.entity.writeConfig(stream);
|
||||||
|
}else{
|
||||||
|
//write consecutive non-entity blocks
|
||||||
|
int consecutives = 0;
|
||||||
|
|
||||||
|
for(int j = i + 1; j < width * height && consecutives < 255; j++){
|
||||||
|
Tile nextTile = tiles[j % width][j / width];
|
||||||
|
|
||||||
|
if(nextTile.block() != tile.block()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
consecutives++;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.writeByte(consecutives);
|
||||||
|
i += consecutives;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
||||||
|
try(DataInputStream stream = new DataInputStream(file.read(1024))){
|
||||||
|
ObjectMap<String, String> tags = new ObjectMap<>();
|
||||||
|
|
||||||
|
//meta is uncompressed
|
||||||
|
int version = stream.readInt();
|
||||||
|
if(version == 0){
|
||||||
|
return readLegacyMap(file, custom);
|
||||||
|
}
|
||||||
|
int build = stream.readInt();
|
||||||
|
short width = stream.readShort(), height = stream.readShort();
|
||||||
|
byte tagAmount = stream.readByte();
|
||||||
|
|
||||||
|
for(int i = 0; i < tagAmount; i++){
|
||||||
|
String name = stream.readUTF();
|
||||||
|
String value = stream.readUTF();
|
||||||
|
tags.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Map(file, width, height, tags, custom, version, build);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Reads tiles from a map, version-agnostic.*/
|
||||||
|
public static void readTiles(Map map, Tile[][] tiles) throws IOException{
|
||||||
|
readTiles(map, (x, y) -> tiles[x][y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Reads tiles from a map, version-agnostic.*/
|
||||||
|
public static void readTiles(Map map, TileProvider tiles) throws IOException{
|
||||||
|
if(map.version == 0){
|
||||||
|
readLegacyMmapTiles(map.file, tiles);
|
||||||
|
}else if(map.version == version){
|
||||||
|
readTiles(map.file, map.width, map.height, tiles);
|
||||||
|
}else{
|
||||||
|
throw new IOException("Unknown map version. What?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Reads tiles from a map in the new build-65 format.*/
|
||||||
|
private static void readTiles(FileHandle file, int width, int height, Tile[][] tiles) throws IOException{
|
||||||
|
readTiles(file, width, height, (x, y) -> tiles[x][y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Reads tiles from a map in the new build-65 format.*/
|
||||||
|
private static void readTiles(FileHandle file, int width, int height, TileProvider tiles) throws IOException{
|
||||||
|
try(BufferedInputStream input = file.read(bufferSize)){
|
||||||
|
|
||||||
|
//read map
|
||||||
|
{
|
||||||
|
DataInputStream stream = new DataInputStream(input);
|
||||||
|
|
||||||
|
stream.readInt(); //version
|
||||||
|
stream.readInt(); //build
|
||||||
|
stream.readInt(); //width + height
|
||||||
|
byte tagAmount = stream.readByte();
|
||||||
|
|
||||||
|
for(int i = 0; i < tagAmount; i++){
|
||||||
|
stream.readUTF();
|
||||||
|
stream.readUTF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try(DataInputStream stream = new DataInputStream(new InflaterInputStream(input))){
|
||||||
|
|
||||||
|
MappableContent[][] c = SaveIO.getSaveWriter().readContentHeader(stream);
|
||||||
|
|
||||||
|
try{
|
||||||
|
content.setTemporaryMapper(c);
|
||||||
|
|
||||||
|
//read floor and create tiles first
|
||||||
|
for(int i = 0; i < width * height; i++){
|
||||||
|
int x = i % width, y = i / width;
|
||||||
|
byte floorid = stream.readByte();
|
||||||
|
byte oreid = stream.readByte();
|
||||||
|
int consecutives = stream.readUnsignedByte();
|
||||||
|
|
||||||
|
Tile tile = tiles.get(x, y);
|
||||||
|
tile.setFloor((Floor)content.block(floorid));
|
||||||
|
tile.setOre(oreid);
|
||||||
|
|
||||||
|
for(int j = i + 1; j < i + 1 + consecutives; j++){
|
||||||
|
int newx = j % width, newy = j / width;
|
||||||
|
Tile newTile = tiles.get(newx, newy);
|
||||||
|
newTile.setFloor((Floor)content.block(floorid));
|
||||||
|
newTile.setOre(oreid);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += consecutives;
|
||||||
|
}
|
||||||
|
|
||||||
|
//read blocks
|
||||||
|
for(int i = 0; i < width * height; i++){
|
||||||
|
int x = i % width, y = i / width;
|
||||||
|
Block block = content.block(stream.readByte());
|
||||||
|
|
||||||
|
Tile tile = tiles.get(x, y);
|
||||||
|
tile.setBlock(block);
|
||||||
|
|
||||||
|
if(block == Blocks.part){
|
||||||
|
tile.link = stream.readByte();
|
||||||
|
}else if(tile.entity != null){
|
||||||
|
byte tr = stream.readByte();
|
||||||
|
short health = stream.readShort();
|
||||||
|
|
||||||
|
byte team = Pack.leftByte(tr);
|
||||||
|
byte rotation = Pack.rightByte(tr);
|
||||||
|
|
||||||
|
tile.setTeam(Team.all[team]);
|
||||||
|
tile.entity.health = health;
|
||||||
|
tile.setRotation(rotation);
|
||||||
|
|
||||||
|
tile.entity.readConfig(stream);
|
||||||
|
}else{ //no entity/part, read consecutives
|
||||||
|
int consecutives = stream.readUnsignedByte();
|
||||||
|
|
||||||
|
for(int j = i + 1; j < i + 1 + consecutives; j++){
|
||||||
|
int newx = j % width, newy = j / width;
|
||||||
|
tiles.get(newx, newy).setBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += consecutives;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}finally{
|
||||||
|
content.setTemporaryMapper(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//region legacy IO
|
||||||
|
|
||||||
/**Reads a pixmap in the 3.5 pixmap format.*/
|
/**Reads a pixmap in the 3.5 pixmap format.*/
|
||||||
public static void readLegacyPixmap(Pixmap pixmap, Tile[][] tiles){
|
public static void readLegacyPixmap(Pixmap pixmap, Tile[][] tiles){
|
||||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||||
@@ -96,100 +339,88 @@ public class MapIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO implement
|
|
||||||
/**Reads a pixmap in the old 4.0 .mmap format.*/
|
/**Reads a pixmap in the old 4.0 .mmap format.*/
|
||||||
private static void readLegacyMmap(FileHandle file, Tile[][] tiles) throws IOException{
|
private static void readLegacyMmapTiles(FileHandle file, Tile[][] tiles) throws IOException{
|
||||||
|
readLegacyMmapTiles(file, (x, y) -> tiles[x][y]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int colorFor(Block floor, Block wall, Team team){
|
//TODO implement
|
||||||
if(wall.synthetic()){
|
/**Reads a mmap in the old 4.0 .mmap format.*/
|
||||||
return team.intColor;
|
private static void readLegacyMmapTiles(FileHandle file, TileProvider tiles) throws IOException{
|
||||||
}
|
try(DataInputStream stream = new DataInputStream(file.read(bufferSize))){
|
||||||
return Color.rgba8888(wall.solid ? wall.color : floor.color);
|
stream.readInt(); //version
|
||||||
}
|
byte tagAmount = stream.readByte();
|
||||||
|
|
||||||
public static void writeMap(FileHandle file, Map map, Tile[][] tiles) throws IOException{
|
for(int i = 0; i < tagAmount; i++){
|
||||||
OutputStream output = file.write(false);
|
stream.readUTF(); //key
|
||||||
|
stream.readUTF(); //val
|
||||||
try(DataOutputStream stream = new DataOutputStream(output)){
|
|
||||||
stream.writeInt(version);
|
|
||||||
stream.writeInt(Version.build);
|
|
||||||
stream.writeShort(tiles.length);
|
|
||||||
stream.writeShort(tiles[0].length);
|
|
||||||
stream.writeByte((byte)map.tags.size);
|
|
||||||
|
|
||||||
for(Entry<String, String> entry : map.tags.entries()){
|
|
||||||
stream.writeUTF(entry.key);
|
|
||||||
stream.writeUTF(entry.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try(DataOutputStream stream = new DataOutputStream(new DeflaterOutputStream(output))){
|
|
||||||
|
|
||||||
SaveIO.getSaveWriter().writeContentHeader(stream);
|
|
||||||
|
|
||||||
//floor first
|
|
||||||
for(int i = 0; i < tiles.length * tiles[0].length; i++){
|
|
||||||
Tile tile = world.tile(i % world.width(), i / world.width());
|
|
||||||
stream.writeByte(tile.getFloorID());
|
|
||||||
stream.writeByte(tile.getOre());
|
|
||||||
int consecutives = 0;
|
|
||||||
|
|
||||||
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
|
|
||||||
Tile nextTile = world.tile(j % world.width(), j / world.width());
|
|
||||||
|
|
||||||
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getOre() != tile.getOre()){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
consecutives++;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeByte(consecutives);
|
|
||||||
i += consecutives;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//then blocks
|
initBlocks();
|
||||||
for(int i = 0; i < tiles.length * tiles[0].length; i++){
|
|
||||||
Tile tile = world.tile(i % world.width(), i / world.width());
|
|
||||||
stream.writeByte(tile.getBlockID());
|
|
||||||
|
|
||||||
if(tile.block() instanceof BlockPart){
|
//block id -> real id map
|
||||||
stream.writeByte(tile.link);
|
IntIntMap map = new IntIntMap();
|
||||||
}else if(tile.entity != null){
|
IntIntMap oreMap = new IntIntMap();
|
||||||
stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.getRotation())); //team + rotation
|
|
||||||
stream.writeShort((short)tile.entity.health); //health
|
|
||||||
tile.entity.writeConfig(stream);
|
|
||||||
}else{
|
|
||||||
//write consecutive non-entity blocks
|
|
||||||
int consecutives = 0;
|
|
||||||
|
|
||||||
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
|
short blocks = stream.readShort();
|
||||||
Tile nextTile = world.tile(j % world.width(), j / world.width());
|
for(int i = 0; i < blocks; i++){
|
||||||
|
short id = stream.readShort();
|
||||||
if(nextTile.block() != tile.block()){
|
String name = stream.readUTF();
|
||||||
break;
|
Block block = content.getByName(ContentType.block, name);
|
||||||
|
if(block == null){
|
||||||
|
//substitute for replacement in missingBlocks if possible
|
||||||
|
if(missingBlocks.containsKey(name)){
|
||||||
|
block = missingBlocks.get(name);
|
||||||
|
}else if(name.startsWith("ore-")){ //an ore floor combination
|
||||||
|
String[] split = name.split("-");
|
||||||
|
String itemName = split[1], floorName = split[2];
|
||||||
|
Item item = content.getByName(ContentType.item, itemName);
|
||||||
|
Block floor = content.getByName(ContentType.block, floorName);
|
||||||
|
if(item != null && floor != null){
|
||||||
|
oreMap.put(id, item.id);
|
||||||
|
block = floor;
|
||||||
|
}else{
|
||||||
|
block = Blocks.air;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
consecutives++;
|
block = Blocks.air;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.writeByte(consecutives);
|
}
|
||||||
i += consecutives;
|
map.put(id, block.id);
|
||||||
|
}
|
||||||
|
short width = stream.readShort(), height = stream.readShort();
|
||||||
|
|
||||||
|
for(int y = 0; y < height; y++){
|
||||||
|
for(int x = 0; x < width; x++){
|
||||||
|
Tile tile = tiles.get(x, y);
|
||||||
|
byte floorb = stream.readByte();
|
||||||
|
byte blockb = stream.readByte();
|
||||||
|
byte rotTeamb = stream.readByte();
|
||||||
|
byte linkb = stream.readByte();
|
||||||
|
stream.readByte(); //unused stuff
|
||||||
|
|
||||||
|
tile.setFloor((Floor)content.block(map.get(floorb, 0)));
|
||||||
|
tile.setBlock(content.block(map.get(blockb, 0)));
|
||||||
|
tile.setRotation(Pack.leftByte(rotTeamb));
|
||||||
|
if(tile.block() == Blocks.part){
|
||||||
|
tile.setLinkByte(linkb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(oreMap.containsKey(floorb)){
|
||||||
|
tile.setOre((byte)oreMap.get(floorb, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map readMap(FileHandle file, boolean custom) throws IOException{
|
private static Map readLegacyMap(FileHandle file, boolean custom) throws IOException{
|
||||||
try(DataInputStream stream = new DataInputStream(file.read())){
|
try(DataInputStream stream = new DataInputStream(file.read(bufferSize))){
|
||||||
ObjectMap<String, String> tags = new ObjectMap<>();
|
ObjectMap<String, String> tags = new ObjectMap<>();
|
||||||
|
|
||||||
//meta is uncompressed
|
|
||||||
int version = stream.readInt();
|
int version = stream.readInt();
|
||||||
int build = stream.readInt();
|
if(version != 0) throw new IOException("Attempted to read non-legacy map in legacy method!");
|
||||||
short width = stream.readShort(), height = stream.readShort();
|
|
||||||
byte tagAmount = stream.readByte();
|
byte tagAmount = stream.readByte();
|
||||||
|
|
||||||
for(int i = 0; i < tagAmount; i++){
|
for(int i = 0; i < tagAmount; i++){
|
||||||
@@ -198,83 +429,21 @@ public class MapIO{
|
|||||||
tags.put(name, value);
|
tags.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Map(file, width, height, tags, custom);
|
short blocks = stream.readShort();
|
||||||
}
|
for(int i = 0; i < blocks; i++){
|
||||||
}
|
stream.readShort();
|
||||||
|
stream.readUTF();
|
||||||
public static Tile[][] readTiles(Map map, Tile[][] tiles) throws IOException{
|
|
||||||
return readTiles(map.file, map.width, map.height, tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Tile[][] readTiles(FileHandle file, int width, int height, Tile[][] tiles) throws IOException{
|
|
||||||
readMap(file, false);
|
|
||||||
|
|
||||||
try(DataInputStream stream = new DataInputStream(new InflaterInputStream(file.read()))){
|
|
||||||
|
|
||||||
MappableContent[][] c = SaveIO.getSaveWriter().readContentHeader(stream);
|
|
||||||
|
|
||||||
try{
|
|
||||||
content.setTemporaryMapper(c);
|
|
||||||
|
|
||||||
//read floor and create tiles first
|
|
||||||
for(int i = 0; i < width * height; i++){
|
|
||||||
int x = i % width, y = i / width;
|
|
||||||
byte floorid = stream.readByte();
|
|
||||||
byte oreid = stream.readByte();
|
|
||||||
int consecutives = stream.readUnsignedByte();
|
|
||||||
|
|
||||||
tiles[x][y] = new Tile(x, y, floorid, (byte)0);
|
|
||||||
tiles[x][y].setOre(oreid);
|
|
||||||
|
|
||||||
for(int j = i + 1; j < i + 1 + consecutives; j++){
|
|
||||||
int newx = j % width, newy = j / width;
|
|
||||||
Tile newTile = new Tile(newx, newy, floorid, (byte)0);
|
|
||||||
newTile.setOre(oreid);
|
|
||||||
tiles[newx][newy] = newTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += consecutives;
|
|
||||||
}
|
|
||||||
|
|
||||||
//read blocks
|
|
||||||
for(int i = 0; i < width * height; i++){
|
|
||||||
int x = i % width, y = i / width;
|
|
||||||
Block block = content.block(stream.readByte());
|
|
||||||
|
|
||||||
Tile tile = tiles[x][y];
|
|
||||||
tile.setBlock(block);
|
|
||||||
|
|
||||||
if(block == Blocks.part){
|
|
||||||
tile.link = stream.readByte();
|
|
||||||
}else if(tile.entity != null){
|
|
||||||
byte tr = stream.readByte();
|
|
||||||
short health = stream.readShort();
|
|
||||||
|
|
||||||
byte team = Pack.leftByte(tr);
|
|
||||||
byte rotation = Pack.rightByte(tr);
|
|
||||||
|
|
||||||
tile.setTeam(Team.all[team]);
|
|
||||||
tile.entity.health = health;
|
|
||||||
tile.setRotation(rotation);
|
|
||||||
|
|
||||||
tile.entity.readConfig(stream);
|
|
||||||
}else{ //no entity/part, read consecutives
|
|
||||||
int consecutives = stream.readUnsignedByte();
|
|
||||||
|
|
||||||
for(int j = i + 1; j < i + 1 + consecutives; j++){
|
|
||||||
int newx = j % width, newy = j / width;
|
|
||||||
tiles[newx][newy].setBlock(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
i += consecutives;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tiles;
|
|
||||||
|
|
||||||
}finally{
|
|
||||||
content.setTemporaryMapper(null);
|
|
||||||
}
|
}
|
||||||
|
short width = stream.readShort(), height = stream.readShort();
|
||||||
|
|
||||||
|
//note that build 64 is the default build of all maps <65; while this can be inaccurate it's better than nothing
|
||||||
|
return new Map(file, width, height, tags, custom, 0, 64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
interface TileProvider{
|
||||||
|
Tile get(int x, int y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static DataInputStream getSlotStream(int slot){
|
public static DataInputStream getSlotStream(int slot){
|
||||||
return new DataInputStream(new InflaterInputStream(fileFor(slot).read()));
|
return new DataInputStream(new InflaterInputStream(fileFor(slot).read(bufferSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSaveValid(int slot){
|
public static boolean isSaveValid(int slot){
|
||||||
@@ -60,7 +60,7 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSaveValid(FileHandle file){
|
public static boolean isSaveValid(FileHandle file){
|
||||||
return isSaveValid(new DataInputStream(new InflaterInputStream(file.read())));
|
return isSaveValid(new DataInputStream(new InflaterInputStream(file.read(bufferSize))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSaveValid(DataInputStream stream){
|
public static boolean isSaveValid(DataInputStream stream){
|
||||||
@@ -95,7 +95,7 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void write(FileHandle file){
|
public static void write(FileHandle file){
|
||||||
write(new DeflaterOutputStream(file.write(false)){
|
write(new DeflaterOutputStream(file.write(false, bufferSize)){
|
||||||
byte[] tmp = {0};
|
byte[] tmp = {0};
|
||||||
|
|
||||||
public void write(int var1) throws IOException {
|
public void write(int var1) throws IOException {
|
||||||
@@ -120,12 +120,12 @@ public class SaveIO{
|
|||||||
public static void load(FileHandle file) throws SaveException{
|
public static void load(FileHandle file) throws SaveException{
|
||||||
try{
|
try{
|
||||||
//try and load; if any exception at all occurs
|
//try and load; if any exception at all occurs
|
||||||
load(new InflaterInputStream(file.read()));
|
load(new InflaterInputStream(file.read(bufferSize)));
|
||||||
}catch(SaveException e){
|
}catch(SaveException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
FileHandle backup = file.sibling(file.name() + "-backup." + file.extension());
|
FileHandle backup = file.sibling(file.name() + "-backup." + file.extension());
|
||||||
if(backup.exists()){
|
if(backup.exists()){
|
||||||
load(new InflaterInputStream(backup.read()));
|
load(new InflaterInputStream(backup.read(bufferSize)));
|
||||||
}else{
|
}else{
|
||||||
throw new SaveException(e.getCause());
|
throw new SaveException(e.getCause());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import io.anuke.arc.Core;
|
|||||||
import io.anuke.arc.collection.ObjectMap;
|
import io.anuke.arc.collection.ObjectMap;
|
||||||
import io.anuke.arc.files.FileHandle;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.arc.graphics.Texture;
|
import io.anuke.arc.graphics.Texture;
|
||||||
|
import io.anuke.mindustry.io.MapIO;
|
||||||
|
|
||||||
public class Map{
|
public class Map{
|
||||||
/** Whether this is a custom map.*/
|
/** Whether this is a custom map.*/
|
||||||
@@ -12,17 +13,31 @@ public class Map{
|
|||||||
public final ObjectMap<String, String> tags;
|
public final ObjectMap<String, String> tags;
|
||||||
/** Base file of this map.*/
|
/** Base file of this map.*/
|
||||||
public final FileHandle file;
|
public final FileHandle file;
|
||||||
/**Map width/height, shorts.*/
|
/** Format version.*/
|
||||||
|
public final int version;
|
||||||
|
/** Map width/height, shorts.*/
|
||||||
public int width, height;
|
public int width, height;
|
||||||
/** Preview texture.*/
|
/** Preview texture.*/
|
||||||
public Texture texture;
|
public Texture texture;
|
||||||
|
/** Build that this map was created in. -1 = unknown or custom build.*/
|
||||||
|
public int build;
|
||||||
|
|
||||||
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom){
|
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom, int version, int build){
|
||||||
this.custom = custom;
|
this.custom = custom;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
this.version = version;
|
||||||
|
this.build = build;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom, int version){
|
||||||
|
this(file, width, height, tags, custom, version, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map(FileHandle file, int width, int height, ObjectMap<String, String> tags, boolean custom){
|
||||||
|
this(file, width, height, tags, custom, MapIO.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fileName(){
|
public String fileName(){
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public class Maps implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Import a map, then save it. This updates all values and stored data necessary. */
|
/** Import a map, then save it. This updates all values and stored data necessary. */
|
||||||
public void importMap(FileHandle file, Map map){
|
public void importMap(FileHandle file, Map map) throws IOException{
|
||||||
file.copyTo(customMapDirectory.child(file.name()));
|
file.copyTo(customMapDirectory.child(file.name()));
|
||||||
if(!headless){
|
if(!headless){
|
||||||
map.texture = new Texture(MapIO.generatePreview(map));
|
map.texture = new Texture(MapIO.generatePreview(map));
|
||||||
|
|||||||
@@ -39,8 +39,13 @@ public class MapsDialog extends FloatingDialog{
|
|||||||
ui.showError(Core.bundle.format("editor.import.exists", name));
|
ui.showError(Core.bundle.format("editor.import.exists", name));
|
||||||
}else if(conflict != null){
|
}else if(conflict != null){
|
||||||
ui.showConfirm("$confirm", "$editor.overwrite.confirm", () -> {
|
ui.showConfirm("$confirm", "$editor.overwrite.confirm", () -> {
|
||||||
world.maps.importMap(file, map);
|
try{
|
||||||
setup();
|
world.maps.importMap(file, map);
|
||||||
|
setup();
|
||||||
|
}catch(Exception e){
|
||||||
|
ui.showError(Core.bundle.format("editor.errorimageload", Strings.parseException(e, false)));
|
||||||
|
Log.err(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
world.maps.importMap(file, map);
|
world.maps.importMap(file, map);
|
||||||
|
|||||||
46
core/src/io/anuke/mindustry/world/CachedTile.java
Normal file
46
core/src/io/anuke/mindustry/world/CachedTile.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package io.anuke.mindustry.world;
|
||||||
|
|
||||||
|
import io.anuke.arc.collection.IntMap;
|
||||||
|
import io.anuke.mindustry.entities.type.TileEntity;
|
||||||
|
import io.anuke.mindustry.game.Team;
|
||||||
|
import io.anuke.mindustry.world.modules.ConsumeModule;
|
||||||
|
import io.anuke.mindustry.world.modules.ItemModule;
|
||||||
|
import io.anuke.mindustry.world.modules.LiquidModule;
|
||||||
|
import io.anuke.mindustry.world.modules.PowerModule;
|
||||||
|
|
||||||
|
/**A tile which does not trigger change events and whose entity types are cached.
|
||||||
|
* Prevents garbage when loading previews.*/
|
||||||
|
public class CachedTile extends Tile{
|
||||||
|
private static IntMap<TileEntity> entities = new IntMap<>();
|
||||||
|
|
||||||
|
public CachedTile(){
|
||||||
|
super(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preChanged(){
|
||||||
|
super.setTeam(Team.none);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void changed(){
|
||||||
|
entity = null;
|
||||||
|
|
||||||
|
Block block = block();
|
||||||
|
|
||||||
|
if(block.hasEntity()){
|
||||||
|
//cache all entity types so only one is ever created per block type. do not add it.
|
||||||
|
if(!entities.containsKey(block.id)){
|
||||||
|
TileEntity n = block.newEntity();
|
||||||
|
n.cons = new ConsumeModule(entity);
|
||||||
|
if(block.hasItems) n.items = new ItemModule();
|
||||||
|
if(block.hasLiquids) n.liquids = new LiquidModule();
|
||||||
|
if(block.hasPower) n.power = new PowerModule();
|
||||||
|
entities.put(block.id, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = entities.get(block.id);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -361,7 +361,7 @@ public class Tile implements Position, TargetTrait{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preChanged(){
|
protected void preChanged(){
|
||||||
block().removed(this);
|
block().removed(this);
|
||||||
if(entity != null){
|
if(entity != null){
|
||||||
entity.removeFromProximity();
|
entity.removeFromProximity();
|
||||||
@@ -369,7 +369,7 @@ public class Tile implements Position, TargetTrait{
|
|||||||
team = 0;
|
team = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changed(){
|
protected void changed(){
|
||||||
if(entity != null){
|
if(entity != null){
|
||||||
entity.remove();
|
entity.remove();
|
||||||
entity = null;
|
entity = null;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class IOSLauncher extends IOSApplication.Delegate {
|
|||||||
ui.editor.show();
|
ui.editor.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.editor.beginEditMap(file.read());
|
ui.editor.beginEditMap(file);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -144,11 +144,11 @@ public class ServerControl implements ApplicationListener{
|
|||||||
|
|
||||||
Call.onInfoMessage((state.rules.pvp
|
Call.onInfoMessage((state.rules.pvp
|
||||||
? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]")
|
? "[YELLOW]The " + event.winner.name() + " team is victorious![]" : "[SCARLET]Game over![]")
|
||||||
+ "\nNext selected map:[accent] "+map.name+"[]"
|
+ "\nNext selected map:[accent] "+map.name()+"[]"
|
||||||
+ (map.meta.author() != null ? " by[accent] " + map.meta.author() + "[]" : "") + "."+
|
+ (map.author() != null ? " by[accent] " + map.author() + "[]" : "") + "."+
|
||||||
"\nNew game begins in " + roundExtraTime + " seconds.");
|
"\nNew game begins in " + roundExtraTime + " seconds.");
|
||||||
|
|
||||||
info("Selected next map to be {0}.", map.name);
|
info("Selected next map to be {0}.", map.name());
|
||||||
|
|
||||||
Map fmap = map;
|
Map fmap = map;
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ public class ServerControl implements ApplicationListener{
|
|||||||
|
|
||||||
if(lastTask != null) lastTask.cancel();
|
if(lastTask != null) lastTask.cancel();
|
||||||
|
|
||||||
Map result = world.maps.all().find(map -> map.name.equalsIgnoreCase(arg[0]));
|
Map result = world.maps.all().find(map -> map.name().equalsIgnoreCase(arg[0]));
|
||||||
|
|
||||||
if(result == null){
|
if(result == null){
|
||||||
err("No map with name &y'{0}'&lr found.", arg[0]);
|
err("No map with name &y'{0}'&lr found.", arg[0]);
|
||||||
@@ -252,7 +252,7 @@ public class ServerControl implements ApplicationListener{
|
|||||||
if(!world.maps.all().isEmpty()){
|
if(!world.maps.all().isEmpty()){
|
||||||
info("Maps:");
|
info("Maps:");
|
||||||
for(Map map : world.maps.all()){
|
for(Map map : world.maps.all()){
|
||||||
info(" &ly{0}: &lb&fi{1} / {2}x{3}", map.name, map.custom ? "Custom" : "Default", map.meta.width, map.meta.height);
|
info(" &ly{0}: &lb&fi{1} / {2}x{3}", map.name(), map.custom ? "Custom" : "Default", map.width, map.height);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
info("No maps found.");
|
info("No maps found.");
|
||||||
@@ -265,7 +265,7 @@ public class ServerControl implements ApplicationListener{
|
|||||||
info("Status: &rserver closed");
|
info("Status: &rserver closed");
|
||||||
}else{
|
}else{
|
||||||
info("Status:");
|
info("Status:");
|
||||||
info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name), state.wave);
|
info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name()), state.wave);
|
||||||
|
|
||||||
if(state.rules.waves){
|
if(state.rules.waves){
|
||||||
info("&ly {0} enemies.", unitGroups[Team.red.ordinal()].size());
|
info("&ly {0} enemies.", unitGroups[Team.red.ordinal()].size());
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ def antialias = {File file ->
|
|||||||
|
|
||||||
ImageIO.write(out, "png", file)
|
ImageIO.write(out, "png", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
task swapColors(){
|
task swapColors(){
|
||||||
doLast{
|
doLast{
|
||||||
if (project.hasProperty("colors")) {
|
if (project.hasProperty("colors")) {
|
||||||
|
|||||||
Reference in New Issue
Block a user