1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-11-13 07:15:28 +03:00

even less broken

This commit is contained in:
Anuken 2019-05-05 22:09:02 -04:00
parent bf073a84c8
commit 20fbe2fbbe
16 changed files with 343 additions and 314 deletions

View File

@ -143,6 +143,19 @@ public class SerializeAnnotationProcessor extends AbstractProcessor{
.addStatement("bjson.writeObjectEnd()")
.addStatement("stream.writeUTF(output.toString())");
MethodSpec.Builder binaryJsonWriteStringMethod = MethodSpec.methodBuilder("write" + simpleTypeName + "StringJson")
.returns(String.class)
.addParameter(DataOutput.class, "stream")
.addParameter(type, "object")
.addException(IOException.class)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addStatement("java.io.StringWriter output = new java.io.StringWriter()")
.addStatement("bjson.setWriter(output)")
.addStatement("bjson.writeObjectStart(" + type + ".class, " + type + ".class)")
.addStatement("write" + simpleTypeName + "Json(bjson, object)")
.addStatement("bjson.writeObjectEnd()")
.addStatement("return output.toString()");
MethodSpec.Builder binaryJsonReadMethod = MethodSpec.methodBuilder("read" + simpleTypeName + "StreamJson")
.returns(type)
.addParameter(DataInput.class, "stream")
@ -151,6 +164,7 @@ public class SerializeAnnotationProcessor extends AbstractProcessor{
.addStatement("return read" + simpleTypeName + "Json(bjson.fromJson(null, stream.readUTF()))");
classBuilder.addMethod(binaryJsonWriteMethod.build());
classBuilder.addMethod(binaryJsonWriteStringMethod.build());
classBuilder.addMethod(binaryJsonReadMethod.build());
}

View File

@ -2,10 +2,10 @@ package io.anuke.mindustry.ai;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntArray;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.*;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Damage;
@ -14,48 +14,25 @@ import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.game.EventType.WorldLoadEvent;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Pos;
import java.io.*;
import static io.anuke.mindustry.Vars.*;
public class WaveSpawner{
private Array<FlyerSpawn> flySpawns = new Array<>();
private Array<GroundSpawn> groundSpawns = new Array<>();
private IntArray loadedSpawns = new IntArray();
private boolean spawning = false;
public WaveSpawner(){
Events.on(WorldLoadEvent.class, e -> reset());
}
public void write(DataOutput stream) throws IOException{
stream.writeInt(groundSpawns.size);
for(GroundSpawn spawn : groundSpawns){
stream.writeInt(Pos.get(spawn.x, spawn.y));
}
}
public void read(DataInput stream) throws IOException{
flySpawns.clear();
groundSpawns.clear();
loadedSpawns.clear();
int amount = stream.readInt();
for(int i = 0; i < amount; i++){
loadedSpawns.add(stream.readInt());
}
}
public int countSpawns(){
return groundSpawns.size;
}
/** @return true if the player is near a ground spawn point. */
public boolean playerNear(){
return groundSpawns.count(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < state.rules.dropZoneRadius) > 0;
return groundSpawns.contains(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < state.rules.dropZoneRadius);
}
public void spawnEnemies(){
@ -117,21 +94,11 @@ public class WaveSpawner{
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
if(world.tile(x, y).block() == Blocks.spawn){
if(world.tile(x, y).overlay() == Blocks.spawn){
addSpawns(x, y);
//hide spawnpoints, they have served their purpose
world.tile(x, y).setBlock(Blocks.air);
}
}
}
for(int i = 0; i < loadedSpawns.size; i++){
int pos = loadedSpawns.get(i);
addSpawns(Pos.x(pos), Pos.y(pos));
}
loadedSpawns.clear();
}
private void addSpawns(int x, int y){

View File

@ -88,15 +88,9 @@ public class Blocks implements ContentList{
hasShadow = false;
}
public void draw(Tile tile){
}
public void load(){
}
public void init(){
}
public void draw(Tile tile){}
public void load(){}
public void init(){}
public boolean isHidden(){
return true;
}
@ -119,7 +113,9 @@ public class Blocks implements ContentList{
}
}
spawn = new Block("spawn");
spawn = new OverlayFloor("spawn"){
public void draw(Tile tile){}
};
//Registers build blocks
//no reference is needed here since they can be looked up by name later

View File

@ -14,6 +14,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.IndexedRenderer;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BlockPart;
import static io.anuke.mindustry.Vars.tilesize;
@ -110,7 +111,7 @@ public class MapRenderer implements Disposable{
int idxWall = (wx % chunksize) + (wy % chunksize) * chunksize;
int idxDecal = (wx % chunksize) + (wy % chunksize) * chunksize + chunksize * chunksize;
if(wall != Blocks.air && (wall.synthetic() || wall == Blocks.part)){
if(wall != Blocks.air && (wall.synthetic() || wall instanceof BlockPart)){
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
if(wall.rotate){

View File

@ -0,0 +1,248 @@
package io.anuke.mindustry.io;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.StringMap;
import io.anuke.arc.util.Time;
import io.anuke.arc.util.io.CounterInputStream;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import java.io.*;
import static io.anuke.mindustry.Vars.*;
public abstract class BaseSaveVersion extends SaveFileVersion{
public BaseSaveVersion(int version){
super(version);
}
public void write(DataOutputStream stream) throws IOException{
region("meta", stream, this::writeMeta);
region("content", stream, this::writeContentHeader);
region("map", stream, this::writeMap);
region("entities", stream, this::writeEntities);
}
public void read(DataInputStream stream, CounterInputStream counter) throws IOException{
region("meta", stream, counter, this::readMeta);
region("content", stream, counter, this::readContentHeader);
region("map", stream, counter, this::readMap);
region("entities", stream, counter, this::readEntities);
}
public void writeMap(DataOutput stream) throws IOException{
//write world size
stream.writeShort(world.width());
stream.writeShort(world.height());
//floor + overlay
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i % world.width(), i / world.width());
stream.writeShort(tile.floorID());
stream.writeShort(tile.overlayID());
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.floorID() != tile.floorID() || nextTile.overlayID() != tile.overlayID()){
break;
}
consecutives++;
}
stream.writeByte(consecutives);
i += consecutives;
}
//blocks
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i % world.width(), i / world.width());
stream.writeShort(tile.blockID());
if(tile.entity != null){
//TODO chunks, backward compat
tile.entity.write(stream);
}else{
//write consecutive non-entity blocks
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.blockID() != tile.blockID()){
break;
}
consecutives++;
}
stream.writeByte(consecutives);
i += consecutives;
}
}
}
public void readMap(DataInput stream) throws IOException{
short width = stream.readShort();
short height = stream.readShort();
world.beginMapLoad();
Tile[][] tiles = world.createTiles(width, height);
//read floor and create tiles first
for(int i = 0; i < width * height; i++){
int x = i % width, y = i / width;
short floorid = stream.readShort();
short oreid = stream.readShort();
int consecutives = stream.readUnsignedByte();
tiles[x][y] = new Tile(x, y, floorid, oreid, (short)0);
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
tiles[newx][newy] = new Tile(newx, newy, floorid, oreid, (short)0);
}
i += consecutives;
}
//read blocks
for(int i = 0; i < width * height; i++){
int x = i % width, y = i / width;
Block block = content.block(stream.readShort());
Tile tile = tiles[x][y];
tile.setBlock(block);
if(tile.entity != null){
//TODO chunks, backward compat
tile.entity.read(stream);
}else{
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;
}
}
content.setTemporaryMapper(null);
world.endMapLoad();
}
public void writeEntities(DataOutput stream) throws IOException{
//write entity chunk
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()){
//TODO chunks, backward compat
//each entity is a separate chunk.
writeChunk(stream, true, out -> {
stream.writeByte(((SaveTrait)entity).getTypeID());
((SaveTrait)entity).writeSave(out);
});
}
}
}
}
public void readEntities(DataInput 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++){
//TODO chunks, backwards compat
byte typeid = stream.readByte();
SaveTrait trait = (SaveTrait)TypeTrait.getTypeByID(typeid).get();
trait.readSave(stream);
}
}
}
public void readContentHeader(DataInput stream) throws IOException{
byte mapped = stream.readByte();
MappableContent[][] map = new MappableContent[ContentType.values().length][0];
for(int i = 0; i < mapped; i++){
ContentType type = ContentType.values()[stream.readByte()];
short total = stream.readShort();
map[type.ordinal()] = new MappableContent[total];
for(int j = 0; j < total; j++){
String name = stream.readUTF();
map[type.ordinal()][j] = content.getByName(type, fallback.get(name, name));
}
}
content.setTemporaryMapper(map);
}
public void writeContentHeader(DataOutput stream) throws IOException{
Array<Content>[] map = content.getContentMap();
int mappable = 0;
for(Array<Content> arr : map){
if(arr.size > 0 && arr.first() instanceof MappableContent){
mappable++;
}
}
stream.writeByte(mappable);
for(Array<Content> arr : map){
if(arr.size > 0 && arr.first() instanceof MappableContent){
stream.writeByte(arr.first().getContentType().ordinal());
stream.writeShort(arr.size);
for(Content c : arr){
stream.writeUTF(((MappableContent)c).name);
}
}
}
}
public void writeMeta(DataOutput stream) throws IOException{
writeStringMap(stream, StringMap.of(
"saved", Time.millis(),
"playtime", headless ? 0 : control.saves.getTotalPlaytime(),
"build", Version.build,
"mapname", world.getMap().name(),
"wave", state.wave,
"wavetime", state.wavetime//,
//"stats", Serialization.writeStatsStreamJson(state.stats),
//"rules", Serialization.writeRulesStreamJson(state.rules),
));
}
public void readMeta(DataInput stream) throws IOException{
StringMap map = readStringMap(stream);
//TODO read rules, stats
state.wave = map.getInt("wave");
state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing);
}
}

