Link previews for power blocks near nodes

This commit is contained in:
Anuken
2021-02-28 17:17:03 -05:00
parent 666c0f3582
commit 49bccffd7c
6 changed files with 72 additions and 20 deletions

View File

@@ -910,24 +910,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
public void placed(){
if(net.client()) return;
if(block.consumesPower || block.outputsPower){
int range = 12;
tempTiles.clear();
Geometry.circle(tileX(), tileY(), range, (x, y) -> {
Building other = world.build(x, y);
if(other != null && other.block instanceof PowerNode node && node.linkValid(other, self()) && !PowerNode.insulated(other, self())
&& !other.proximity().contains(this.<Building>self()) &&
!(block.outputsPower && proximity.contains(p -> p.power != null && p.power.graph == other.power.graph))){
tempTiles.add(other.tile);
if((block.consumesPower || block.outputsPower) && block.hasPower){
PowerNode.getNodeLinks(tile, block, other -> {
if(!other.power.links.contains(pos())){
other.configureAny(pos());
}
});
tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile)));
if(!tempTiles.isEmpty()){
Tile toLink = tempTiles.first();
if(!toLink.build.power.links.contains(pos())){
toLink.build.configureAny(pos());
}
}
}
}

View File

@@ -26,6 +26,7 @@ import mindustry.graphics.MultiPacker.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.power.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import mindustry.world.meta.values.*;
@@ -255,6 +256,22 @@ public class Block extends UnlockableContent{
/** Drawn when you are placing a block. */
public void drawPlace(int x, int y, int rotation, boolean valid){
if((consumesPower || outputsPower) && hasPower){
Tile tile = world.tile(x, y);
if(tile != null){
PowerNode.getNodeLinks(tile, this, other -> {
PowerNode node = (PowerNode)other.block;
Draw.color(node.laserColor1, Renderer.laserOpacity * 0.5f);
node.drawLaser(tile.team(), x * tilesize + offset, y * tilesize + offset, other.x, other.y, size, other.block.size);
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
PowerNode.insulators(other.tileX(), other.tileY(), tile.x, tile.y, cause -> {
Drawf.square(cause.x, cause.y, cause.block.size * tilesize / 2f + 2f, Pal.plastanium);
});
});
}
}
}
public float drawPlaceText(String text, int x, int y, boolean valid){

View File

@@ -105,7 +105,7 @@ public class BlockForge extends PayloadAcceptor{
consume();
payload = new BuildPayload(recipe, team);
payVector.setZero();
progress = 0f;
progress %= 1f;
}
}

View File

@@ -167,7 +167,7 @@ public class PowerNode extends PowerBlock{
Draw.alpha(Renderer.laserOpacity);
}
protected void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){
public void drawLaser(Team team, float x1, float y1, float x2, float y2, int size1, int size2){
float angle1 = Angles.angle(x1, y1, x2, y2),
vx = Mathf.cosDeg(angle1), vy = Mathf.sinDeg(angle1),
len1 = size1 * tilesize / 2f - 1.5f, len2 = size2 * tilesize / 2f - 1.5f;
@@ -240,6 +240,53 @@ public class PowerNode extends PowerBlock{
});
}
//TODO code duplication w/ method above?
/** Iterates through linked nodes of a block at a tile. All returned buildings are power nodes. */
public static void getNodeLinks(Tile tile, Block block, Cons<Building> others){
Boolf<Building> valid = other -> other != null && other.tile() != tile && other.block instanceof PowerNode node &&
other.power.links.size < node.maxNodes &&
node.overlaps(tile.x * tilesize + block.offset, tile.y * tilesize + block.offset, other.tile(), node.laserRange * tilesize) && other.team == player.team()
&& !graphs.contains(other.power.graph) &&
!Structs.contains(Edges.getEdges(block.size), p -> { //do not link to adjacent buildings
var t = world.tile(tile.x + p.x, tile.y + p.y);
return t != null && t.build == other;
});
tempTileEnts.clear();
graphs.clear();
//add conducting graphs to prevent double link
for(var p : Edges.getEdges(block.size)){
Tile other = tile.nearby(p);
if(other != null && other.team() == player.team() && other.build != null && other.build.power != null){
graphs.add(other.build.power.graph);
}
}
if(tile.build != null && tile.build.power != null){
graphs.add(tile.build.power.graph);
}
//max linking range is currently 12
Geometry.circle(tile.x, tile.y, 12, (x, y) -> {
Building other = world.build(x, y);
if(valid.get(other) && !tempTileEnts.contains(other)){
tempTileEnts.add(other);
}
});
tempTileEnts.sort((a, b) -> {
int type = -Boolean.compare(a.block instanceof PowerNode, b.block instanceof PowerNode);
if(type != 0) return type;
return Float.compare(a.dst2(tile), b.dst2(tile));
});
tempTileEnts.each(valid, t -> {
graphs.add(t.power.graph);
others.get(t);
});
}
@Override
public void drawRequestConfigTop(BuildPlan req, Eachable<BuildPlan> list){
if(req.config instanceof Point2[] ps){

View File

@@ -175,7 +175,7 @@ public class Reconstructor extends UnitBlock{
//upgrade the unit
if(progress >= constructTime){
payload.unit = upgrade(payload.unit.type).create(payload.unit.team());
progress = 0;
progress %= 1f;
Effect.shake(2f, 3f, this);
Fx.producesmoke.at(this);
consume();

View File

@@ -225,7 +225,7 @@ public class UnitFactory extends UnitBlock{
UnitPlan plan = plans.get(currentPlan);
if(progress >= plan.time && consValid()){
progress = 0f;
progress %= 1f;
payload = new UnitPayload(plan.unit.create(team));
payVector.setZero();