Fog building hiding
This commit is contained in:
@@ -70,6 +70,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
transient float enabledControlTime;
|
transient float enabledControlTime;
|
||||||
transient String lastAccessed;
|
transient String lastAccessed;
|
||||||
transient boolean wasDamaged; //used only by the indexer
|
transient boolean wasDamaged; //used only by the indexer
|
||||||
|
transient boolean wasVisible; //used only by the block renderer when fog is on
|
||||||
transient float visualLiquid;
|
transient float visualLiquid;
|
||||||
|
|
||||||
@Nullable PowerModule power;
|
@Nullable PowerModule power;
|
||||||
@@ -1775,6 +1776,24 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Replace
|
||||||
|
@Override
|
||||||
|
public boolean inFogTo(Team viewer){
|
||||||
|
if(team == viewer || !state.rules.fog) return false;
|
||||||
|
|
||||||
|
int size = block.size, of = block.sizeOffset, tx = tile.x, ty = tile.y;
|
||||||
|
|
||||||
|
for(int x = 0; x < size; x++){
|
||||||
|
for(int y = 0; y < size; y++){
|
||||||
|
if(fogControl.isVisibleTile(viewer, tx + x + of, ty + y + of)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
if(sound != null){
|
if(sound != null){
|
||||||
|
|||||||
@@ -320,7 +320,8 @@ public class FogControl implements CustomChunk{
|
|||||||
data.write.clear();
|
data.write.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
circle(data.write, x, y, rad);
|
//radius is always +1 to keep up with visuals
|
||||||
|
circle(data.write, x, y, rad + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dynamicEvents.clear();
|
dynamicEvents.clear();
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ public class Rules{
|
|||||||
public ObjectSet<Item> hiddenBuildItems = new ObjectSet<>();
|
public ObjectSet<Item> hiddenBuildItems = new ObjectSet<>();
|
||||||
/** HIGHLY UNSTABLE/EXPERIMENTAL. DO NOT USE THIS. */
|
/** HIGHLY UNSTABLE/EXPERIMENTAL. DO NOT USE THIS. */
|
||||||
public boolean fog = false;
|
public boolean fog = false;
|
||||||
|
/** Color for static, undiscovered fog of war areas. */
|
||||||
|
public Color staticColor = new Color(0f, 0f, 0f, 1f);
|
||||||
|
/** Color for discovered but un-monitored fog of war areas. */
|
||||||
|
public Color dynamicColor = new Color(0f, 0f, 0f, 0.5f);
|
||||||
/** 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.
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ import arc.math.*;
|
|||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -81,7 +83,11 @@ public class BlockRenderer{
|
|||||||
updateFloors.add(new UpdateRenderState(tile, tile.floor()));
|
updateFloors.add(new UpdateRenderState(tile, tile.floor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tile.block().hasShadow){
|
if(tile.build != null && (tile.team() == player.team() || !state.rules.fog)){
|
||||||
|
tile.build.wasVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tile.block().hasShadow && (tile.build == null || tile.build.wasVisible)){
|
||||||
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
|
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +105,14 @@ public class BlockRenderer{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Events.on(TileChangeEvent.class, event -> {
|
Events.on(TileChangeEvent.class, event -> {
|
||||||
shadowEvents.add(event.tile);
|
boolean visible = event.tile.build == null || event.tile.build.inFogTo(Vars.player.team());
|
||||||
|
if(event.tile.build != null){
|
||||||
|
event.tile.build.wasVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(visible){
|
||||||
|
shadowEvents.add(event.tile);
|
||||||
|
}
|
||||||
|
|
||||||
int avgx = (int)(camera.position.x / tilesize);
|
int avgx = (int)(camera.position.x / tilesize);
|
||||||
int avgy = (int)(camera.position.y / tilesize);
|
int avgy = (int)(camera.position.y / tilesize);
|
||||||
@@ -265,7 +278,7 @@ public class BlockRenderer{
|
|||||||
|
|
||||||
for(Tile tile : shadowEvents){
|
for(Tile tile : shadowEvents){
|
||||||
//draw white/shadow color depending on blend
|
//draw white/shadow color depending on blend
|
||||||
Draw.color(!tile.block().hasShadow ? Color.white : blendShadowColor);
|
Draw.color((!tile.block().hasShadow || (state.rules.fog && tile.build != null && !tile.build.wasVisible)) ? Color.white : blendShadowColor);
|
||||||
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
|
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +384,7 @@ public class BlockRenderer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawBlocks(){
|
public void drawBlocks(){
|
||||||
|
Team pteam = player.team();
|
||||||
|
|
||||||
drawDestroyed();
|
drawDestroyed();
|
||||||
|
|
||||||
@@ -382,7 +396,9 @@ public class BlockRenderer{
|
|||||||
|
|
||||||
Draw.z(Layer.block);
|
Draw.z(Layer.block);
|
||||||
|
|
||||||
if(block != Blocks.air){
|
boolean visible = (build == null || !build.inFogTo(pteam)/* || build.wasVisible*/);
|
||||||
|
|
||||||
|
if(block != Blocks.air && visible){
|
||||||
block.drawBase(tile);
|
block.drawBase(tile);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
Draw.z(Layer.block);
|
Draw.z(Layer.block);
|
||||||
@@ -394,6 +410,8 @@ public class BlockRenderer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(build != null){
|
if(build != null){
|
||||||
|
if(!build.wasVisible) updateShadow(build);
|
||||||
|
build.wasVisible = true;
|
||||||
|
|
||||||
if(build.damaged()){
|
if(build.damaged()){
|
||||||
Draw.z(Layer.blockCracks);
|
Draw.z(Layer.blockCracks);
|
||||||
@@ -411,6 +429,11 @@ public class BlockRenderer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
}else if(!visible){
|
||||||
|
//TODO here is the question: should buildings you lost sight of remain rendered? if so, how should this information be stored?
|
||||||
|
//comment lines below for buggy persistence
|
||||||
|
if(build.wasVisible) updateShadow(build);
|
||||||
|
build.wasVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,6 +466,16 @@ public class BlockRenderer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateShadow(Building build){
|
||||||
|
int size = build.block.size, of = build.block.sizeOffset, tx = build.tile.x, ty = build.tile.y;
|
||||||
|
|
||||||
|
for(int x = 0; x < size; x++){
|
||||||
|
for(int y = 0; y < size; y++){
|
||||||
|
shadowEvents.add(world.tile(x + tx + of, y + ty + of));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class BlockQuadtree extends QuadTree<Tile>{
|
static class BlockQuadtree extends QuadTree<Tile>{
|
||||||
|
|
||||||
public BlockQuadtree(Rect bounds){
|
public BlockQuadtree(Rect bounds){
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ public class EnvRenderers{
|
|||||||
tex.setWrap(TextureWrap.repeat);
|
tex.setWrap(TextureWrap.repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw.z(Layer.weather - 1);
|
//TODO layer looks better? should not be conditional
|
||||||
|
Draw.z(state.rules.fog ? Layer.fogOfWar + 1 : Layer.weather - 1);
|
||||||
Weather.drawNoiseLayers(tex, Color.scarlet, 1000f, 0.23f, 0.4f, 1f, 1f, 0f,
|
Weather.drawNoiseLayers(tex, Color.scarlet, 1000f, 0.23f, 0.4f, 1f, 1f, 0f,
|
||||||
4, -1.3f, 0.7f, 0.8f, 0.9f);
|
4, -1.3f, 0.7f, 0.8f, 0.9f);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
/** Highly experimental fog-of-war renderer. */
|
/** Highly experimental fog-of-war renderer. */
|
||||||
public class FogRenderer{
|
public class FogRenderer{
|
||||||
public static final Color
|
|
||||||
staticColor = new Color(0f, 0f, 0f, 1f),
|
|
||||||
dynamicColor = new Color(0f, 0f, 0f, 0.5f);
|
|
||||||
private FrameBuffer staticFog = new FrameBuffer(), dynamicFog = new FrameBuffer();
|
private FrameBuffer staticFog = new FrameBuffer(), dynamicFog = new FrameBuffer();
|
||||||
private LongSeq events = new LongSeq();
|
private LongSeq events = new LongSeq();
|
||||||
private Rect rect = new Rect();
|
private Rect rect = new Rect();
|
||||||
@@ -114,17 +111,18 @@ public class FogRenderer{
|
|||||||
dynamicFog.getTexture().setFilter(TextureFilter.linear);
|
dynamicFog.getTexture().setFilter(TextureFilter.linear);
|
||||||
|
|
||||||
Draw.shader(Shaders.fog);
|
Draw.shader(Shaders.fog);
|
||||||
Draw.color(dynamicColor);
|
Draw.color(state.rules.dynamicColor);
|
||||||
Draw.fbo(dynamicFog.getTexture(), world.width(), world.height(), tilesize);
|
Draw.fbo(dynamicFog.getTexture(), world.width(), world.height(), tilesize);
|
||||||
Draw.color(staticColor);
|
Draw.color(state.rules.staticColor);
|
||||||
Draw.fbo(staticFog.getTexture(), world.width(), world.height(), tilesize);
|
Draw.fbo(staticFog.getTexture(), world.width(), world.height(), tilesize);
|
||||||
Draw.shader();
|
Draw.shader();
|
||||||
}
|
}
|
||||||
|
|
||||||
void poly(Rect check, float x, float y, float rad){
|
void poly(Rect check, float x, float y, float rad){
|
||||||
if(check.overlaps(x - rad, y - rad, rad * 2f, rad * 2f)){
|
//todo clipping messes up the minimap
|
||||||
Fill.poly(x, y, 20, rad);
|
//if(check.overlaps(x - rad, y - rad, rad * 2f, rad * 2f)){
|
||||||
}
|
Fill.poly(x, y, 20, rad);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderEvent(long e){
|
void renderEvent(long e){
|
||||||
|
|||||||
@@ -155,11 +155,12 @@ public class MinimapRenderer{
|
|||||||
Tmp.tr1.set(dynamicTex);
|
Tmp.tr1.set(dynamicTex);
|
||||||
Tmp.tr1.set(region.u, 1f - region.v, region.u2, 1f - region.v2);
|
Tmp.tr1.set(region.u, 1f - region.v, region.u2, 1f - region.v2);
|
||||||
|
|
||||||
Draw.color(FogRenderer.dynamicColor);
|
Draw.color(state.rules.dynamicColor);
|
||||||
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h);
|
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h);
|
||||||
|
|
||||||
Tmp.tr1.texture = staticTex;
|
Tmp.tr1.texture = staticTex;
|
||||||
Draw.color(FogRenderer.staticColor);
|
//must be black to fit with borders
|
||||||
|
Draw.color(0f, 0f, 0f, state.rules.staticColor.a);
|
||||||
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h);
|
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h);
|
||||||
|
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ public class UnitType extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(fogRadius < 0){
|
if(fogRadius < 0){
|
||||||
fogRadius = Math.max(lightRadius * 2.5f, 1f) / 8f;
|
fogRadius = Math.max(lightRadius * 3.1f, 1f) / 8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(weapons.isEmpty()){
|
if(weapons.isEmpty()){
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ public class Block extends UnlockableContent implements Senseable{
|
|||||||
public int size = 1;
|
public int size = 1;
|
||||||
/** multiblock offset */
|
/** multiblock offset */
|
||||||
public float offset = 0f;
|
public float offset = 0f;
|
||||||
|
/** offset for iteration (internal use only) */
|
||||||
|
public int sizeOffset = 0;
|
||||||
/** Clipping size of this block. Should be as large as the block will draw. */
|
/** Clipping size of this block. Should be as large as the block will draw. */
|
||||||
public float clipSize = -1f;
|
public float clipSize = -1f;
|
||||||
/** When placeRangeCheck is enabled, this is the range checked for enemy blocks. */
|
/** When placeRangeCheck is enabled, this is the range checked for enemy blocks. */
|
||||||
@@ -1076,6 +1078,7 @@ public class Block extends UnlockableContent implements Senseable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset = ((size + 1) % 2) * tilesize / 2f;
|
offset = ((size + 1) % 2) * tilesize / 2f;
|
||||||
|
sizeOffset = -((size - 1) / 2);
|
||||||
|
|
||||||
if(requirements.length > 0){
|
if(requirements.length > 0){
|
||||||
buildCost = 0f;
|
buildCost = 0f;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import arc.math.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -110,6 +111,12 @@ public class BaseShield extends Block{
|
|||||||
drawShield();
|
drawShield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//always visible due to their shield nature
|
||||||
|
@Override
|
||||||
|
public boolean inFogTo(Team viewer){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void drawShield(){
|
public void drawShield(){
|
||||||
if(!broken){
|
if(!broken){
|
||||||
float radius = radius();
|
float radius = radius();
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import arc.util.io.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.logic.*;
|
import mindustry.logic.*;
|
||||||
@@ -140,6 +141,11 @@ public class ForceProjector extends Block{
|
|||||||
radscl = warmup = 0f;
|
radscl = warmup = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean inFogTo(Team viewer){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
boolean phaseValid = itemConsumer != null && itemConsumer.valid(this);
|
boolean phaseValid = itemConsumer != null && itemConsumer.valid(this);
|
||||||
|
|||||||
Reference in New Issue
Block a user