Implemented fog saving
This commit is contained in:
@@ -29,7 +29,10 @@ public class Mindustry extends ModuleCore{
|
||||
module(ui = new UI());
|
||||
module(netServer = new NetServer());
|
||||
module(netClient = new NetClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(){
|
||||
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 Throwable error;
|
||||
//private Input gdxInput;
|
||||
|
||||
public Control(){
|
||||
|
||||
@@ -68,8 +67,6 @@ public class Control extends Module{
|
||||
|
||||
db.load();
|
||||
|
||||
//gdxInput = Gdx.input;
|
||||
|
||||
Sounds.setFalloff(9000f);
|
||||
Sounds.setPlayer((sound, volume) -> {
|
||||
long time = TimeUtils.millis();
|
||||
|
||||
@@ -67,21 +67,21 @@ public class UI extends SceneModule{
|
||||
|
||||
public UI(){
|
||||
Dialog.setShowAction(() -> sequence(
|
||||
alpha(0f),
|
||||
originCenter(),
|
||||
moveToAligned(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Align.center),
|
||||
scaleTo(0.0f, 1f),
|
||||
parallel(
|
||||
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
|
||||
fadeIn(0.1f, Interpolation.fade)
|
||||
)
|
||||
alpha(0f),
|
||||
originCenter(),
|
||||
moveToAligned(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Align.center),
|
||||
scaleTo(0.0f, 1f),
|
||||
parallel(
|
||||
scaleTo(1f, 1f, 0.1f, Interpolation.fade),
|
||||
fadeIn(0.1f, Interpolation.fade)
|
||||
)
|
||||
));
|
||||
|
||||
Dialog.setHideAction(() -> sequence(
|
||||
parallel(
|
||||
scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade),
|
||||
fadeOut(0.1f, Interpolation.fade)
|
||||
)
|
||||
parallel(
|
||||
scaleTo(0.01f, 0.01f, 0.1f, Interpolation.fade),
|
||||
fadeOut(0.1f, Interpolation.fade)
|
||||
)
|
||||
));
|
||||
|
||||
TooltipManager.getInstance().animations = false;
|
||||
@@ -179,6 +179,7 @@ public class UI extends SceneModule{
|
||||
listfrag.build(group);
|
||||
debugfrag.build(group);
|
||||
loadfrag.build(group);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -495,7 +495,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
||||
.size(size).get().setAlignment(Align.center, Align.center);
|
||||
|
||||
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);
|
||||
|
||||
}).margin(0).left().growY();
|
||||
|
||||
@@ -75,8 +75,7 @@ public class Saves{
|
||||
|
||||
Timers.run(2f, () -> {
|
||||
try{
|
||||
SaveIO.saveToSlot(current.index);
|
||||
current.meta = SaveIO.getData(current.index);
|
||||
current.save();
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -108,10 +107,7 @@ public class Saves{
|
||||
slot.setName(name);
|
||||
saves.add(slot);
|
||||
saveMap.put(slot.index, slot);
|
||||
SaveIO.saveToSlot(slot.index);
|
||||
slot.meta = SaveIO.getData(slot.index);
|
||||
current = slot;
|
||||
|
||||
slot.save();
|
||||
saveSlots();
|
||||
return slot;
|
||||
}
|
||||
@@ -162,9 +158,18 @@ public class Saves{
|
||||
}
|
||||
|
||||
public void save(){
|
||||
SaveIO.saveToSlot(index);
|
||||
meta = SaveIO.getData(index);
|
||||
current = this;
|
||||
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);
|
||||
meta = SaveIO.getData(index);
|
||||
current = this;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isHidden(){
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.anuke.mindustry.graphics;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
@@ -32,10 +33,11 @@ public class FogRenderer implements Disposable{
|
||||
|
||||
private TextureRegion region = new TextureRegion();
|
||||
private FrameBuffer buffer;
|
||||
private ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(4);
|
||||
private ByteBuffer pixelBuffer;
|
||||
private Array<Tile> changeQueue = new Array<>();
|
||||
private int padding;
|
||||
private Rectangle rect = new Rectangle();
|
||||
private boolean dirty;
|
||||
|
||||
public FogRenderer(){
|
||||
Events.on(WorldLoadGraphicsEvent.class, () -> {
|
||||
@@ -51,15 +53,8 @@ public class FogRenderer implements Disposable{
|
||||
Graphics.clear(0, 0, 0, 1f);
|
||||
buffer.end();
|
||||
|
||||
for(int x = 0; x < world.width(); x++){
|
||||
for(int y = 0; y < world.height(); y++){
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile.getTeam() == players[0].getTeam() && tile.block().synthetic() && tile.block().viewRange > 0){
|
||||
changeQueue.add(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
pixelBuffer = ByteBuffer.allocateDirect(world.width() * world.height() * 3);
|
||||
dirty = true;
|
||||
});
|
||||
|
||||
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(){
|
||||
return padding;
|
||||
}
|
||||
@@ -94,12 +108,6 @@ public class FogRenderer implements Disposable{
|
||||
|
||||
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),
|
||||
(world.width() + shadowPadding*2) ,
|
||||
(world.height() + shadowPadding*2)));
|
||||
@@ -118,6 +126,16 @@ public class FogRenderer implements Disposable{
|
||||
|
||||
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);
|
||||
Graphics.end();
|
||||
buffer.end();
|
||||
|
||||
@@ -135,6 +135,18 @@ public class Save16 extends SaveFileVersion{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -223,5 +235,27 @@ public class Save16 extends SaveFileVersion{
|
||||
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
|
||||
stream.writeByte(state.teams.getTeams().size);
|
||||
for(TeamData data : state.teams.getTeams()){
|
||||
@@ -215,6 +237,18 @@ public class NetworkIO{
|
||||
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();
|
||||
state.teams = new TeamInfo();
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
private byte team;
|
||||
/** Tile elevation. -1 means slope.*/
|
||||
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){
|
||||
this.x = (short) x;
|
||||
@@ -67,6 +69,10 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
public boolean discovered(){
|
||||
return visibility > 0;
|
||||
}
|
||||
|
||||
public int packedPosition(){
|
||||
return x + y * world.width();
|
||||
}
|
||||
@@ -172,6 +178,14 @@ public class Tile implements PosTrait, TargetTrait{
|
||||
this.floor = type;
|
||||
}
|
||||
|
||||
public byte getVisibility(){
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public void setVisibility(byte visibility){
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public byte getRotation(){
|
||||
return rotation;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user