I waste several hours
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
12
core/assets/shaders/fog.frag
Normal file
12
core/assets/shaders/fog.frag
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#define HIGHP
|
||||||
|
#define QUANT 0.3
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 color = texture2D(u_texture, v_texCoords.xy);
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0 - floor(color.r / QUANT) * QUANT);
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
private static final Interp landInterp = Interp.pow3;
|
private static final Interp landInterp = Interp.pow3;
|
||||||
|
|
||||||
public final BlockRenderer blocks = new BlockRenderer();
|
public final BlockRenderer blocks = new BlockRenderer();
|
||||||
|
public final FogRenderer fog = new FogRenderer();
|
||||||
public final MinimapRenderer minimap = new MinimapRenderer();
|
public final MinimapRenderer minimap = new MinimapRenderer();
|
||||||
public final OverlayRenderer overlays = new OverlayRenderer();
|
public final OverlayRenderer overlays = new OverlayRenderer();
|
||||||
public final LightRenderer lights = new LightRenderer();
|
public final LightRenderer lights = new LightRenderer();
|
||||||
@@ -342,6 +343,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Draw.draw(Layer.overlayUI, overlays::drawTop);
|
Draw.draw(Layer.overlayUI, overlays::drawTop);
|
||||||
|
if(state.rules.fog) Draw.draw(Layer.fogOfWar, fog::drawFog);
|
||||||
Draw.draw(Layer.space, this::drawLanding);
|
Draw.draw(Layer.space, this::drawLanding);
|
||||||
|
|
||||||
Events.fire(Trigger.drawOver);
|
Events.fire(Trigger.drawOver);
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ public class Rules{
|
|||||||
public ObjectSet<String> researched = new ObjectSet<>();
|
public ObjectSet<String> researched = new ObjectSet<>();
|
||||||
/** Block containing these items as requirements are hidden. */
|
/** Block containing these items as requirements are hidden. */
|
||||||
public ObjectSet<Item> hiddenBuildItems = new ObjectSet<>();
|
public ObjectSet<Item> hiddenBuildItems = new ObjectSet<>();
|
||||||
|
/** HIGHLY UNSTABLE/EXPERIMENTAL. DO NOT USE THIS. */
|
||||||
|
public boolean fog = false;
|
||||||
/** Whether ambient lighting is enabled. */
|
/** Whether ambient lighting is enabled. */
|
||||||
public boolean lighting = false;
|
public boolean lighting = false;
|
||||||
/** Whether enemy lighting is visible.
|
/** Whether enemy lighting is visible.
|
||||||
|
|||||||
173
core/src/mindustry/graphics/FogRenderer.java
Normal file
173
core/src/mindustry/graphics/FogRenderer.java
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
package mindustry.graphics;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.Texture.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.gl.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.io.*;
|
||||||
|
import mindustry.io.SaveFileReader.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
/** Highly experimental fog-of-war renderer. */
|
||||||
|
public class FogRenderer implements CustomChunk{
|
||||||
|
private static final float fogSpeed = 1f;
|
||||||
|
private FrameBuffer buffer = new FrameBuffer();
|
||||||
|
private Seq<Building> events = new Seq<>();
|
||||||
|
private boolean read = false;
|
||||||
|
private Rect rect = new Rect();
|
||||||
|
|
||||||
|
public FogRenderer(){
|
||||||
|
SaveVersion.addCustomChunk("fog", this);
|
||||||
|
|
||||||
|
Events.on(WorldLoadEvent.class, event -> {
|
||||||
|
if(state.rules.fog){
|
||||||
|
buffer.resize(world.width(), world.height());
|
||||||
|
|
||||||
|
events.clear();
|
||||||
|
Groups.build.copy(events);
|
||||||
|
|
||||||
|
//clear
|
||||||
|
if(!read){
|
||||||
|
buffer.begin(Color.black);
|
||||||
|
buffer.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
read = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//draw fog when tile is placed.
|
||||||
|
Events.on(TileChangeEvent.class, event -> {
|
||||||
|
if(state.rules.fog && event.tile.build != null && event.tile.isCenter()){
|
||||||
|
events.add(event.tile.build);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture getTexture(){
|
||||||
|
return buffer.getTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawFog(){
|
||||||
|
//resize if world size changes
|
||||||
|
buffer.resize(world.width(), world.height());
|
||||||
|
|
||||||
|
//set projection to whole map
|
||||||
|
Draw.proj(0, 0, buffer.getWidth() * tilesize, buffer.getHeight() * tilesize);
|
||||||
|
buffer.begin();
|
||||||
|
Gl.blendEquationSeparate(Gl.max, Gl.max);
|
||||||
|
ScissorStack.push(rect.set(1, 1, buffer.getWidth() - 2, buffer.getHeight() - 2));
|
||||||
|
|
||||||
|
Draw.color(Color.white);
|
||||||
|
|
||||||
|
for(var build : events){
|
||||||
|
if(build.team == player.team()){
|
||||||
|
Fill.circle(build.x, build.y, 40f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
events.clear();
|
||||||
|
|
||||||
|
Draw.alpha(fogSpeed * Math.max(Time.delta, 1f));
|
||||||
|
|
||||||
|
//TODO slow and terrible
|
||||||
|
Groups.unit.each(u -> {
|
||||||
|
if(u.team == player.team()){
|
||||||
|
Fill.circle(u.x, u.y, u.type.lightRadius);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buffer.end();
|
||||||
|
buffer.getTexture().setFilter(TextureFilter.linear);
|
||||||
|
Gl.blendEquationSeparate(Gl.funcAdd, Gl.funcAdd);
|
||||||
|
ScissorStack.pop();
|
||||||
|
|
||||||
|
Draw.proj(Core.camera);
|
||||||
|
|
||||||
|
Draw.shader(Shaders.fog);
|
||||||
|
Draw.fbo(buffer.getTexture(), world.width(), world.height(), tilesize);
|
||||||
|
Draw.shader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutput stream) throws IOException{
|
||||||
|
ByteBuffer bytes = Buffers.newUnsafeByteBuffer(buffer.getWidth() * buffer.getHeight() * 4);
|
||||||
|
try{
|
||||||
|
bytes.position(0);
|
||||||
|
buffer.begin();
|
||||||
|
Gl.readPixels(0, 0, buffer.getWidth(), buffer.getHeight(), Gl.rgba, Gl.unsignedByte, bytes);
|
||||||
|
buffer.end();
|
||||||
|
bytes.position(0);
|
||||||
|
stream.writeShort(buffer.getWidth());
|
||||||
|
stream.writeShort(buffer.getHeight());
|
||||||
|
|
||||||
|
//TODO flip?
|
||||||
|
|
||||||
|
int pos = 0, size = bytes.capacity() / 4;
|
||||||
|
while(pos < size){
|
||||||
|
int consecutives = 0;
|
||||||
|
boolean cur = bytes.get(pos * 4) != 0;
|
||||||
|
while(consecutives < 127 && pos < size){
|
||||||
|
boolean next = bytes.get(pos * 4) != 0;
|
||||||
|
if(cur != next){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
consecutives ++;
|
||||||
|
pos ++;
|
||||||
|
}
|
||||||
|
int mask = (cur ? 0b1000_0000 : 0);
|
||||||
|
stream.write(mask | (consecutives));
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
Buffers.disposeUnsafeByteBuffer(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInput stream) throws IOException{
|
||||||
|
short w = stream.readShort(), h = stream.readShort();
|
||||||
|
int pos = 0;
|
||||||
|
int len = w * h;
|
||||||
|
buffer.resize(w, h);
|
||||||
|
buffer.begin(Color.black);
|
||||||
|
Draw.proj(0, 0, buffer.getWidth(), buffer.getHeight());
|
||||||
|
Draw.color();
|
||||||
|
|
||||||
|
while(pos < len){
|
||||||
|
int data = stream.readByte() & 0xff;
|
||||||
|
boolean sign = (data & 0b1000_0000) != 0;
|
||||||
|
int consec = data & 0b0111_1111;
|
||||||
|
|
||||||
|
if(sign){
|
||||||
|
for(int i = 0; i < consec; i++){
|
||||||
|
int x = pos % w, y = pos / w;
|
||||||
|
//TODO this is slow
|
||||||
|
Fill.rect(x + 0.5f, y + 0.5f, 1f, 1f);
|
||||||
|
|
||||||
|
pos ++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pos += consec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.end();
|
||||||
|
Draw.proj(Core.camera);
|
||||||
|
read = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldWrite(){
|
||||||
|
return state.rules.fog && buffer.getTexture() != null && buffer.getWidth() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,6 +92,9 @@ public class Layer{
|
|||||||
//names of players in the game
|
//names of players in the game
|
||||||
playerName = 150,
|
playerName = 150,
|
||||||
|
|
||||||
|
//fog of war effect, if applicable
|
||||||
|
fogOfWar = 155,
|
||||||
|
|
||||||
//space effects, currently only the land and launch effects
|
//space effects, currently only the land and launch effects
|
||||||
space = 160,
|
space = 160,
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.graphics;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.Texture.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
@@ -134,6 +135,23 @@ public class MinimapRenderer{
|
|||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
|
if(state.rules.fog){
|
||||||
|
if(withLabels){
|
||||||
|
float z = zoom;
|
||||||
|
//max zoom out fixes everything, somehow?
|
||||||
|
setZoom(99999f);
|
||||||
|
getRegion();
|
||||||
|
zoom = z;
|
||||||
|
}
|
||||||
|
Draw.shader(Shaders.fog);
|
||||||
|
renderer.fog.getTexture().setFilter(TextureFilter.nearest);
|
||||||
|
//crisp pixels
|
||||||
|
Tmp.tr1.set(renderer.fog.getTexture());
|
||||||
|
Tmp.tr1.set(region.u, 1f - region.v, region.u2, 1f - region.v2);
|
||||||
|
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h);
|
||||||
|
Draw.shader();
|
||||||
|
}
|
||||||
|
|
||||||
//TODO might be useful in the standard minimap too
|
//TODO might be useful in the standard minimap too
|
||||||
if(withLabels){
|
if(withLabels){
|
||||||
drawSpawns(x, y, w, h, scaling);
|
drawSpawns(x, y, w, h, scaling);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class Shaders{
|
|||||||
public static UnitBuildShader build;
|
public static UnitBuildShader build;
|
||||||
public static UnitArmorShader armor;
|
public static UnitArmorShader armor;
|
||||||
public static DarknessShader darkness;
|
public static DarknessShader darkness;
|
||||||
|
public static FogShader fog;
|
||||||
public static LightShader light;
|
public static LightShader light;
|
||||||
public static SurfaceShader water, mud, tar, slag, cryofluid, space, caustics, arkycite;
|
public static SurfaceShader water, mud, tar, slag, cryofluid, space, caustics, arkycite;
|
||||||
public static PlanetShader planet;
|
public static PlanetShader planet;
|
||||||
@@ -41,6 +42,7 @@ public class Shaders{
|
|||||||
shield = null;
|
shield = null;
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
fog = new FogShader();
|
||||||
buildBeam = new BuildBeamShader();
|
buildBeam = new BuildBeamShader();
|
||||||
build = new UnitBuildShader();
|
build = new UnitBuildShader();
|
||||||
armor = new UnitArmorShader();
|
armor = new UnitArmorShader();
|
||||||
@@ -178,6 +180,12 @@ public class Shaders{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FogShader extends LoadShader{
|
||||||
|
public FogShader(){
|
||||||
|
super("fog", "default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @deprecated transition class for mods; use UnitBuildShader instead. */
|
/** @deprecated transition class for mods; use UnitBuildShader instead. */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static class UnitBuild extends UnitBuildShader{}
|
public static class UnitBuild extends UnitBuildShader{}
|
||||||
|
|||||||
@@ -72,10 +72,11 @@ public abstract class SaveFileReader{
|
|||||||
"slag", "molten-slag"
|
"slag", "molten-slag"
|
||||||
);
|
);
|
||||||
|
|
||||||
protected final ReusableByteOutStream byteOutput = new ReusableByteOutStream();
|
protected final ReusableByteOutStream byteOutput = new ReusableByteOutStream(), byteOutput2 = new ReusableByteOutStream();
|
||||||
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput);
|
protected final DataOutputStream dataBytes = new DataOutputStream(byteOutput), dataBytes2 = new DataOutputStream(byteOutput2);
|
||||||
protected final ReusableByteOutStream byteOutputSmall = new ReusableByteOutStream();
|
protected final ReusableByteOutStream byteOutputSmall = new ReusableByteOutStream();
|
||||||
protected final DataOutputStream dataBytesSmall = new DataOutputStream(byteOutputSmall);
|
protected final DataOutputStream dataBytesSmall = new DataOutputStream(byteOutputSmall);
|
||||||
|
protected boolean chunkNested = false;
|
||||||
|
|
||||||
protected int lastRegionLength;
|
protected int lastRegionLength;
|
||||||
protected @Nullable CounterInputStream currCounter;
|
protected @Nullable CounterInputStream currCounter;
|
||||||
@@ -112,23 +113,41 @@ 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 isShort, IORunner<DataOutput> runner) throws IOException{
|
||||||
ReusableByteOutStream dout = isByte ? byteOutputSmall : byteOutput;
|
|
||||||
//reset output position
|
//TODO awful
|
||||||
dout.reset();
|
boolean wasNested = chunkNested;
|
||||||
//write the needed info
|
if(!isShort){
|
||||||
runner.accept(isByte ? dataBytesSmall : dataBytes);
|
chunkNested = true;
|
||||||
int length = dout.size();
|
}
|
||||||
//write length (either int or byte) followed by the output bytes
|
ReusableByteOutStream dout =
|
||||||
if(!isByte){
|
isShort ? byteOutputSmall :
|
||||||
output.writeInt(length);
|
wasNested ? byteOutput2 :
|
||||||
}else{
|
byteOutput;
|
||||||
if(length > 65535){
|
try{
|
||||||
throw new IOException("Byte write length exceeded: " + length + " > 65535");
|
//reset output position
|
||||||
|
dout.reset();
|
||||||
|
//write the needed info
|
||||||
|
runner.accept(
|
||||||
|
isShort ? dataBytesSmall :
|
||||||
|
wasNested ? dataBytes2 :
|
||||||
|
dataBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
int length = dout.size();
|
||||||
|
//write length (either int or byte) followed by the output bytes
|
||||||
|
if(!isShort){
|
||||||
|
output.writeInt(length);
|
||||||
|
}else{
|
||||||
|
if(length > 65535){
|
||||||
|
throw new IOException("Byte write length exceeded: " + length + " > 65535");
|
||||||
|
}
|
||||||
|
output.writeShort(length);
|
||||||
}
|
}
|
||||||
output.writeShort(length);
|
output.write(dout.getBytes(), 0, length);
|
||||||
|
}finally{
|
||||||
|
chunkNested = wasNested;
|
||||||
}
|
}
|
||||||
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{
|
||||||
@@ -148,8 +167,8 @@ public abstract class SaveFileReader{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Skip a chunk completely, discarding the bytes. */
|
/** Skip a chunk completely, discarding the bytes. */
|
||||||
public void skipChunk(DataInput input, boolean isByte) throws IOException{
|
public void skipChunk(DataInput input, boolean isShort) throws IOException{
|
||||||
int length = readChunk(input, isByte, t -> {});
|
int length = readChunk(input, isShort, t -> {});
|
||||||
int skipped = input.skipBytes(length);
|
int skipped = input.skipBytes(length);
|
||||||
if(length != skipped){
|
if(length != skipped){
|
||||||
throw new IOException("Could not skip bytes. Expected length: " + length + "; Actual length: " + skipped);
|
throw new IOException("Could not skip bytes. Expected length: " + length + "; Actual length: " + skipped);
|
||||||
@@ -180,4 +199,10 @@ public abstract class SaveFileReader{
|
|||||||
public interface IORunner<T>{
|
public interface IORunner<T>{
|
||||||
void accept(T stream) throws IOException;
|
void accept(T stream) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface CustomChunk{
|
||||||
|
void write(DataOutput stream) throws IOException;
|
||||||
|
void read(DataInput stream) throws IOException;
|
||||||
|
boolean shouldWrite();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class SaveIO{
|
|||||||
/** Save format header. */
|
/** Save format header. */
|
||||||
public static final byte[] header = {'M', 'S', 'A', 'V'};
|
public static final byte[] header = {'M', 'S', 'A', 'V'};
|
||||||
public static final IntMap<SaveVersion> versions = new IntMap<>();
|
public static final IntMap<SaveVersion> versions = new IntMap<>();
|
||||||
public static final Seq<SaveVersion> versionArray = Seq.with(new Save1(), new Save2(), new Save3(), new Save4(), new Save5(), new Save6());
|
public static final Seq<SaveVersion> versionArray = Seq.with(new Save1(), new Save2(), new Save3(), new Save4(), new Save5(), new Save6(), new Save7());
|
||||||
|
|
||||||
static{
|
static{
|
||||||
for(SaveVersion version : versionArray){
|
for(SaveVersion version : versionArray){
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import java.util.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public abstract class SaveVersion extends SaveFileReader{
|
public abstract class SaveVersion extends SaveFileReader{
|
||||||
public int version;
|
protected static OrderedMap<String, CustomChunk> customChunks = new OrderedMap<>();
|
||||||
|
|
||||||
|
public final int version;
|
||||||
|
|
||||||
//HACK stores the last read build of the save file, valid after read meta call
|
//HACK stores the last read build of the save file, valid after read meta call
|
||||||
protected int lastReadBuild;
|
protected int lastReadBuild;
|
||||||
@@ -31,6 +33,14 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
//if null, fall back to EntityMapping's values
|
//if null, fall back to EntityMapping's values
|
||||||
protected @Nullable Prov[] entityMapping;
|
protected @Nullable Prov[] entityMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a custom save chunk reader/writer by name. This is mostly used for mods that need to save extra data.
|
||||||
|
* @param name a mod-specific, unique name for identifying this chunk. Prefixing is recommended.
|
||||||
|
* */
|
||||||
|
public static void addCustomChunk(String name, CustomChunk chunk){
|
||||||
|
customChunks.put(name, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
public SaveVersion(int version){
|
public SaveVersion(int version){
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
@@ -56,23 +66,49 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void read(DataInputStream stream, CounterInputStream counter, WorldContext context) throws IOException{
|
public void read(DataInputStream stream, CounterInputStream counter, WorldContext context) throws IOException{
|
||||||
region("meta", stream, counter, this::readMeta);
|
region("meta", stream, counter, this::readMeta);
|
||||||
region("content", stream, counter, this::readContentHeader);
|
region("content", stream, counter, this::readContentHeader);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
region("map", stream, counter, in -> readMap(in, context));
|
region("map", stream, counter, in -> readMap(in, context));
|
||||||
region("entities", stream, counter, this::readEntities);
|
region("entities", stream, counter, this::readEntities);
|
||||||
|
region("custom", stream, counter, this::readCustomChunks);
|
||||||
}finally{
|
}finally{
|
||||||
content.setTemporaryMapper(null);
|
content.setTemporaryMapper(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void write(DataOutputStream stream, StringMap extraTags) throws IOException{
|
public void write(DataOutputStream stream, StringMap extraTags) throws IOException{
|
||||||
region("meta", stream, out -> writeMeta(out, extraTags));
|
region("meta", stream, out -> writeMeta(out, extraTags));
|
||||||
region("content", stream, this::writeContentHeader);
|
region("content", stream, this::writeContentHeader);
|
||||||
region("map", stream, this::writeMap);
|
region("map", stream, this::writeMap);
|
||||||
region("entities", stream, this::writeEntities);
|
region("entities", stream, this::writeEntities);
|
||||||
|
region("custom", stream, this::writeCustomChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeCustomChunks(DataOutput stream) throws IOException{
|
||||||
|
var chunks = customChunks.orderedKeys().select(s -> customChunks.get(s).shouldWrite());
|
||||||
|
stream.writeInt(chunks.size);
|
||||||
|
for(var chunkName : chunks){
|
||||||
|
var chunk = customChunks.get(chunkName);
|
||||||
|
stream.writeUTF(chunkName);
|
||||||
|
|
||||||
|
writeChunk(stream, false, chunk::write);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readCustomChunks(DataInput stream) throws IOException{
|
||||||
|
int amount = stream.readInt();
|
||||||
|
for(int i = 0; i < amount; i++){
|
||||||
|
String name = stream.readUTF();
|
||||||
|
var chunk = customChunks.get(name);
|
||||||
|
if(chunk != null){
|
||||||
|
readChunk(stream, false, chunk::read);
|
||||||
|
}else{
|
||||||
|
skipChunk(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
public void writeMeta(DataOutput stream, StringMap tags) throws IOException{
|
||||||
|
|||||||
@@ -1,10 +1,31 @@
|
|||||||
package mindustry.io.versions;
|
package mindustry.io.versions;
|
||||||
|
|
||||||
|
import arc.util.io.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
|
/** This version does not read custom chunk data. */
|
||||||
public class Save6 extends SaveVersion{
|
public class Save6 extends SaveVersion{
|
||||||
|
|
||||||
public Save6(){
|
public Save6(){
|
||||||
super(6);
|
super(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream stream, CounterInputStream counter, WorldContext context) throws IOException{
|
||||||
|
region("meta", stream, counter, this::readMeta);
|
||||||
|
region("content", stream, counter, this::readContentHeader);
|
||||||
|
|
||||||
|
try{
|
||||||
|
region("map", stream, counter, in -> readMap(in, context));
|
||||||
|
region("entities", stream, counter, this::readEntities);
|
||||||
|
}finally{
|
||||||
|
content.setTemporaryMapper(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
core/src/mindustry/io/versions/Save7.java
Normal file
10
core/src/mindustry/io/versions/Save7.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package mindustry.io.versions;
|
||||||
|
|
||||||
|
import mindustry.io.*;
|
||||||
|
|
||||||
|
public class Save7 extends SaveVersion{
|
||||||
|
|
||||||
|
public Save7(){
|
||||||
|
super(7);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,4 +24,4 @@ android.useAndroidX=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=243eb136dc
|
archash=502eb9934e
|
||||||
|
|||||||
Reference in New Issue
Block a user