Save file refactor / Changed sector size

This commit is contained in:
Anuken
2018-10-19 22:46:53 -04:00
parent bed22f51b4
commit 59bc73656f
9 changed files with 207 additions and 199 deletions

View File

@@ -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;

View File

@@ -347,7 +347,6 @@ public class Control extends Module{
@Override
public void update(){
if(error != null){
throw new RuntimeException(error);
}

View File

@@ -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"));
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);