Made save format actually functional, many things still broken

This commit is contained in:
Anuken
2019-05-08 23:16:08 -04:00
parent 53167a3b52
commit 8127e5a66f
16 changed files with 146 additions and 60 deletions
@@ -13,9 +13,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes({ @SupportedAnnotationTypes("io.anuke.annotations.Annotations.Serialize")
"io.anuke.annotations.Annotations.Serialize"
})
public class SerializeAnnotationProcessor extends AbstractProcessor{ public class SerializeAnnotationProcessor extends AbstractProcessor{
/** Target class name. */ /** Target class name. */
private static final String className = "Serialization"; private static final String className = "Serialization";
@@ -44,6 +42,28 @@ public class SerializeAnnotationProcessor extends AbstractProcessor{
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC); TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build()); classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning); classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
classBuilder.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.bestGuess("io.anuke.arc.collection.ObjectMap"),
ClassName.get(Class.class),
ClassName.bestGuess("io.anuke.mindustry.io.JsonTypeWriter")),
"writers", Modifier.PRIVATE, Modifier.STATIC).initializer("new io.anuke.arc.collection.ObjectMap<>()").build());
classBuilder.addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.bestGuess("io.anuke.arc.collection.ObjectMap"),
ClassName.get(Class.class),
ClassName.bestGuess("io.anuke.mindustry.io.JsonTypeReader")),
"readers", Modifier.PRIVATE, Modifier.STATIC).initializer("new io.anuke.arc.collection.ObjectMap<>()").build());
classBuilder.addMethod(MethodSpec.methodBuilder("setSerializer")
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addTypeVariable(TypeVariableName.get("T"))
.addParameter(ParameterizedTypeName.get(ClassName.get(Class.class), TypeVariableName.get("T")), "type")
.addParameter(ParameterizedTypeName.get(ClassName.bestGuess("io.anuke.mindustry.io.JsonTypeWriter"), TypeVariableName.get("T")), "writer")
.addParameter(ParameterizedTypeName.get(ClassName.bestGuess("io.anuke.mindustry.io.JsonTypeReader"), TypeVariableName.get("T")), "reader")
.addStatement("writers.put(type, writer)")
.addStatement("readers.put(type, reader)").build());
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
TypeName jsonType = ClassName.bestGuess("io.anuke.arc.util.serialization.Json"); TypeName jsonType = ClassName.bestGuess("io.anuke.arc.util.serialization.Json");
@@ -107,6 +127,32 @@ public class SerializeAnnotationProcessor extends AbstractProcessor{
}else{ }else{
writeMethod.addStatement("io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")"); writeMethod.addStatement("io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
readMethod.addStatement("object." + name + " = (" + typeName + ")io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)"); readMethod.addStatement("object." + name + " = (" + typeName + ")io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
if(field.asType().toString().equalsIgnoreCase("java.lang.String")){
jsonWriteMethod.addStatement("json.writeValue(\"" + name + "\", object." + name + ")");
jsonReadMethod.addStatement("if(value.has(\"" + name + "\")) object." + name + "= value.getString(\"" + name + "\")");
}else if(field.asType().toString().startsWith("io.anuke.arc.collection.Array")){ //oh boy here it begins
String genericType = field.asType().toString().substring(field.asType().toString().indexOf('<') + 1, field.asType().toString().indexOf('>'));
{
jsonWriteMethod.addStatement("json.writeArrayStart($S)", name)
.beginControlFlow("for(" + genericType + " item : object." + name + ")")
.addStatement("json.writeValue(item)")
.endControlFlow()
.addStatement("json.writeArrayEnd()");
}
{
//jsonWriteMethod.beginControlFlow("if(value.has($S))", name);
//jsonWriteMethod.addStatement("io.anuke.arc.util.serialization.JsonValue list = value.get($S)", name);
//jsonWriteMethod.endControlFlow();
}
//jsonWriteMethod.addStatement("for( ")
}else{
jsonWriteMethod.addStatement("if(object."+name+" != null) writers.getThrow("+typeName+".class, () -> new IllegalArgumentException(\"Class '"
+ typeName + "' does not have a serializer!\")).write(bjson, object."+name+", \"" + name+"\")");
jsonReadMethod.addStatement("if(value.has(\"" + name + "\")) object." + name + " = ("+typeName+")readers.getThrow("+typeName+".class, () -> new IllegalArgumentException(\"Class '"
+ typeName + "' does not have a serializer!\")).read(value, \""+name+"\")");
}
} }
} }
+4 -3
View File
@@ -60,9 +60,10 @@ public class Logic implements ApplicationListener{
state.wavetime = state.rules.waveSpacing * 2; //grace period of 2x wave time before game starts state.wavetime = state.rules.waveSpacing * 2; //grace period of 2x wave time before game starts
//sometimes a map has no waves defined, they're defined in the zone rules //sometimes a map has no waves defined, they're defined in the zone rules
if(world.getMap().getWaves() != DefaultWaves.get() || !world.isZone()){ //TODO ???? how does this even work now
state.rules.spawns = world.getMap().getWaves(); //if(world.getMap().getWaves() != DefaultWaves.get() || !world.isZone()){
} // state.rules.spawns = world.getMap().getWaves();
//}
Events.fire(new PlayEvent()); Events.fire(new PlayEvent());
} }
@@ -35,7 +35,9 @@ public class World implements ApplicationListener{
private boolean generating, invalidMap; private boolean generating, invalidMap;
public World(){ public World(){
//TODO swap
Core.app.post(maps::load); Core.app.post(maps::load);
//maps.load();
} }
@Override @Override
+1 -1
View File
@@ -9,7 +9,7 @@ import io.anuke.mindustry.type.*;
@Serialize @Serialize
public class Stats{ public class Stats{
/** Items delivered to global resoure counter. Zones only. */ /** Items delivered to global resoure counter. Zones only. */
public ObjectIntMap<Item> itemsDelivered = new ObjectIntMap<>(); public transient ObjectIntMap<Item> itemsDelivered = new ObjectIntMap<>();
/** Enemy (red team) units destroyed. */ /** Enemy (red team) units destroyed. */
public int enemyUnitsDestroyed; public int enemyUnitsDestroyed;
/** Total waves lasted. */ /** Total waves lasted. */
@@ -0,0 +1,24 @@
package io.anuke.mindustry.io;
import io.anuke.arc.util.serialization.Json;
import io.anuke.mindustry.game.Rules;
import io.anuke.mindustry.game.SpawnGroup;
public class JsonIO{
private static Json json = new Json(){{
setIgnoreUnknownFields(true);
setElementType(Rules.class, "spawns", SpawnGroup.class);
}};
public static String write(Object object){
return json.toJson(object);
}
public static <T> T read(Class<T> type, String string){
return json.fromJson(type, string);
}
public static String print(String in){
return json.prettyPrint(in);
}
}
@@ -0,0 +1,7 @@
package io.anuke.mindustry.io;
import io.anuke.arc.util.serialization.JsonValue;
public interface JsonTypeReader<T>{
T read(JsonValue json, String name);
}
@@ -0,0 +1,7 @@
package io.anuke.mindustry.io;
import io.anuke.arc.util.serialization.Json;
public interface JsonTypeWriter<T>{
void write(Json json, T object, String name);
}
@@ -6,7 +6,9 @@ import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Pixmap; import io.anuke.arc.graphics.Pixmap;
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.arc.util.serialization.Json;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.io.MapIO.TileProvider; import io.anuke.mindustry.io.MapIO.TileProvider;
import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.Map;
@@ -25,16 +27,22 @@ import static io.anuke.mindustry.Vars.*;
* Differentiate between legacy maps and new maps by checking the extension (or the header).*/ * Differentiate between legacy maps and new maps by checking the extension (or the header).*/
public class LegacyMapIO{ public class LegacyMapIO{
private static final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad"); private static final ObjectMap<String, String> fallback = ObjectMap.of("alpha-dart-mech-pad", "dart-mech-pad");
private static final Json json = new Json();
/* Convert a map from the old format to the new format. */ /* Convert a map from the old format to the new format. */
public static void convertMap(FileHandle in, FileHandle out) throws IOException{ public static void convertMap(FileHandle in, FileHandle out) throws IOException{
Map map = readMap(in, true); Map map = readMap(in, true);
String waves = map.tags.get("waves", "[]");
Array<SpawnGroup> groups = new Array<>(json.fromJson(SpawnGroup[].class, waves));
Tile[][] tiles = world.createTiles(map.width, map.height); Tile[][] tiles = world.createTiles(map.width, map.height);
for(int x = 0; x < map.width; x++){ for(int x = 0; x < map.width; x++){
for(int y = 0; y < map.height; y++){ for(int y = 0; y < map.height; y++){
tiles[x][y] = new Tile(x, y); tiles[x][y] = new CachedTile();
} }
} }
state.rules.spawns = groups;
readTiles(map, tiles); readTiles(map, tiles);
MapIO.writeMap(out, map); MapIO.writeMap(out, map);
} }
@@ -11,6 +11,8 @@ import java.io.*;
public abstract class SaveFileReader{ public abstract class SaveFileReader{
protected final ReusableByteOutStream byteOutput = new ReusableByteOutStream(); protected final ReusableByteOutStream byteOutput = new ReusableByteOutStream();
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput); protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
protected final ReusableByteOutStream byteOutputSmall = new ReusableByteOutStream();
protected final DataOutputStream dataBytesSmall = new DataOutputStream(byteOutputSmall);
protected final ObjectMap<String, String> fallback = ObjectMap.of(); protected final ObjectMap<String, String> fallback = ObjectMap.of();
protected void region(String name, DataInput stream, CounterInputStream counter, IORunner<DataInput> cons) throws IOException{ protected void region(String name, DataInput stream, CounterInputStream counter, IORunner<DataInput> cons) throws IOException{
@@ -21,6 +23,7 @@ public abstract class SaveFileReader{
}catch(Throwable e){ }catch(Throwable e){
throw new IOException("Error reading region \"" + name + "\".", e); throw new IOException("Error reading region \"" + name + "\".", e);
} }
if(length != counter.count() - 4){ if(length != counter.count() - 4){
throw new IOException("Error reading region \"" + name + "\": read length mismatch. Expected: " + length + "; Actual: " + (counter.count() - 4)); throw new IOException("Error reading region \"" + name + "\": read length mismatch. Expected: " + length + "; Actual: " + (counter.count() - 4));
} }
@@ -40,11 +43,12 @@ public abstract class SaveFileReader{
/** Write a chunk of input to the stream. An integer of some length is written first, followed by the data. */ /** Write a chunk of input to the stream. An integer of some length is written first, followed by the data. */
public void writeChunk(DataOutput output, boolean isByte, IORunner<DataOutput> runner) throws IOException{ public void writeChunk(DataOutput output, boolean isByte, IORunner<DataOutput> runner) throws IOException{
ReusableByteOutStream dout = isByte ? byteOutputSmall : byteOutput;
//reset output position //reset output position
byteOutput.reset(); dout.reset();
//write the needed info //write the needed info
runner.accept(dataBytes); runner.accept(isByte ? dataBytesSmall : dataBytes);
int length = byteOutput.size(); int length = dout.size();
//write length (either int or byte) followed by the output bytes //write length (either int or byte) followed by the output bytes
if(!isByte){ if(!isByte){
output.writeInt(length); output.writeInt(length);
@@ -54,7 +58,7 @@ public abstract class SaveFileReader{
} }
output.writeShort(length); output.writeShort(length);
} }
output.write(byteOutput.getBytes(), 0, length); output.write(dout.getBytes(), 0, length);
} }
public int readChunk(DataInput input, IORunner<DataInput> runner) throws IOException{ public int readChunk(DataInput input, IORunner<DataInput> runner) throws IOException{
+2 -5
View File
@@ -90,6 +90,7 @@ public class SaveIO{
public static SaveMeta getMeta(DataInputStream stream){ public static SaveMeta getMeta(DataInputStream stream){
try{ try{
readHeader(stream);
int version = stream.readInt(); int version = stream.readInt();
SaveMeta meta = versions.get(version).getMeta(stream); SaveMeta meta = versions.get(version).getMeta(stream);
stream.close(); stream.close();
@@ -116,10 +117,7 @@ public class SaveIO{
} }
public static void write(OutputStream os, StringMap tags){ public static void write(OutputStream os, StringMap tags){
DataOutputStream stream; try(DataOutputStream stream = new DataOutputStream(os)){
try{
stream = new DataOutputStream(os);
stream.write(header); stream.write(header);
stream.writeInt(getVersion().version); stream.writeInt(getVersion().version);
if(tags == null){ if(tags == null){
@@ -127,7 +125,6 @@ public class SaveIO{
}else{ }else{
getVersion().write(stream, tags); getVersion().write(stream, tags);
} }
stream.close();
}catch(Exception e){ }catch(Exception e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
+19 -17
View File
@@ -8,7 +8,6 @@ import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.Serialization;
import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -27,7 +26,7 @@ public abstract class SaveVersion extends SaveFileReader{
public SaveMeta getMeta(DataInput stream) throws IOException{ public SaveMeta getMeta(DataInput stream) throws IOException{
stream.readInt(); //length of data, doesn't matter here stream.readInt(); //length of data, doesn't matter here
StringMap map = readStringMap(stream); StringMap map = readStringMap(stream);
return new SaveMeta(map.getInt("version"), map.getLong("saved"), map.getLong("playtime"), map.getInt("build"), map.get("mapname"), map.getInt("wave"), Serialization.readRulesStringJson(map.get("rules", "{}"))); return new SaveMeta(map.getInt("version"), map.getLong("saved"), map.getLong("playtime"), map.getInt("build"), map.get("mapname"), map.getInt("wave"), JsonIO.read(Rules.class, map.get("rules", "{}")));
} }
public final void write(DataOutputStream stream) throws IOException{ public final void write(DataOutputStream stream) throws IOException{
@@ -56,8 +55,8 @@ public abstract class SaveVersion extends SaveFileReader{
"mapname", world.getMap() == null ? "unknown" : world.getMap().name(), "mapname", world.getMap() == null ? "unknown" : world.getMap().name(),
"wave", state.wave, "wave", state.wave,
"wavetime", state.wavetime, "wavetime", state.wavetime,
"stats", Serialization.writeStatsJson(state.stats), "stats", JsonIO.write(state.stats),
"rules", Serialization.writeRulesJson(state.rules), "rules", JsonIO.write(state.rules),
"width", world.width(), "width", world.width(),
"height", world.height() "height", world.height()
).merge(tags)); ).merge(tags));
@@ -68,11 +67,12 @@ public abstract class SaveVersion extends SaveFileReader{
state.wave = map.getInt("wave"); state.wave = map.getInt("wave");
state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing); state.wavetime = map.getFloat("wavetime", state.rules.waveSpacing);
state.stats = Serialization.readStatsStringJson(map.get("stats", "{}")); state.stats = JsonIO.read(Stats.class, map.get("stats", "{}"));
state.rules = Serialization.readRulesStringJson(map.get("rules", "{}")); state.rules = JsonIO.read(Rules.class, map.get("rules", "{}"));
} }
public void writeMap(DataOutput stream) throws IOException{ public void writeMap(DataOutput stream) throws IOException{
//TODO something here messes up everything
//write world size //write world size
stream.writeShort(world.width()); stream.writeShort(world.width());
stream.writeShort(world.height()); stream.writeShort(world.height());
@@ -106,7 +106,7 @@ public abstract class SaveVersion extends SaveFileReader{
if(tile.entity != null){ if(tile.entity != null){
writeChunk(stream, true, out -> { writeChunk(stream, true, out -> {
out.writeByte(tile.entity.version()); out.writeByte(tile.entity.version());
tile.entity.write(stream); tile.entity.write(out);
}); });
}else{ }else{
//write consecutive non-entity blocks //write consecutive non-entity blocks
@@ -129,10 +129,12 @@ public abstract class SaveVersion extends SaveFileReader{
} }
public void readMap(DataInput stream) throws IOException{ public void readMap(DataInput stream) throws IOException{
short width = stream.readShort(); int width = stream.readUnsignedShort();
short height = stream.readShort(); int height = stream.readUnsignedShort();
world.beginMapLoad(); boolean generating = world.isGenerating();
if(!generating) world.beginMapLoad();
Tile[][] tiles = world.createTiles(width, height); Tile[][] tiles = world.createTiles(width, height);
@@ -163,7 +165,7 @@ public abstract class SaveVersion extends SaveFileReader{
if(tile.entity != null){ if(tile.entity != null){
readChunk(stream, true, in -> { readChunk(stream, true, in -> {
byte version = in.readByte(); byte version = in.readByte();
tile.entity.read(stream, version); tile.entity.read(in, version);
}); });
}else{ }else{
int consecutives = stream.readUnsignedByte(); int consecutives = stream.readUnsignedByte();
@@ -178,7 +180,7 @@ public abstract class SaveVersion extends SaveFileReader{
} }
content.setTemporaryMapper(null); content.setTemporaryMapper(null);
world.endMapLoad(); if(!generating) world.endMapLoad();
} }
public void writeEntities(DataOutput stream) throws IOException{ public void writeEntities(DataOutput stream) throws IOException{
@@ -200,8 +202,8 @@ public abstract class SaveVersion extends SaveFileReader{
SaveTrait save = (SaveTrait)entity; SaveTrait save = (SaveTrait)entity;
//each entity is a separate chunk. //each entity is a separate chunk.
writeChunk(stream, true, out -> { writeChunk(stream, true, out -> {
stream.writeByte(save.getTypeID()); out.writeByte(save.getTypeID());
stream.writeByte(save.version()); out.writeByte(save.version());
save.writeSave(out); save.writeSave(out);
}); });
} }
@@ -217,10 +219,10 @@ public abstract class SaveVersion extends SaveFileReader{
for(int j = 0; j < amount; j++){ for(int j = 0; j < amount; j++){
//TODO throw exception on read fail //TODO throw exception on read fail
readChunk(stream, true, in -> { readChunk(stream, true, in -> {
byte typeid = stream.readByte(); byte typeid = in.readByte();
byte version = stream.readByte(); byte version = in.readByte();
SaveTrait trait = (SaveTrait)TypeTrait.getTypeByID(typeid).get(); SaveTrait trait = (SaveTrait)TypeTrait.getTypeByID(typeid).get();
trait.readSave(stream, version); trait.readSave(in, version);
}); });
} }
} }
+1 -20
View File
@@ -1,15 +1,10 @@
package io.anuke.mindustry.maps; package io.anuke.mindustry.maps;
import io.anuke.arc.Core; import io.anuke.arc.Core;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.StringMap;
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.arc.util.Log;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.DefaultWaves;
import io.anuke.mindustry.game.SpawnGroup;
import static io.anuke.mindustry.Vars.world;
public class Map implements Comparable<Map>{ public class Map implements Comparable<Map>{
/** Whether this is a custom map. */ /** Whether this is a custom map. */
@@ -49,20 +44,6 @@ public class Map implements Comparable<Map>{
this(Vars.customMapDirectory.child(tags.get("name", "unknown")), 0, 0, tags, true); this(Vars.customMapDirectory.child(tags.get("name", "unknown")), 0, 0, tags, true);
} }
public Array<SpawnGroup> getWaves(){
if(tags.containsKey("waves")){
try{
return world.maps.readWaves(tags.get("waves"));
}catch(Exception e){
Log.err("Malformed waves: {0}", tags.get("waves"));
e.printStackTrace();
return DefaultWaves.get();
}
}else{
return DefaultWaves.get();
}
}
public int getHightScore(){ public int getHightScore(){
return Core.settings.getInt("hiscore" + file.nameWithoutExtension(), 0); return Core.settings.getInt("hiscore" + file.nameWithoutExtension(), 0);
} }
+2 -2
View File
@@ -8,8 +8,7 @@ import io.anuke.arc.util.Disposable;
import io.anuke.arc.util.Log; import io.anuke.arc.util.Log;
import io.anuke.arc.util.serialization.Json; import io.anuke.arc.util.serialization.Json;
import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.game.SpawnGroup;
import io.anuke.mindustry.io.LegacyMapIO; import io.anuke.mindustry.io.*;
import io.anuke.mindustry.io.MapIO;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
@@ -61,6 +60,7 @@ public class Maps implements Disposable{
public void load(){ public void load(){
try{ try{
//TODO remove, this is only for testing //TODO remove, this is only for testing
for(FileHandle in : Core.files.absolute("/home/anuke/Projects/Mindustry/core/assets/maps").list()){ for(FileHandle in : Core.files.absolute("/home/anuke/Projects/Mindustry/core/assets/maps").list()){
if(in.extension().equalsIgnoreCase(oldMapExtension)){ if(in.extension().equalsIgnoreCase(oldMapExtension)){
Log.info("Converting {0}...", in); Log.info("Converting {0}...", in);
@@ -60,10 +60,9 @@ public class MapGenerator extends Generator{
@Override @Override
public void init(Loadout loadout){ public void init(Loadout loadout){
this.loadout = loadout; this.loadout = loadout;
//TODO uncomment once conversion works map = world.maps.loadInternalMap(mapName);
//map = world.maps.loadInternalMap(mapName); width = map.width;
//width = map.width; height = map.height;
//height = map.height;
} }
@Override @Override
@@ -13,6 +13,7 @@ import io.anuke.mindustry.game.EventType.ZoneConfigureCompleteEvent;
import io.anuke.mindustry.game.EventType.ZoneRequireCompleteEvent; import io.anuke.mindustry.game.EventType.ZoneRequireCompleteEvent;
import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.Rules;
import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.gen.Serialization;
import io.anuke.mindustry.maps.generators.Generator; import io.anuke.mindustry.maps.generators.Generator;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@@ -38,6 +39,12 @@ public class Zone extends UnlockableContent{
private Array<ItemStack> defaultStartingItems = new Array<>(); private Array<ItemStack> defaultStartingItems = new Array<>();
static{
Serialization.setSerializer(Zone.class,
(json, zone, name) -> json.writeValue(name, zone.name),
(json, name) -> content.getByName(ContentType.zone, json.getString(name)));
}
public Zone(String name, Generator generator){ public Zone(String name, Generator generator){
super(name); super(name);
this.generator = generator; this.generator = generator;
@@ -37,6 +37,7 @@ public class CachedTile extends Tile{
if(!entities.containsKey(block.id)){ if(!entities.containsKey(block.id)){
TileEntity n = block.newEntity(); TileEntity n = block.newEntity();
n.cons = new ConsumeModule(entity); n.cons = new ConsumeModule(entity);
n.tile = this;
if(block.hasItems) n.items = new ItemModule(); if(block.hasItems) n.items = new ItemModule();
if(block.hasLiquids) n.liquids = new LiquidModule(); if(block.hasLiquids) n.liquids = new LiquidModule();
if(block.hasPower) n.power = new PowerModule(); if(block.hasPower) n.power = new PowerModule();