Implemented fog saving
This commit is contained in:
@@ -29,7 +29,10 @@ public class Mindustry extends ModuleCore{
|
|||||||
module(ui = new UI());
|
module(ui = new UI());
|
||||||
module(netServer = new NetServer());
|
module(netServer = new NetServer());
|
||||||
module(netClient = new NetClient());
|
module(netClient = new NetClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(){
|
||||||
Log.info("Time to load [total]: {0}", Timers.elapsed());
|
Log.info("Time to load [total]: {0}", Timers.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public class Control extends Module{
|
|||||||
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
|
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
|
||||||
|
|
||||||
private Throwable error;
|
private Throwable error;
|
||||||
//private Input gdxInput;
|
|
||||||
|
|
||||||
public Control(){
|
public Control(){
|
||||||
|
|
||||||
@@ -68,8 +67,6 @@ public class Control extends Module{
|
|||||||
|
|
||||||
db.load();
|
db.load();
|
||||||
|
|
||||||
//gdxInput = Gdx.input;
|
|
||||||
|
|
||||||
Sounds.setFalloff(9000f);
|
Sounds.setFalloff(9000f);
|
||||||
Sounds.setPlayer((sound, volume) -> {
|
Sounds.setPlayer((sound, volume) -> {
|
||||||
long time = TimeUtils.millis();
|
long time = TimeUtils.millis();
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public class UI extends SceneModule{
|
|||||||
listfrag.build(group);
|
listfrag.build(group);
|
||||||
debugfrag.build(group);
|
debugfrag.build(group);
|
||||||
loadfrag.build(group);
|
loadfrag.build(group);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
.size(size).get().setAlignment(Align.center, Align.center);
|
.size(size).get().setAlignment(Align.center, Align.center);
|
||||||
|
|
||||||
t.addImageButton("icon-arrow-right", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
|
t.addImageButton("icon-arrow-right", 16 * 2f, () -> editor.setDrawElevation(editor.getDrawElevation() + 1))
|
||||||
.disabled(b -> editor.getDrawElevation() >= 127).size(size);
|
.disabled(b -> editor.getDrawElevation() >= 63).size(size);
|
||||||
}).colspan(3).height(size).padTop(-5).width(size * 3f);
|
}).colspan(3).height(size).padTop(-5).width(size * 3f);
|
||||||
|
|
||||||
}).margin(0).left().growY();
|
}).margin(0).left().growY();
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ public class Saves{
|
|||||||
|
|
||||||
Timers.run(2f, () -> {
|
Timers.run(2f, () -> {
|
||||||
try{
|
try{
|
||||||
SaveIO.saveToSlot(current.index);
|
current.save();
|
||||||
current.meta = SaveIO.getData(current.index);
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -108,10 +107,7 @@ public class Saves{
|
|||||||
slot.setName(name);
|
slot.setName(name);
|
||||||
saves.add(slot);
|
saves.add(slot);
|
||||||
saveMap.put(slot.index, slot);
|
saveMap.put(slot.index, slot);
|
||||||
SaveIO.saveToSlot(slot.index);
|
slot.save();
|
||||||
slot.meta = SaveIO.getData(slot.index);
|
|
||||||
current = slot;
|
|
||||||
|
|
||||||
saveSlots();
|
saveSlots();
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
@@ -162,9 +158,18 @@ public class Saves{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void save(){
|
public void save(){
|
||||||
|
threads.runGraphics(() -> {
|
||||||
|
//Renderer fog needs to be written on graphics thread, but save() can run on logic thread
|
||||||
|
//thus, runGraphics is required here
|
||||||
|
renderer.fog().writeFog();
|
||||||
|
|
||||||
|
//save on the logic thread
|
||||||
|
threads.run(() -> {
|
||||||
SaveIO.saveToSlot(index);
|
SaveIO.saveToSlot(index);
|
||||||
meta = SaveIO.getData(index);
|
meta = SaveIO.getData(index);
|
||||||
current = this;
|
current = this;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHidden(){
|
public boolean isHidden(){
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.graphics;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
import com.badlogic.gdx.graphics.Pixmap.Format;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
@@ -32,10 +33,11 @@ public class FogRenderer implements Disposable{
|
|||||||
|
|
||||||
private TextureRegion region = new TextureRegion();
|
private TextureRegion region = new TextureRegion();
|
||||||
private FrameBuffer buffer;
|
private FrameBuffer buffer;
|
||||||
private ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(4);
|
private ByteBuffer pixelBuffer;
|
||||||
private Array<Tile> changeQueue = new Array<>();
|
private Array<Tile> changeQueue = new Array<>();
|
||||||
private int padding;
|
private int padding;
|
||||||
private Rectangle rect = new Rectangle();
|
private Rectangle rect = new Rectangle();
|
||||||
|
private boolean dirty;
|
||||||
|
|
||||||
public FogRenderer(){
|
public FogRenderer(){
|
||||||
Events.on(WorldLoadGraphicsEvent.class, () -> {
|
Events.on(WorldLoadGraphicsEvent.class, () -> {
|
||||||
@@ -51,15 +53,8 @@ public class FogRenderer implements Disposable{
|
|||||||
Graphics.clear(0, 0, 0, 1f);
|
Graphics.clear(0, 0, 0, 1f);
|
||||||
buffer.end();
|
buffer.end();
|
||||||
|
|
||||||
for(int x = 0; x < world.width(); x++){
|
pixelBuffer = ByteBuffer.allocateDirect(world.width() * world.height() * 3);
|
||||||
for(int y = 0; y < world.height(); y++){
|
dirty = true;
|
||||||
Tile tile = world.tile(x, y);
|
|
||||||
|
|
||||||
if(tile.getTeam() == players[0].getTeam() && tile.block().synthetic() && tile.block().viewRange > 0){
|
|
||||||
changeQueue.add(tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.on(TileChangeEvent.class, tile -> threads.runGraphics(() -> {
|
Events.on(TileChangeEvent.class, tile -> threads.runGraphics(() -> {
|
||||||
@@ -69,6 +64,25 @@ public class FogRenderer implements Disposable{
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeFog(){
|
||||||
|
if(buffer == null) return;
|
||||||
|
|
||||||
|
buffer.begin();
|
||||||
|
pixelBuffer.position(0);
|
||||||
|
Gdx.gl.glPixelStorei(GL20.GL_PACK_ALIGNMENT, 1);
|
||||||
|
Gdx.gl.glReadPixels(padding, padding, world.width(), world.height(), GL20.GL_RGB, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
|
||||||
|
|
||||||
|
pixelBuffer.position(0);
|
||||||
|
for(int i = 0; i < world.width() * world.height(); i++){
|
||||||
|
byte r = pixelBuffer.get();
|
||||||
|
if(r != 0){
|
||||||
|
world.tile(i).setVisibility((byte)1);
|
||||||
|
}
|
||||||
|
pixelBuffer.position(pixelBuffer.position() + 2);
|
||||||
|
}
|
||||||
|
buffer.end();
|
||||||
|
}
|
||||||
|
|
||||||
public int getPadding(){
|
public int getPadding(){
|
||||||
return padding;
|
return padding;
|
||||||
}
|
}
|
||||||
@@ -94,12 +108,6 @@ public class FogRenderer implements Disposable{
|
|||||||
|
|
||||||
buffer.begin();
|
buffer.begin();
|
||||||
|
|
||||||
//TODO use this for per-tile visibility to show/hide units
|
|
||||||
//pixelBuffer.position(0);
|
|
||||||
//Gdx.gl.glPixelStorei(GL20.GL_PACK_ALIGNMENT, 1);
|
|
||||||
//Gdx.gl.glReadPixels(world.width()/2, world.height()/2 + 20, 1, 1, GL20.GL_RGB, GL20.GL_UNSIGNED_BYTE, pixelBuffer);
|
|
||||||
//Log.info(pixelBuffer.get(0));
|
|
||||||
|
|
||||||
boolean pop = ScissorStack.pushScissors(rect.set((padding-shadowPadding), (padding-shadowPadding),
|
boolean pop = ScissorStack.pushScissors(rect.set((padding-shadowPadding), (padding-shadowPadding),
|
||||||
(world.width() + shadowPadding*2) ,
|
(world.width() + shadowPadding*2) ,
|
||||||
(world.height() + shadowPadding*2)));
|
(world.height() + shadowPadding*2)));
|
||||||
@@ -118,6 +126,16 @@ public class FogRenderer implements Disposable{
|
|||||||
|
|
||||||
changeQueue.clear();
|
changeQueue.clear();
|
||||||
|
|
||||||
|
if(dirty){
|
||||||
|
for(int i = 0; i < world.width() * world.height(); i++){
|
||||||
|
Tile tile = world.tile(i);
|
||||||
|
if(tile.discovered()){
|
||||||
|
Fill.rect(tile.worldx(), tile.worldy(), tilesize, tilesize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
EntityDraw.setClip(true);
|
EntityDraw.setClip(true);
|
||||||
Graphics.end();
|
Graphics.end();
|
||||||
buffer.end();
|
buffer.end();
|
||||||
|
|||||||
@@ -135,6 +135,18 @@ public class Save16 extends SaveFileVersion{
|
|||||||
tiles[x][y] = tile;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
world.endMapLoad();
|
world.endMapLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,5 +235,27 @@ public class Save16 extends SaveFileVersion{
|
|||||||
i += 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,28 @@ public class NetworkIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
//write team data
|
//write team data
|
||||||
stream.writeByte(state.teams.getTeams().size);
|
stream.writeByte(state.teams.getTeams().size);
|
||||||
for(TeamData data : state.teams.getTeams()){
|
for(TeamData data : state.teams.getTeams()){
|
||||||
@@ -215,6 +237,18 @@ public class NetworkIO{
|
|||||||
tiles[x][y] = tile;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
player.reset();
|
player.reset();
|
||||||
state.teams = new TeamInfo();
|
state.teams = new TeamInfo();
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ public class Tile implements PosTrait, TargetTrait{
|
|||||||
private byte team;
|
private byte team;
|
||||||
/** Tile elevation. -1 means slope.*/
|
/** Tile elevation. -1 means slope.*/
|
||||||
private byte elevation;
|
private byte elevation;
|
||||||
|
/** Visibility status: 3 states, but saved as a single bit. 0 = unexplored, 1 = visited, 2 = currently visible (saved as 1)*/
|
||||||
|
private byte visibility;
|
||||||
|
|
||||||
public Tile(int x, int y){
|
public Tile(int x, int y){
|
||||||
this.x = (short) x;
|
this.x = (short) x;
|
||||||
@@ -67,6 +69,10 @@ public class Tile implements PosTrait, TargetTrait{
|
|||||||
this.team = team;
|
this.team = team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean discovered(){
|
||||||
|
return visibility > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public int packedPosition(){
|
public int packedPosition(){
|
||||||
return x + y * world.width();
|
return x + y * world.width();
|
||||||
}
|
}
|
||||||
@@ -172,6 +178,14 @@ public class Tile implements PosTrait, TargetTrait{
|
|||||||
this.floor = type;
|
this.floor = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getVisibility(){
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisibility(byte visibility){
|
||||||
|
this.visibility = visibility;
|
||||||
|
}
|
||||||
|
|
||||||
public byte getRotation(){
|
public byte getRotation(){
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ public class DesktopPlatform extends Platform{
|
|||||||
@Override
|
@Override
|
||||||
public boolean isDebug(){
|
public boolean isDebug(){
|
||||||
//honestly I'm just putting this ridiculous """anti-debug""" mess here to see if anyone bothers solving it without editing source
|
//honestly I'm just putting this ridiculous """anti-debug""" mess here to see if anyone bothers solving it without editing source
|
||||||
return args.length > 0 && args[0].equals("-debug_" + getUUID().hashCode() + "_"
|
return args.length > 0 && args[0].equals(("-debug_" + getUUID().hashCode() + "_"
|
||||||
+ " " + System.getProperty("os.arch") + "nice" + (int)(Math.sin(System.getProperty("user.dir").hashCode()) * 100) + Thread.currentThread().getStackTrace()[1].toString()) && new File("../../desktop/build/").exists();
|
+ " " + System.getProperty("os.arch") + "nice" + (int)(Math.sin(System.getProperty("user.dir").hashCode()) * 100) + Thread.currentThread().getStackTrace()[1].toString()).hashCode() + "") && new File("../../desktop/build/").exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user