Misc fog improvements

This commit is contained in:
Anuken
2022-03-01 10:24:20 -05:00
parent 8b51ba17ec
commit 97cbc3d345
23 changed files with 214 additions and 45 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

View File

@@ -551,3 +551,4 @@
63152=tank-reconstructor|block-tank-reconstructor-ui 63152=tank-reconstructor|block-tank-reconstructor-ui
63151=mech-reconstructor|block-mech-reconstructor-ui 63151=mech-reconstructor|block-mech-reconstructor-ui
63150=ship-reconstructor|block-ship-reconstructor-ui 63150=ship-reconstructor|block-ship-reconstructor-ui
63149=radar|block-radar-ui

Binary file not shown.

View File

@@ -85,6 +85,7 @@ public class Blocks{
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
//defense - erekir //defense - erekir
radar,
buildTower, buildTower,
regenProjector, barrierProjector, regenProjector, barrierProjector,
//campaign only //campaign only
@@ -1693,6 +1694,14 @@ public class Blocks{
tendrils = 4; tendrils = 4;
}}; }};
radar = new Radar("radar"){{
requirements(Category.effect, BuildVisibility.fogOnly, with(Items.silicon, 30, Items.graphite, 30));
outlineColor = Color.valueOf("4a4b53");
fogRadius = 27;
consumePower(0.2f);
}};
buildTower = new BuildTurret("build-tower"){{ buildTower = new BuildTurret("build-tower"){{
requirements(Category.effect, with(Items.silicon, 80, Items.carbide, 30, Items.oxide, 40, Items.thorium, 30)); requirements(Category.effect, with(Items.silicon, 80, Items.carbide, 30, Items.oxide, 40, Items.thorium, 30));
outlineColor = Pal.darkOutline; outlineColor = Pal.darkOutline;
@@ -3247,7 +3256,6 @@ public class Blocks{
coolantMultiplier = 6f; coolantMultiplier = 6f;
unitFilter = u -> !u.spawnedByCore;
shootShake = 1f; shootShake = 1f;
ammoPerShot = 5; ammoPerShot = 5;
draw = new DrawTurret("reinforced-"); draw = new DrawTurret("reinforced-");
@@ -3488,8 +3496,6 @@ public class Blocks{
}}); }});
}}; }};
unitFilter = u -> !u.spawnedByCore;
shoot = new ShootAlternate(){{ shoot = new ShootAlternate(){{
spread = 4.7f; spread = 4.7f;
shots = 4; shots = 4;

View File

@@ -3396,6 +3396,9 @@ public class UnitTypes{
hitSize = 9f; hitSize = 9f;
engineSize = 0; engineSize = 0;
fogRadius = 0f;
targetable = false;
setEnginesMirror( setEnginesMirror(
new UnitEngine(21 / 4f, 19 / 4f, 2.2f, 45f), new UnitEngine(21 / 4f, 19 / 4f, 2.2f, 45f),
new UnitEngine(23 / 4f, -22 / 4f, 2.2f, 315f) new UnitEngine(23 / 4f, -22 / 4f, 2.2f, 315f)
@@ -3452,6 +3455,9 @@ public class UnitTypes{
armor = 2f; armor = 2f;
hitSize = 11f; hitSize = 11f;
fogRadius = 0f;
targetable = false;
engineOffset = 7.2f; engineOffset = 7.2f;
engineSize = 3.1f; engineSize = 3.1f;
@@ -3522,6 +3528,9 @@ public class UnitTypes{
hitSize = 12f; hitSize = 12f;
buildBeamOffset = 8f; buildBeamOffset = 8f;
fogRadius = 0f;
targetable = false;
engineOffset = 7.5f; engineOffset = 7.5f;
engineSize = 3.4f; engineSize = 3.4f;

View File

@@ -446,6 +446,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
return nearby(Geometry.d4(rotation + 3).x * trns, Geometry.d4(rotation + 3).y * trns); return nearby(Geometry.d4(rotation + 3).x * trns, Geometry.d4(rotation + 3).y * trns);
} }
/** Any class that overrides this method and changes the value must call Vars.fogControl.forceUpdate(team). */
public float fogRadius(){
return block.fogRadius;
}
public int pos(){ public int pos(){
return tile.pos(); return tile.pos();
} }

View File

@@ -37,7 +37,7 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
float lastExtend = walkExtension; float lastExtend = walkExtension;
if(extendScl < lastExtend && base % 2f > 1f && !isFlying()){ if(!headless && extendScl < lastExtend && base % 2f > 1f && !isFlying() && !inFogTo(player.team())){
int side = -Mathf.sign(extend); int side = -Mathf.sign(extend);
float width = hitSize / 2f * side, length = type.mechStride * 1.35f; float width = hitSize / 2f * side, length = type.mechStride * 1.35f;

View File

@@ -30,7 +30,7 @@ abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec
@Override @Override
public void update(){ public void update(){
//dust //dust
if(walked && !headless){ if(walked && !headless && !inFogTo(player.team())){
treadEffectTime += Time.delta; treadEffectTime += Time.delta;
if(treadEffectTime >= 6f && type.treadRects.length > 0){ if(treadEffectTime >= 6f && type.treadRects.length > 0){
var treadRegion = type.treadRegion; var treadRegion = type.treadRegion;

View File

@@ -1,6 +1,7 @@
package mindustry.game; package mindustry.game;
import arc.*; import arc.*;
import arc.math.*;
import arc.struct.Bits; import arc.struct.Bits;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
@@ -19,7 +20,7 @@ import static mindustry.Vars.*;
public final class FogControl implements CustomChunk{ public final class FogControl implements CustomChunk{
private static volatile int ww, wh; private static volatile int ww, wh;
private static final int staticUpdateInterval = 1000 / 25; //25 FPS private static final int dynamicUpdateInterval = 1000 / 25; //25 FPS
private static final Object notifyStatic = new Object(), notifyDynamic = new Object(); private static final Object notifyStatic = new Object(), notifyDynamic = new Object();
/** indexed by team */ /** indexed by team */
@@ -48,11 +49,11 @@ public final class FogControl implements CustomChunk{
wh = world.height(); wh = world.height();
//all old buildings have static light scheduled around them //all old buildings have static light scheduled around them
if(state.rules.fog){ if(state.rules.fog && state.rules.staticFog){
synchronized(staticEvents){ synchronized(staticEvents){
for(var build : Groups.build){ for(var build : Groups.build){
if(build.block.flags.contains(BlockFlag.hasFogRadius)){ if(build.block.flags.contains(BlockFlag.hasFogRadius)){
staticEvents.add(FogEvent.get(build.tile.x, build.tile.y, build.block.fogRadius, build.team.id)); staticEvents.add(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id));
} }
} }
} }
@@ -66,9 +67,11 @@ public final class FogControl implements CustomChunk{
data.dynamicUpdated = true; data.dynamicUpdated = true;
} }
synchronized(staticEvents){ if(state.rules.staticFog){
//TODO event per team? synchronized(staticEvents){
pushEvent(FogEvent.get(event.tile.x, event.tile.y, event.tile.block().fogRadius, event.tile.build.team.id)); //TODO event per team?
pushEvent(FogEvent.get(event.tile.x, event.tile.y, Mathf.round(event.tile.build.fogRadius()), event.tile.build.team.id));
}
} }
} }
}); });
@@ -83,7 +86,7 @@ public final class FogControl implements CustomChunk{
} }
}); });
SaveVersion.addCustomChunk("fogdata", this); SaveVersion.addCustomChunk("static-fog-data", this);
} }
public @Nullable Bits getDiscovered(Team team){ public @Nullable Bits getDiscovered(Team team){
@@ -124,12 +127,26 @@ public final class FogControl implements CustomChunk{
} }
void pushEvent(long event){ void pushEvent(long event){
if(!state.rules.staticFog) return;
staticEvents.add(event); staticEvents.add(event);
if(!headless && FogEvent.team(event) == Vars.player.team().id){ if(!headless && FogEvent.team(event) == Vars.player.team().id){
renderer.fog.handleEvent(event); renderer.fog.handleEvent(event);
} }
} }
public void forceUpdate(Team team, Building build){
if(state.rules.fog && fog[team.id] != null){
fog[team.id].dynamicUpdated = true;
if(state.rules.staticFog){
synchronized(staticEvents){
pushEvent(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id));
}
}
}
}
public void update(){ public void update(){
if(fog == null){ if(fog == null){
fog = new FogData[256]; fog = new FogData[256];
@@ -168,6 +185,7 @@ public final class FogControl implements CustomChunk{
//TODO slow? //TODO slow?
for(var unit : team.units){ for(var unit : team.units){
int tx = unit.tileX(), ty = unit.tileY(), pos = tx + ty * ww; int tx = unit.tileX(), ty = unit.tileY(), pos = tx + ty * ww;
if(unit.type.fogRadius <= 0f) continue;
long event = FogEvent.get(tx, ty, (int)unit.type.fogRadius, team.team.id); long event = FogEvent.get(tx, ty, (int)unit.type.fogRadius, team.team.id);
//always update the dynamic events, but only *flush* the results when necessary? //always update the dynamic events, but only *flush* the results when necessary?
@@ -182,13 +200,13 @@ public final class FogControl implements CustomChunk{
} }
//if it's time for an update, flush *everything* onto the update queue //if it's time for an update, flush *everything* onto the update queue
if(data.dynamicUpdated && Time.timeSinceMillis(data.lastDynamicMs) > staticUpdateInterval){ if(data.dynamicUpdated && Time.timeSinceMillis(data.lastDynamicMs) > dynamicUpdateInterval){
data.dynamicUpdated = false; data.dynamicUpdated = false;
data.lastDynamicMs = Time.millis(); data.lastDynamicMs = Time.millis();
//add building updates //add building updates
for(var build : indexer.getFlagged(team.team, BlockFlag.hasFogRadius)){ for(var build : indexer.getFlagged(team.team, BlockFlag.hasFogRadius)){
dynamicEventQueue.add(FogEvent.get(build.tile.x, build.tile.y, build.block.fogRadius, build.team.id)); dynamicEventQueue.add(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id));
} }
//add unit updates //add unit updates
@@ -219,7 +237,7 @@ public final class FogControl implements CustomChunk{
} }
//wake up, it's time to draw some circles //wake up, it's time to draw some circles
if(staticEvents.size > 0 && staticFogThread != null){ if(state.rules.staticFog && staticEvents.size > 0 && staticFogThread != null){
synchronized(notifyStatic){ synchronized(notifyStatic){
notifyStatic.notify(); notifyStatic.notify();
} }
@@ -310,6 +328,8 @@ public final class FogControl implements CustomChunk{
long event = dynamicEvents.items[i]; long event = dynamicEvents.items[i];
int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event); int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event);
if(rad <= 0) continue;
var data = fog[team]; var data = fog[team];
if(data != null){ if(data != null){
@@ -412,7 +432,7 @@ public final class FogControl implements CustomChunk{
@Override @Override
public boolean shouldWrite(){ public boolean shouldWrite(){
return state.rules.fog && fog != null; return state.rules.fog && state.rules.staticFog && fog != null;
} }
static void circle(Bits arr, int x, int y, int radius){ static void circle(Bits arr, int x, int y, int radius){

View File

@@ -115,6 +115,8 @@ 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;
/** If fog = true, this is whether static (black) fog is enabled. */
public boolean staticFog = true;
/** Color for static, undiscovered fog of war areas. */ /** Color for static, undiscovered fog of war areas. */
public Color staticColor = new Color(0f, 0f, 0f, 1f); public Color staticColor = new Color(0f, 0f, 0f, 1f);
/** Color for discovered but un-monitored fog of war areas. */ /** Color for discovered but un-monitored fog of war areas. */

View File

@@ -412,7 +412,10 @@ public class BlockRenderer{
if(build != null){ if(build != null){
if(visible){ if(visible){
if(!build.wasVisible) updateShadow(build); if(!build.wasVisible){
updateShadow(build);
renderer.minimap.update(tile);
}
build.wasVisible = true; build.wasVisible = true;
} }

View File

@@ -51,7 +51,7 @@ public final class FogRenderer{
dynamicFog.resize(world.width(), world.height()); dynamicFog.resize(world.width(), world.height());
if(player.team() != lastTeam){ if(state.rules.staticFog && player.team() != lastTeam){
copyFromCpu(); copyFromCpu();
lastTeam = player.team(); lastTeam = player.team();
clearStatic = false; clearStatic = false;
@@ -59,8 +59,6 @@ public final class FogRenderer{
//draw dynamic fog every frame //draw dynamic fog every frame
{ {
Core.camera.bounds(Tmp.r1);
Draw.proj(0, 0, staticFog.getWidth() * tilesize, staticFog.getHeight() * tilesize); Draw.proj(0, 0, staticFog.getWidth() * tilesize, staticFog.getHeight() * tilesize);
dynamicFog.begin(Color.black); dynamicFog.begin(Color.black);
ScissorStack.push(rect.set(1, 1, staticFog.getWidth() - 2, staticFog.getHeight() - 2)); ScissorStack.push(rect.set(1, 1, staticFog.getWidth() - 2, staticFog.getHeight() - 2));
@@ -68,11 +66,11 @@ public final class FogRenderer{
Team team = player.team(); Team team = player.team();
for(var build : indexer.getFlagged(team, BlockFlag.hasFogRadius)){ for(var build : indexer.getFlagged(team, BlockFlag.hasFogRadius)){
poly(Tmp.r1, build.x, build.y, build.block.fogRadius * tilesize); poly(build.x, build.y, build.fogRadius() * tilesize);
} }
for(var unit : team.data().units){ for(var unit : team.data().units){
poly(Tmp.r1, unit.x, unit.y, unit.type.fogRadius * tilesize); poly(unit.x, unit.y, unit.type.fogRadius * tilesize);
} }
dynamicFog.end(); dynamicFog.end();
@@ -81,7 +79,7 @@ public final class FogRenderer{
} }
//grab static events //grab static events
if(clearStatic || events.size > 0){ if(state.rules.staticFog && (clearStatic || events.size > 0)){
//set projection to whole map //set projection to whole map
Draw.proj(0, 0, staticFog.getWidth(), staticFog.getHeight()); Draw.proj(0, 0, staticFog.getWidth(), staticFog.getHeight());
@@ -107,22 +105,23 @@ public final class FogRenderer{
Draw.proj(Core.camera); Draw.proj(Core.camera);
} }
staticFog.getTexture().setFilter(TextureFilter.linear); if(state.rules.staticFog){
staticFog.getTexture().setFilter(TextureFilter.linear);
}
dynamicFog.getTexture().setFilter(TextureFilter.linear); dynamicFog.getTexture().setFilter(TextureFilter.linear);
Draw.shader(Shaders.fog); Draw.shader(Shaders.fog);
Draw.color(state.rules.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(state.rules.staticColor); if(state.rules.staticFog){
Draw.fbo(staticFog.getTexture(), world.width(), world.height(), tilesize); Draw.color(state.rules.staticColor);
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(float x, float y, float rad){
//todo clipping messes up the minimap
//if(check.overlaps(x - rad, y - rad, rad * 2f, rad * 2f)){
Fill.poly(x, y, 20, rad); Fill.poly(x, y, 20, rad);
//}
} }
void renderEvent(long e){ void renderEvent(long e){

View File

@@ -150,7 +150,6 @@ public class MinimapRenderer{
Texture staticTex = renderer.fog.getStaticTexture(), dynamicTex = renderer.fog.getDynamicTexture(); Texture staticTex = renderer.fog.getStaticTexture(), dynamicTex = renderer.fog.getDynamicTexture();
//crisp pixels //crisp pixels
staticTex.setFilter(TextureFilter.nearest);
dynamicTex.setFilter(TextureFilter.nearest); dynamicTex.setFilter(TextureFilter.nearest);
Tmp.tr1.set(dynamicTex); Tmp.tr1.set(dynamicTex);
@@ -159,10 +158,14 @@ public class MinimapRenderer{
Draw.color(state.rules.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; if(state.rules.staticFog){
//must be black to fit with borders staticTex.setFilter(TextureFilter.nearest);
Draw.color(0f, 0f, 0f, state.rules.staticColor.a);
Draw.rect(Tmp.tr1, x + w/2f, y + h/2f, w, h); Tmp.tr1.texture = staticTex;
//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.color(); Draw.color();
Draw.shader(); Draw.shader();
@@ -252,13 +255,20 @@ public class MinimapRenderer{
Units.nearby((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize, units::add); Units.nearby((dx - sz) * tilesize, (dy - sz) * tilesize, sz * 2 * tilesize, sz * 2 * tilesize, units::add);
} }
private Block realBlock(Tile tile){
//TODO dynamically update on visibility change; right now it's just entirely hidden
return tile.build == null ? tile.block() : state.rules.fog && tile.build.team != player.team() ? Blocks.air : tile.block();
}
private int colorFor(Tile tile){ private int colorFor(Tile tile){
if(tile == null) return 0; if(tile == null) return 0;
int bc = tile.block().minimapColor(tile); Block real = realBlock(tile);
Color color = Tmp.c1.set(bc == 0 ? MapIO.colorFor(tile.block(), tile.floor(), tile.overlay(), tile.team()) : bc); int bc = real.minimapColor(tile);
Color color = Tmp.c1.set(bc == 0 ? MapIO.colorFor(real, tile.floor(), tile.overlay(), tile.team()) : bc);
color.mul(1f - Mathf.clamp(world.getDarkness(tile.x, tile.y) / 4f)); color.mul(1f - Mathf.clamp(world.getDarkness(tile.x, tile.y) / 4f));
if(tile.block() == Blocks.air && tile.y < world.height() - 1 && world.tile(tile.x, tile.y + 1).block().solid){ if(real == Blocks.air && tile.y < world.height() - 1 && realBlock(world.tile(tile.x, tile.y + 1)).solid){
color.mul(0.7f); color.mul(0.7f);
}else if(tile.floor().isLiquid && (tile.y >= world.height() - 1 || !world.tile(tile.x, tile.y + 1).floor().isLiquid)){ }else if(tile.floor().isLiquid && (tile.y >= world.height() - 1 || !world.tile(tile.x, tile.y + 1).floor().isLiquid)){
color.mul(0.84f, 0.84f, 0.9f, 1f); color.mul(0.84f, 0.84f, 0.9f, 1f);

View File

@@ -312,8 +312,8 @@ public class TypeIO{
/** @return the maximum acceptable amount of plans to send over the network */ /** @return the maximum acceptable amount of plans to send over the network */
public static int getMaxPlans(Queue<BuildPlan> plans){ public static int getMaxPlans(Queue<BuildPlan> plans){
//limit to 10 to prevent buffer overflows //limit to prevent buffer overflows
int used = Math.min(plans.size, 10); int used = Math.min(plans.size, 15);
int totalLength = 0; int totalLength = 0;
//prevent buffer overflow by checking config length //prevent buffer overflow by checking config length

View File

@@ -169,6 +169,7 @@ public class UnitType extends UnlockableContent{
public float hitSize = 6f; public float hitSize = 6f;
public float itemOffsetY = 3f; public float itemOffsetY = 3f;
public float lightRadius = -1f, lightOpacity = 0.6f; public float lightRadius = -1f, lightOpacity = 0.6f;
/** Fog view radius in tiles. <0 for automatic radius. */
public float fogRadius = -1f; public float fogRadius = -1f;
public Color lightColor = Pal.powerLight; public Color lightColor = Pal.powerLight;
public boolean drawCell = true, drawItems = true, drawShields = true, drawBody = true; public boolean drawCell = true, drawItems = true, drawShields = true, drawBody = true;

View File

@@ -624,7 +624,7 @@ public class SettingsMenuDialog extends BaseDialog{
button(bundle.get("settings.reset", "Reset to Defaults"), () -> { button(bundle.get("settings.reset", "Reset to Defaults"), () -> {
for(Setting setting : list){ for(Setting setting : list){
if(setting.name == null || setting.title == null) continue; if(setting.name == null || setting.title == null) continue;
settings.put(setting.name, settings.getDefault(setting.name)); settings.remove(setting.name);
} }
rebuild(); rebuild();
}).margin(14).width(240f).pad(6); }).margin(14).width(240f).pad(6);

View File

@@ -119,6 +119,12 @@ public class PlacementFragment extends Fragment{
if(Core.input.keyTap(Binding.pick) && player.isBuilder() && !Core.scene.hasDialog()){ //mouse eyedropper select if(Core.input.keyTap(Binding.pick) && player.isBuilder() && !Core.scene.hasDialog()){ //mouse eyedropper select
var build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); var build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
//can't middle click buildings in fog
if(build != null && build.inFogTo(player.team())){
build = null;
}
Block tryRecipe = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block; Block tryRecipe = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block;
Object tryConfig = build == null || !build.block.copyConfig ? null : build.config(); Object tryConfig = build == null || !build.block.copyConfig ? null : build.config();
@@ -577,7 +583,7 @@ public class PlacementFragment extends Fragment{
Tile hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); Tile hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
if(hoverTile != null){ if(hoverTile != null){
//if the tile has a building, display it //if the tile has a building, display it
if(hoverTile.build != null && hoverTile.build.displayable()){ if(hoverTile.build != null && hoverTile.build.displayable() && !hoverTile.build.inFogTo(player.team())){
return nextFlowBuild = hoverTile.build; return nextFlowBuild = hoverTile.build;
} }

View File

@@ -0,0 +1,106 @@
package mindustry.world.blocks.defense;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.struct.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
public class Radar extends Block{
public float discoveryTime = 60f * 7f;
public float rotateSpeed = 2f;
public @Load("@-base") TextureRegion baseRegion;
public @Load("@-glow") TextureRegion glowRegion;
public Color glowColor = Pal.turretHeat;
public float glowScl = 5f, glowMag = 0.6f;
public Radar(String name){
super(name);
update = solid = true;
flags = EnumSet.of(BlockFlag.hasFogRadius);
outlineIcon = true;
fogRadius = 10;
}
@Override
public TextureRegion[] icons(){
return new TextureRegion[]{baseRegion, region};
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
super.drawPlace(x, y, rotation, valid);
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, fogRadius * tilesize, Pal.accent);
}
public class RadarBuild extends Building{
public float progress;
public float lastRadius = 0f;
public float smoothEfficiency = 1f;
public float totalProgress;
@Override
public float fogRadius(){
return fogRadius * progress * smoothEfficiency;
}
@Override
public void updateTile(){
smoothEfficiency = Mathf.lerpDelta(smoothEfficiency, efficiency, 0.05f);
if(Math.abs(fogRadius() - lastRadius) >= 0.5f){
Vars.fogControl.forceUpdate(team, this);
lastRadius = fogRadius();
}
progress += edelta() / discoveryTime;
progress = Mathf.clamp(progress);
totalProgress += efficiency * edelta();
}
@Override
public void drawSelect(){
Drawf.dashCircle(x, y, fogRadius() * tilesize, Pal.accent);
}
@Override
public void draw(){
Draw.rect(baseRegion, x, y);
Draw.rect(region, x, y, rotateSpeed * totalProgress);
Drawf.additive(glowRegion, glowColor, glowColor.a * (1f - glowMag + Mathf.absin(glowScl, glowMag)), x, y, rotateSpeed * totalProgress, Layer.blockAdditive);
}
@Override
public float progress(){
return progress;
}
@Override
public void write(Writes write){
super.write(write);
write.f(progress);
}
@Override
public void read(Reads read, byte revision){
super.read(read, revision);
progress = read.f();
}
}
}

View File

@@ -104,7 +104,7 @@ public class CoreBlock extends StorageBlock{
public void init(){ public void init(){
//assign to update clipSize internally //assign to update clipSize internally
lightRadius = 30f + 20f * size; lightRadius = 30f + 20f * size;
fogRadius = Math.max(fogRadius, (int)(lightRadius / 8f * 2f)); fogRadius = Math.max(fogRadius, (int)(lightRadius / 8f * 3f));
emitLight = true; emitLight = true;
super.init(); super.init();

View File

@@ -13,7 +13,8 @@ public enum BuildVisibility{
campaignOnly(() -> Vars.state == null || Vars.state.isCampaign()), campaignOnly(() -> Vars.state == null || Vars.state.isCampaign()),
lightingOnly(() -> Vars.state == null || Vars.state.rules.lighting || Vars.state.isCampaign()), lightingOnly(() -> Vars.state == null || Vars.state.rules.lighting || Vars.state.isCampaign()),
berylliumOnly(() -> !Vars.state.rules.hiddenBuildItems.contains(Items.beryllium)), berylliumOnly(() -> !Vars.state.rules.hiddenBuildItems.contains(Items.beryllium)),
ammoOnly(() -> Vars.state == null || Vars.state.rules.unitAmmo); ammoOnly(() -> Vars.state == null || Vars.state.rules.unitAmmo),
fogOnly(() -> Vars.state == null || Vars.state.rules.fog);
private final Boolp visible; private final Boolp visible;

View File

@@ -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=5f559f794f archash=162d5f8fa4