diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index cd8891e462..a51431a503 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -49,7 +49,7 @@ public class Vars{ public static final int maxNameLength = 40; public static final float itemSize = 5f; public static final int tilesize = 8; - public static final int sectorSize = 120; + public static final int sectorSize = 250; public static final int mapPadding = 3; public static final int invalidSector = Integer.MAX_VALUE; public static Locale[] locales; diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 1222bde0da..35b926899f 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -347,7 +347,6 @@ public class Control extends Module{ @Override public void update(){ - if(error != null){ throw new RuntimeException(error); } diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 5c5f543044..ffd06c5ef3 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -111,8 +111,8 @@ public class UI extends SceneModule{ Structs.each(font -> { font.setUseIntegerPositions(false); font.getData().setScale(Vars.fontScale); - font.getData().down += Unit.dp.scl(4f); - font.getData().lineHeight -= Unit.dp.scl(4f); + font.getData().down += Unit.dp.scl(3f); + font.getData().lineHeight -= Unit.dp.scl(3f); }, skin.font(), skin.getFont("default-font-chat"), skin.getFont("trad-chinese"), skin.getFont("simp-chinese")); } diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index b338fdaf4d..5f3d005030 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -1,16 +1,28 @@ package io.anuke.mindustry.io; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.content.blocks.StorageBlocks; +import io.anuke.mindustry.entities.traits.SaveTrait; +import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.MappableContent; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.BlockPart; +import io.anuke.ucore.entities.Entities; +import io.anuke.ucore.entities.EntityGroup; +import io.anuke.ucore.entities.trait.Entity; +import io.anuke.ucore.util.Bits; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.*; public abstract class SaveFileVersion{ public final int version; @@ -31,6 +43,187 @@ public abstract class SaveFileVersion{ return new SaveMeta(version, time, playtime, build, sector, mode, map, wave, Difficulty.values()[difficulty]); } + public void writeMap(DataOutputStream stream) throws IOException{ + + //write world size + stream.writeShort(world.width()); + stream.writeShort(world.height()); + + for(int i = 0; i < world.width() * world.height(); i++){ + Tile tile = world.tile(i); + + stream.writeByte(tile.getFloorID()); + stream.writeByte(tile.getBlockID()); + stream.writeByte(tile.getElevation()); + + if(tile.block() instanceof BlockPart){ + stream.writeByte(tile.link); + }else if(tile.entity != null){ + stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation + stream.writeShort((short) tile.entity.health); //health + + if(tile.entity.items != null) tile.entity.items.write(stream); + if(tile.entity.power != null) tile.entity.power.write(stream); + if(tile.entity.liquids != null) tile.entity.liquids.write(stream); + if(tile.entity.cons != null) tile.entity.cons.write(stream); + + tile.entity.write(stream); + }else if(tile.block() == Blocks.air){ + int consecutives = 0; + + for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ + Tile nextTile = world.tile(j); + + if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){ + break; + } + + consecutives++; + } + + stream.writeByte(consecutives); + i += consecutives; + } + } + + //write visibility, length-run encoded + for(int i = 0; i < world.width() * world.height(); i++){ + Tile tile = world.tile(i); + boolean discovered = tile.discovered(); + + int consecutives = 0; + + for(int j = i + 1; j < world.width() * world.height() && consecutives < 32767*2-1; j++){ + Tile nextTile = world.tile(j); + + if(nextTile.discovered() != discovered){ + break; + } + + consecutives++; + } + + stream.writeBoolean(discovered); + stream.writeShort(consecutives); + i += consecutives; + } + } + + public void readMap(DataInputStream stream) throws IOException{ + short width = stream.readShort(); + short height = stream.readShort(); + + if(world.getSector() != null){ + world.setMap(new Map("Sector " + world.getSector().x + ", " + world.getSector().y, width, height)); + }else if(world.getMap() == null){ + world.setMap(new Map("unknown", width, height)); + } + + world.beginMapLoad(); + + Tile[][] tiles = world.createTiles(width, height); + + for(int i = 0; i < width * height; i++){ + int x = i % width, y = i / width; + byte floorid = stream.readByte(); + byte wallid = stream.readByte(); + byte elevation = stream.readByte(); + + Tile tile = new Tile(x, y, floorid, wallid); + tile.setElevation(elevation); + + if(wallid == Blocks.blockpart.id){ + tile.link = stream.readByte(); + }else if(tile.entity != null){ + byte tr = stream.readByte(); + short health = stream.readShort(); + + byte team = Bits.getLeftByte(tr); + byte rotation = Bits.getRightByte(tr); + + Team t = Team.all[team]; + + tile.setTeam(Team.all[team]); + tile.entity.health = health; + tile.setRotation(rotation); + + if(tile.entity.items != null) tile.entity.items.read(stream); + if(tile.entity.power != null) tile.entity.power.read(stream); + if(tile.entity.liquids != null) tile.entity.liquids.read(stream); + if(tile.entity.cons != null) tile.entity.cons.read(stream); + + tile.entity.read(stream); + + if(tile.block() == StorageBlocks.core){ + state.teams.get(t).cores.add(tile); + } + }else if(wallid == 0){ + int consecutives = stream.readUnsignedByte(); + + for(int j = i + 1; j < i + 1 + consecutives; j++){ + int newx = j % width, newy = j / width; + Tile newTile = new Tile(newx, newy, floorid, wallid); + newTile.setElevation(elevation); + tiles[newx][newy] = newTile; + } + + i += consecutives; + } + + tiles[x][y] = tile; + } + + for(int i = 0; i < width * height; i++){ + boolean discovered = stream.readBoolean(); + int consecutives = stream.readUnsignedShort(); + if(discovered){ + for(int j = i + 1; j < i + 1 + consecutives; j++){ + int newx = j % width, newy = j / width; + tiles[newx][newy].setVisibility((byte) 1); + } + } + i += consecutives; + } + + content.setTemporaryMapper(null); + world.endMapLoad(); + } + + public void writeEntities(DataOutputStream stream) throws IOException{ + int groups = 0; + + for(EntityGroup group : Entities.getAllGroups()){ + if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ + groups++; + } + } + + stream.writeByte(groups); + + for(EntityGroup group : Entities.getAllGroups()){ + if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ + stream.writeInt(group.size()); + for(Entity entity : group.all()){ + stream.writeByte(((SaveTrait) entity).getTypeID()); + ((SaveTrait) entity).writeSave(stream); + } + } + } + } + + public void readEntities(DataInputStream stream) throws IOException{ + byte groups = stream.readByte(); + + for(int i = 0; i < groups; i++){ + int amount = stream.readInt(); + for(int j = 0; j < amount; j++){ + byte typeid = stream.readByte(); + SaveTrait trait = (SaveTrait) TypeTrait.getTypeByID(typeid).get(); + trait.readSave(stream); + } + } + } + public MappableContent[][] readContentHeader(DataInputStream stream) throws IOException{ byte mapped = stream.readByte(); diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index ccef23d108..51120ce987 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -28,6 +28,10 @@ public class SaveIO{ } } + public static SaveFileVersion getSaveWriter(){ + return versionArray.peek(); + } + public static void saveToSlot(int slot){ if(gwt){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 52e859635c..3431873465 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -1,23 +1,11 @@ package io.anuke.mindustry.io.versions; import com.badlogic.gdx.utils.TimeUtils; -import io.anuke.mindustry.content.blocks.Blocks; -import io.anuke.mindustry.content.blocks.StorageBlocks; -import io.anuke.mindustry.entities.traits.SaveTrait; -import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.io.SaveFileVersion; import io.anuke.mindustry.maps.Map; -import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.BlockPart; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.entities.Entities; -import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.entities.trait.Entity; -import io.anuke.ucore.util.Bits; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -39,7 +27,6 @@ public class Save16 extends SaveFileVersion{ int sector = stream.readInt(); //sector ID //general state - byte mode = stream.readByte(); String mapname = stream.readUTF(); Map map = world.maps.getByName(mapname); @@ -60,98 +47,9 @@ public class Save16 extends SaveFileVersion{ state.spawner.read(stream); - //entities + readEntities(stream); - byte groups = stream.readByte(); - - for(int i = 0; i < groups; i++){ - int amount = stream.readInt(); - for(int j = 0; j < amount; j++){ - byte typeid = stream.readByte(); - SaveTrait trait = (SaveTrait) TypeTrait.getTypeByID(typeid).get(); - trait.readSave(stream); - } - } - - //map - - short width = stream.readShort(); - short height = stream.readShort(); - - if(world.getSector() != null){ - world.setMap(new Map("Sector " + world.getSector().x + ", " + world.getSector().y, width, height)); - }else if(map == null){ - world.setMap(new Map("unknown", width, height)); - } - - world.beginMapLoad(); - - Tile[][] tiles = world.createTiles(width, height); - - for(int i = 0; i < width * height; i++){ - int x = i % width, y = i / width; - byte floorid = stream.readByte(); - byte wallid = stream.readByte(); - byte elevation = stream.readByte(); - - Tile tile = new Tile(x, y, floorid, wallid); - tile.setElevation(elevation); - - if(wallid == Blocks.blockpart.id){ - tile.link = stream.readByte(); - }else if(tile.entity != null){ - byte tr = stream.readByte(); - short health = stream.readShort(); - - byte team = Bits.getLeftByte(tr); - byte rotation = Bits.getRightByte(tr); - - Team t = Team.all[team]; - - tile.setTeam(Team.all[team]); - tile.entity.health = health; - tile.setRotation(rotation); - - if(tile.entity.items != null) tile.entity.items.read(stream); - if(tile.entity.power != null) tile.entity.power.read(stream); - if(tile.entity.liquids != null) tile.entity.liquids.read(stream); - if(tile.entity.cons != null) tile.entity.cons.read(stream); - - tile.entity.read(stream); - - if(tile.block() == StorageBlocks.core){ - state.teams.get(t).cores.add(tile); - } - }else if(wallid == 0){ - int consecutives = stream.readUnsignedByte(); - - for(int j = i + 1; j < i + 1 + consecutives; j++){ - int newx = j % width, newy = j / width; - Tile newTile = new Tile(newx, newy, floorid, wallid); - newTile.setElevation(elevation); - tiles[newx][newy] = newTile; - } - - i += consecutives; - } - - tiles[x][y] = tile; - } - - for(int i = 0; i < width * height; i++){ - boolean discovered = stream.readBoolean(); - int consecutives = stream.readUnsignedShort(); - if(discovered){ - for(int j = i + 1; j < i + 1 + consecutives; j++){ - int newx = j % width, newy = j / width; - tiles[newx][newy].setVisibility((byte) 1); - } - } - i += consecutives; - } - - content.setTemporaryMapper(null); - world.endMapLoad(); + readMap(stream); } @Override @@ -177,91 +75,8 @@ public class Save16 extends SaveFileVersion{ //--ENTITIES-- - int groups = 0; + writeEntities(stream); - for(EntityGroup group : Entities.getAllGroups()){ - if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ - groups++; - } - } - - stream.writeByte(groups); - - for(EntityGroup group : Entities.getAllGroups()){ - if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ - stream.writeInt(group.size()); - for(Entity entity : group.all()){ - stream.writeByte(((SaveTrait) entity).getTypeID()); - ((SaveTrait) entity).writeSave(stream); - } - } - } - - //--MAP DATA-- - - Timers.mark(); - - //write world size - stream.writeShort(world.width()); - stream.writeShort(world.height()); - - for(int i = 0; i < world.width() * world.height(); i++){ - Tile tile = world.tile(i); - - stream.writeByte(tile.getFloorID()); - stream.writeByte(tile.getBlockID()); - stream.writeByte(tile.getElevation()); - - if(tile.block() instanceof BlockPart){ - stream.writeByte(tile.link); - }else if(tile.entity != null){ - stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation - stream.writeShort((short) tile.entity.health); //health - - if(tile.entity.items != null) tile.entity.items.write(stream); - if(tile.entity.power != null) tile.entity.power.write(stream); - if(tile.entity.liquids != null) tile.entity.liquids.write(stream); - if(tile.entity.cons != null) tile.entity.cons.write(stream); - - tile.entity.write(stream); - }else if(tile.block() == Blocks.air){ - int consecutives = 0; - - for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){ - Tile nextTile = world.tile(j); - - if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getElevation() != tile.getElevation()){ - break; - } - - consecutives++; - } - - stream.writeByte(consecutives); - i += consecutives; - } - } - - //write visibility, length-run encoded - for(int i = 0; i < world.width() * world.height(); i++){ - Tile tile = world.tile(i); - boolean discovered = tile.discovered(); - - int consecutives = 0; - - for(int j = i + 1; j < world.width() * world.height() && consecutives < 32767*2-1; j++){ - Tile nextTile = world.tile(j); - - if(nextTile.discovered() != discovered){ - break; - } - - consecutives++; - } - - stream.writeBoolean(discovered); - stream.writeShort(consecutives); - i += consecutives; - } + writeMap(stream); } } diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index b0dbd8beeb..f256557b6c 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -153,8 +153,6 @@ public class NetworkIO{ Player player = players[0]; - //TODO !! use map name as the network map in Maps, so getMap() isn't null. - try(DataInputStream stream = new DataInputStream(is)){ float timerTime = stream.readFloat(); long timestamp = stream.readLong(); @@ -194,7 +192,6 @@ public class NetworkIO{ int width = stream.readShort(); int height = stream.readShort(); - //TODO send advanced map meta such as author, etc Map currentMap = new Map(map, new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null); currentMap.meta.tags.clear(); currentMap.meta.tags.putAll(tags); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java index 07c97c9301..0009263d47 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SectorsDialog.java @@ -71,7 +71,7 @@ public class SectorsDialog extends FloatingDialog{ class SectorView extends Element{ float lastX, lastY; - float sectorSize = Unit.dp.scl(32*4); + float sectorSize = Unit.dp.scl(32*5); float sectorPadding = Unit.dp.scl(14f); boolean clicked = false; float panX = -sectorPadding/2f, panY = -sectorSize/2f; diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java index 8c76090929..e8a5205267 100644 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ b/core/src/io/anuke/mindustry/world/ColorMapper.java @@ -35,7 +35,7 @@ public class ColorMapper implements ContentList{ float maxMult = 1f/Math.max(Math.max(tmpColor.r, tmpColor.g), tmpColor.b) ; float mul = Math.min(0.7f + elevation / 5f, maxMult); if((cliffs & ((1 << 6))) != 0){ - mul -= 0.5f; + mul -= 0.35f; } tmpColor.mul(mul, mul, mul, 1f); color = Color.rgba8888(tmpColor);