View File

@ -1,40 +1,50 @@
package io.anuke.mindustry.io;
import io.anuke.arc.collection.*;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.collection.ObjectMap.Entry;
import io.anuke.arc.collection.StringMap;
import io.anuke.arc.util.io.CounterInputStream;
import io.anuke.arc.util.io.ReusableByteOutStream;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.MappableContent;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import java.io.*;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.world;
/**
* Format:
* 1. version of format / int
* - version of format: int
* (begin deflating)
* 2. regions
* - regions begin
* 1. meta tags (short length, key-val UTF pairs)
* 2. map data
*/
public abstract class SaveFileVersion{
public final int version;
private final ReusableByteOutStream byteOutput = new ReusableByteOutStream();
private final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
private final Region[] regions;
private final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad");
protected final ReusableByteOutStream byteOutput = new ReusableByteOutStream();
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
protected final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad");
public SaveFileVersion(int version, Region... regions){
public SaveFileVersion(int version){
this.version = version;
this.regions = regions;
}
protected void region(String name, DataInput stream, CounterInputStream counter, IORunner<DataInput> cons) throws IOException{
int length;
try{
length = readChunk(stream, cons);
}catch(Throwable e){
throw new IOException("Error reading region \"" + name + "\".", e);
}
if(length != counter.count() + 4){
throw new IOException("Error reading region \"" + name + "\": read length mismatch. Expected: " + length + "; Actual: " + (counter.count() + 4));
}
}
protected void region(String name, DataOutput stream, IORunner<DataOutput> cons) throws IOException{
try{
writeChunk(stream, cons);
}catch(Throwable e){
throw new IOException("Error writing region \"" + name + "\".", e);
}
}
public void writeChunk(DataOutput output, IORunner<DataOutput> runner) throws IOException{
@ -67,7 +77,6 @@ public abstract class SaveFileVersion{
/** Reads a chunk of some length. Use the runner for reading to catch more descriptive errors. */
public int readChunk(DataInput input, boolean isByte, IORunner<DataInput> runner) throws IOException{
int length = isByte ? input.readUnsignedByte() : input.readInt();
//TODO descriptive error with chunk name
runner.accept(input);
return length;
}
@ -81,7 +90,7 @@ public abstract class SaveFileVersion{
}
}
public void writeMeta(DataOutput stream, ObjectMap<String, String> map) throws IOException{
public void writeStringMap(DataOutput stream, ObjectMap<String, String> map) throws IOException{
stream.writeShort(map.size);
for(Entry<String, String> entry : map.entries()){
stream.writeUTF(entry.key);
@ -89,7 +98,7 @@ public abstract class SaveFileVersion{
}
}
public StringMap readMeta(DataInput stream) throws IOException{
public StringMap readStringMap(DataInput stream) throws IOException{
StringMap map = new StringMap();
short size = stream.readShort();
for(int i = 0; i < size; i++){
@ -98,227 +107,9 @@ public abstract class SaveFileVersion{
return map;
}
public void writeMap(DataOutput stream) throws IOException{
//write world size
stream.writeShort(world.width());
stream.writeShort(world.height());
public abstract void read(DataInputStream stream, CounterInputStream counter) throws IOException;
//floor + overlay
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i % world.width(), i / world.width());
stream.writeShort(tile.floorID());
stream.writeShort(tile.overlayID());
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.floorID() != tile.floorID() || nextTile.overlayID() != tile.overlayID()){
break;
}
consecutives++;
}
stream.writeByte(consecutives);
i += consecutives;
}
//blocks
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i % world.width(), i / world.width());
stream.writeShort(tile.blockID());
if(tile.entity != null){
tile.entity.write(stream);
}else{
//write consecutive non-entity blocks
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.blockID() != tile.blockID()){
break;
}
consecutives++;
}
stream.writeByte(consecutives);
i += consecutives;
}
}
}
public void readMap(DataInputStream stream) throws IOException{
short width = stream.readShort();
short height = stream.readShort();
world.beginMapLoad();
Tile[][] tiles = world.createTiles(width, height);
//read floor and create tiles first
for(int i = 0; i < width * height; i++){
int x = i % width, y = i / width;
short floorid = stream.readShort();
short oreid = stream.readShort();
int consecutives = stream.readUnsignedByte();
tiles[x][y] = new Tile(false, x, y, floorid, oreid);
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
tiles[newx][newy] = new Tile(false, newx, newy, floorid, 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.readShort());
Tile tile = tiles[x][y];
tile.setBlock(block);
if(tile.entity != null){
tile.entity.read(stream);
}else{
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;
}
}
content.setTemporaryMapper(null);
world.endMapLoad();
}
public void writeEntities(DataOutputStream stream) throws IOException{
//write entity chunk
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()){
//each entity is a separate chunk.
writeChunk(stream, true, out -> {
stream.writeByte(((SaveTrait)entity).getTypeID());
((SaveTrait)entity).writeSave(out);
});
}
}
}
}
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();
MappableContent[][] map = new MappableContent[ContentType.values().length][0];
for(int i = 0; i < mapped; i++){
ContentType type = ContentType.values()[stream.readByte()];
short total = stream.readShort();
map[type.ordinal()] = new MappableContent[total];
for(int j = 0; j < total; j++){
String name = stream.readUTF();
map[type.ordinal()][j] = content.getByName(type, fallback.get(name, name));
}
}
return map;
}
public void writeContentHeader(DataOutputStream stream) throws IOException{
Array<Content>[] map = content.getContentMap();
int mappable = 0;
for(Array<Content> arr : map){
if(arr.size > 0 && arr.first() instanceof MappableContent){
mappable++;
}
}
stream.writeByte(mappable);
for(Array<Content> arr : map){
if(arr.size > 0 && arr.first() instanceof MappableContent){
stream.writeByte(arr.first().getContentType().ordinal());
stream.writeShort(arr.size);
for(Content c : arr){
stream.writeUTF(((MappableContent)c).name);
}
}
}
}
public final void read(DataInputStream stream, CounterInputStream counter) throws IOException{
for(Region region : regions){
counter.resetCount();
try{
int length = readChunk(stream, region.reader);
if(length != counter.count() + 4){
throw new IOException("Error reading region \"" + region.name + "\": read length mismatch. Expected: " + length + "; Actual: " + (counter.count() + 4));
}
}catch(Throwable e){
throw new IOException("Error reading region \"" + region.name + "\".", e);
}
}
}
public final void write(DataOutputStream stream) throws IOException{
for(Region region : regions){
try{
writeChunk(stream, region.writer);
}catch(Throwable e){
throw new IOException("Error writing region \"" + region.name + "\".", e);
}
}
}
/** A region of a save file that holds a specific category of information.
* Uses: simplify code reuse, provide better error messages, skip unnecessary data.*/
protected final class Region{
final IORunner<DataOutput> writer;
final IORunner<DataInput> reader;
final String name;
public Region(IORunner<DataOutput> writer, IORunner<DataInput> reader, String name){
this.writer = writer;
this.reader = reader;
this.name = name;
}
}
public abstract void write(DataOutputStream stream) throws IOException;
protected interface IORunner<T>{
void accept(T stream) throws IOException;

View File

@ -1,12 +1,14 @@
package io.anuke.mindustry.io;
import io.anuke.arc.collection.*;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.IntMap;
import io.anuke.arc.files.FileHandle;
import io.anuke.arc.util.io.CounterInputStream;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.io.versions.Save1;
import java.io.*;
import java.util.Arrays;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
@ -110,6 +112,8 @@ public class SaveIO{
try{
stream = new DataOutputStream(os);
stream.write(header);
stream.writeInt(getVersion().version);
getVersion().write(stream);
stream.close();
}catch(Exception e){
@ -135,6 +139,7 @@ public class SaveIO{
public static void load(InputStream is) throws SaveException{
try(CounterInputStream counter = new CounterInputStream(is); DataInputStream stream = new DataInputStream(counter)){
logic.reset();
readHeader(stream);
int version = stream.readInt();
SaveFileVersion ver = versions.get(version);
@ -150,6 +155,14 @@ public class SaveIO{
return versionArray.peek();
}
public static void readHeader(DataInput input) throws IOException{
byte[] bytes = new byte[header.length];
input.readFully(bytes);
if(!Arrays.equals(bytes, header)){
throw new IOException("Incorrect header! Expecting: " + Arrays.toString(header) + "; Actual: " + Arrays.toString(bytes));
}
}
public static class SaveException extends RuntimeException{
public SaveException(Throwable throwable){
super(throwable);

View File

@ -69,6 +69,7 @@ public class Save1 extends SaveFileVersion{
stream.writeFloat(state.wavetime); //wave countdown
Serialization.writeStats(stream, state.stats);
world.spawner.write(stream);
writeContentHeader(stream);

View File

@ -156,8 +156,7 @@ public abstract class BasicGenerator extends RandomGenerator{
block = tiles[x][y].block();
ore = tiles[x][y].overlay();
r.accept(x, y);
tiles[x][y] = new Tile(x, y, floor.id, block.id);
tiles[x][y].setOverlay(ore);
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
}
}
}

View File

@ -12,8 +12,7 @@ import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Loadout;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.StaticWall;
import io.anuke.mindustry.world.blocks.*;
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
import io.anuke.mindustry.world.blocks.storage.StorageBlock;
@ -88,12 +87,12 @@ public class MapGenerator extends Generator{
tiles[x][y].setBlock(Blocks.air);
}
if(tiles[x][y].block() == Blocks.spawn && enemySpawns != -1){
if(tiles[x][y].overlay() == Blocks.spawn && enemySpawns != -1){
enemies.add(new Point2(x, y));
tiles[x][y].setBlock(Blocks.air);
tiles[x][y].setOverlay(Blocks.air);
}
if(tiles[x][y].block() == Blocks.part){
if(tiles[x][y].block() instanceof BlockPart){
tiles[x][y].setBlock(Blocks.air);
}
}
@ -111,13 +110,15 @@ public class MapGenerator extends Generator{
if(((tile.block() instanceof StaticWall
&& tiles[newX][newY].block() instanceof StaticWall)
|| (tile.block() == Blocks.air && !tiles[newX][newY].block().synthetic())
|| (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall)) && tiles[newX][newY].block() != Blocks.spawn && tile.block() != Blocks.spawn){
|| (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall))){
tile.setBlock(tiles[newX][newY].block());
}
if(distortFloor){
tile.setFloor(tiles[newX][newY].floor());
tile.setOverlay(tiles[newX][newY].overlay());
if(tiles[newX][newY].overlay() != Blocks.spawn && tile.overlay() != Blocks.spawn){
tile.setOverlay(tiles[newX][newY].overlay());
}
}
for(Decoration decor : decorations){
@ -150,7 +151,7 @@ public class MapGenerator extends Generator{
enemies.shuffle();
for(int i = 0; i < enemySpawns; i++){
Point2 point = enemies.get(i);
tiles[point.x][point.y].setBlock(Blocks.spawn);
tiles[point.x][point.y].setOverlay(Blocks.spawn);
int rad = 10, frad = 12;
@ -160,7 +161,9 @@ public class MapGenerator extends Generator{
double dst = Mathf.dst(x, y);
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
Tile tile = tiles[wx][wy];
tile.clearOverlay();
if(tile.overlay() != Blocks.spawn){
tile.clearOverlay();
}
}
}
}

View File

@ -26,8 +26,7 @@ public abstract class RandomGenerator extends Generator{
block = Blocks.air;
ore = Blocks.air;
generate(x, y);
tiles[x][y] = new Tile(x, y, floor.id, block.id);
tiles[x][y].setOverlay(ore);
tiles[x][y] = new Tile(x, y, floor.id, ore.id, block.id);
}
}

View File

@ -41,7 +41,7 @@ public class DesertWastesGenerator extends BasicGenerator{
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
tiles[endX][endY].setBlock(Blocks.spawn);
tiles[endX][endY].setOverlay(Blocks.spawn);
loadout.setup(spawnX, spawnY);
}
}

View File

@ -37,7 +37,7 @@ public class OvergrowthGenerator extends BasicGenerator{
noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
tiles[endX][endY].setBlock(Blocks.spawn);
tiles[endX][endY].setOverlay(Blocks.spawn);
loadout.setup(spawnX, spawnY);
}
}

View File

@ -40,7 +40,6 @@ public class NetworkIO{
stream.writeInt(player.id);
player.write(stream);
world.spawner.write(stream);
SaveIO.getSaveWriter().writeMap(stream);
stream.write(Team.all.length);
@ -98,7 +97,6 @@ public class NetworkIO{
player.add();
//map
world.spawner.read(stream);
SaveIO.getSaveWriter().readMap(stream);
world.setMap(new Map(customMapDirectory.child(map), 0, 0, new ObjectMap<>(), true));

View File

@ -18,7 +18,7 @@ public class LegacyColorMapper implements ContentList{
public void load(){
defaultValue = new LegacyBlock(Blocks.stone, Blocks.air);
map("ff0000", Blocks.stone, Blocks.spawn);
map("ff0000", Blocks.stone, Blocks.air, Blocks.spawn);
map("00ff00", Blocks.stone);
map("323232", Blocks.stone);
map("646464", Blocks.stone, Blocks.rocks);
@ -60,9 +60,7 @@ public class LegacyColorMapper implements ContentList{
public final Block ore;
public LegacyBlock(Block floor, Block wall){
this.floor = (Floor)floor;
this.wall = wall;
this.ore = null;
this(floor, wall, Blocks.air);
}
public LegacyBlock(Block floor, Block wall, Block ore){

View File

@ -36,10 +36,11 @@ public class Tile implements Position, TargetTrait{
block = floor = (Floor)Blocks.air;
}
public Tile(boolean __removeThisLater, int x, int y, short floor, short overlay){
public Tile(int x, int y, short floor, short overlay, short wall){
this.x = (short)x;
this.y = (short)y;
this.floor = (Floor)content.block(floor);
this.block = content.block(wall);
this.overlay = overlay;
}