New map format, completely broke loading or playing

This commit is contained in:
Anuken
2018-03-17 21:21:24 -04:00
parent 713875100b
commit 172ac78466
55 changed files with 483 additions and 2664 deletions
+51 -208
View File
@@ -1,20 +1,19 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.utils.ByteArray;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.mindustry.world.blocks.types.BlockPart;
import io.anuke.mindustry.world.blocks.types.Rock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.util.Bits;
import java.io.*;
import java.nio.ByteBuffer;
@@ -23,86 +22,6 @@ import static io.anuke.mindustry.Vars.*;
public class NetworkIO {
public static void writeMap(Map map, OutputStream os){
try(DataOutputStream stream = new DataOutputStream(os)){
stream.writeUTF(map.name);
stream.writeBoolean(map.oreGen);
stream.writeShort(map.getWidth());
stream.writeShort(map.getHeight());
int width = map.getWidth();
int cap = map.getWidth() * map.getHeight();
int pos = 0;
while(pos < cap){
int color = map.pixmap.getPixel(pos % width, pos / width);
byte id = ColorMapper.getColorID(color);
int length = 1;
while(true){
if(pos >= cap || length > 254){
break;
}
pos ++;
int next = map.pixmap.getPixel(pos % width, pos / width);
if(next != color){
pos --;
break;
}else{
length ++;
}
}
if(id == -1) id = 2;
stream.writeByte((byte)(length > 127 ? length - 256 : length));
stream.writeByte(id);
pos ++;
}
}catch (IOException e){
throw new RuntimeException(e);
}
}
public static Map loadMap(InputStream is){
try(DataInputStream stream = new DataInputStream(is)){
String name = stream.readUTF();
boolean ores = stream.readBoolean();
short width = stream.readShort();
short height = stream.readShort();
Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888);
int pos = 0;
while(stream.available() > 0){
int length = stream.readByte();
byte id = stream.readByte();
if(length < 0) length += 256;
int color = ColorMapper.getColorByID(id);
for(int p = 0; p < length; p ++){
pixmap.drawPixel(pos % width, pos / width,color);
pos ++;
}
}
Map map = new Map();
map.name = name;
map.oreGen = ores;
map.custom = true;
map.pixmap = pixmap;
map.visible = false;
map.id = -1;
return map;
}catch (IOException e){
throw new RuntimeException(e);
}
}
public static void writeWorld(Player player, ByteArray upgrades, OutputStream os){
try(DataOutputStream stream = new DataOutputStream(os)){
@@ -112,7 +31,7 @@ public class NetworkIO {
//--GENERAL STATE--
stream.writeByte(state.mode.ordinal()); //gamemode
stream.writeByte(world.getMap().custom ? -1 : world.getMap().id); //map ID
stream.writeUTF(world.getMap().name); //map ID
stream.writeInt(state.wave); //wave
stream.writeFloat(state.wavetime); //wave countdown
@@ -136,87 +55,33 @@ public class NetworkIO {
//--MAP DATA--
//seed
stream.writeInt(world.getSeed());
int totalblocks = 0;
int totalrocks = 0;
//map size
stream.writeShort(world.width());
stream.writeShort(world.height());
for(int x = 0; x < world.width(); x ++){
for(int y = 0; y < world.height(); y ++){
Tile tile = world.tile(x, y);
if(tile.breakable()){
if(tile.block() instanceof Rock){
totalrocks ++;
}else{
totalblocks ++;
}
//TODO will break if block number gets over BYTE_MAX
stream.writeByte(tile.floor().id); //floor ID
stream.writeByte(tile.block().id); //block ID
if(tile.block() instanceof BlockPart){
stream.writeByte(tile.link);
}
}
}
//amount of rocks
stream.writeInt(totalrocks);
if(tile.entity != null){
stream.writeByte(Bits.packByte((byte)tile.getTeam().ordinal(), tile.getRotation()));
stream.writeShort((short)tile.entity.health); //health
//write all rocks
for(int x = 0; x < world.width(); x ++) {
for (int y = 0; y < world.height(); y++) {
Tile tile = world.tile(x, y);
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
if(tile.entity.power != null) tile.entity.power.write(stream);
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
if (tile.block() instanceof Rock) {
stream.writeInt(tile.packedPosition());
tile.entity.write(stream);
}
}
}
//tile amount
stream.writeInt(totalblocks);
for(int x = 0; x < world.width(); x ++){
for(int y = 0; y < world.height(); y ++){
Tile tile = world.tile(x, y);
if(tile.breakable() && !(tile.block() instanceof Rock)){
stream.writeInt(x + y*world.width()); //tile pos
//TODO will break if block number gets over BYTE_MAX
stream.writeByte(tile.block().id); //block ID
if(tile.block() instanceof BlockPart){
stream.writeByte(tile.link);
}
if(tile.entity != null){
stream.writeByte(tile.getRotation());
stream.writeByte(tile.getDump());
stream.writeByte(tile.getExtra());
stream.writeShort((short)tile.entity.health); //health
if(tile.entity.inventory != null) tile.entity.inventory.write(stream);
if(tile.entity.power != null) tile.entity.power.write(stream);
if(tile.entity.liquid != null) tile.entity.liquid.write(stream);
//timer data
//amount of active timers
byte times = 0;
for(; times < tile.entity.timer.getTimes().length; times ++){
if(tile.entity.timer.getTimes()[times] <= 1){
break;
}
}
stream.writeByte(times);
for(int i = 0; i < times; i ++){
stream.writeFloat(tile.entity.timer.getTimes()[i]);
}
tile.entity.write(stream);
}
}
}
}
@@ -228,6 +93,8 @@ public class NetworkIO {
/**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/
public static void loadWorld(InputStream is){
//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();
@@ -237,7 +104,7 @@ public class NetworkIO {
//general state
byte mode = stream.readByte();
byte mapid = stream.readByte();
String map = stream.readUTF();
int wave = stream.readInt();
float wavetime = stream.readFloat();
@@ -266,7 +133,7 @@ public class NetworkIO {
byte weapons = stream.readByte();
for(int i = 0; i < weapons; i ++){
control.upgrades().getWeapons().add((Weapon) Upgrade.getByID(stream.readByte()));
control.upgrades().getWeapons().add(Upgrade.getByID(stream.readByte()));
}
player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().peek();
@@ -278,68 +145,44 @@ public class NetworkIO {
player.add();
//map
int width = stream.readShort();
int height = stream.readShort();
int seed = stream.readInt();
world.loadMap(world.maps().getMap(mapid), seed);
renderer.clearTiles();
player.set(world.getSpawnX(), world.getSpawnY());
Tile[][] tiles = world.createTiles(width, height);
for(int x = 0; x < world.width(); x ++){
for(int y = 0; y < world.height(); y ++){
Tile tile = world.tile(x, y);
byte floorid = stream.readByte();
byte blockid = stream.readByte();
//remove breakables like rocks
if(tile.breakable()){
world.tile(x, y).setBlock(Blocks.air);
}
}
}
Tile tile = new Tile(x, y, floorid, blockid);
int rocks = stream.readInt();
for(int i = 0; i < rocks; i ++){
int pos = stream.readInt();
Tile tile = world.tile(pos % world.width(), pos / world.width());
Block result = WorldGenerator.rocks.get(tile.floor());
if(result != null) tile.setBlock(result);
}
int tiles = stream.readInt();
for(int i = 0; i < tiles; i ++){
int pos = stream.readInt();
byte blockid = stream.readByte();
Tile tile = world.tile(pos % world.width(), pos / world.width());
tile.setBlock(Block.getByID(blockid));
if(tile.block() == Blocks.blockpart){
tile.link = stream.readByte();
}
if(tile.entity != null){
tile.setRotation(stream.readByte());
tile.setDump(stream.readByte());
tile.setExtra(stream.readByte());
short health = stream.readShort();
tile.entity.health = health;
if(tile.entity.inventory != null) tile.entity.inventory.read(stream);
if(tile.entity.power != null) tile.entity.power.read(stream);
if(tile.entity.liquid != null) tile.entity.liquid.read(stream);
byte timers = stream.readByte();
for(int time = 0; time < timers; time ++){
tile.entity.timer.getTimes()[time] = stream.readFloat();
if(tile.block() == Blocks.blockpart){
tile.link = stream.readByte();
}
tile.entity.read(stream);
if(tile.entity != null) {
byte tr = stream.readByte();
short health = stream.readShort();
tile.setTeam(Team.values()[Bits.getLeftByte(tr)]);
tile.setRotation(Bits.getRightByte(tr));
tile.entity.health = health;
if (tile.entity.inventory != null) tile.entity.inventory.read(stream);
if (tile.entity.power != null) tile.entity.power.read(stream);
if (tile.entity.liquid != null) tile.entity.liquid.read(stream);
tile.entity.read(stream);
}
tiles[x][y] = tile;
}
}
player.set(world.getSpawnX(), world.getSpawnY());
}catch (IOException e){
throw new RuntimeException(e);
}
+7 -18
View File
@@ -14,6 +14,7 @@ import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Block;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.util.IOUtils;
import java.nio.ByteBuffer;
@@ -64,8 +65,7 @@ public class Packets {
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(Version.build);
buffer.put((byte)name.getBytes().length);
buffer.put(name.getBytes());
IOUtils.writeString(buffer, name);
buffer.put(android ? (byte)1 : 0);
buffer.putInt(color);
buffer.put(uuid);
@@ -74,10 +74,7 @@ public class Packets {
@Override
public void read(ByteBuffer buffer) {
version = buffer.getInt();
byte length = buffer.get();
byte[] bytes = new byte[length];
buffer.get(bytes);
name = new String(bytes);
name = IOUtils.readString(buffer);
android = buffer.get() == 1;
color = buffer.getInt();
uuid = new byte[8];
@@ -320,8 +317,7 @@ public class Packets {
}else{
buffer.putShort((short)-1);
}
buffer.putShort((short)text.getBytes().length);
buffer.put(text.getBytes());
IOUtils.writeString(buffer, text);
buffer.putInt(id);
}
@@ -333,12 +329,9 @@ public class Packets {
buffer.get(n);
name = new String(n);
}
short tlength = buffer.getShort();
byte[] t = new byte[tlength];
buffer.get(t);
text = IOUtils.readString(buffer);
id = buffer.getInt();
text = new String(t);
}
}
@@ -487,16 +480,12 @@ public class Packets {
@Override
public void write(ByteBuffer buffer) {
buffer.putShort((short)message.getBytes().length);
buffer.put(message.getBytes());
IOUtils.writeString(buffer, message);
}
@Override
public void read(ByteBuffer buffer) {
short length = buffer.getShort();
byte[] bytes = new byte[length];
buffer.get(bytes);
message = new String(bytes);
message = IOUtils.readString(buffer);
}
}