mirror of
https://github.com/Anuken/Mindustry.git
synced 2024-12-22 23:34:00 +07:00
Beam node link previews, closes Anuken/Mindustry-Suggestions/issues/5140
This commit is contained in:
parent
1f900b52f8
commit
7671766469
@ -441,6 +441,14 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
|
||||
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
|
||||
});
|
||||
|
||||
BeamNode.getNodeLinks(tile, this, player.team(), other -> {
|
||||
BeamNode node = (BeamNode)other.block;
|
||||
Draw.color(node.laserColor1, Renderer.laserOpacity * 0.5f);
|
||||
node.drawLaser(other.x, other.y, x * tilesize + offset, y * tilesize + offset, size, other.block.size);
|
||||
|
||||
Drawf.square(other.x, other.y, other.block.size * tilesize / 2f + 2f, Pal.place);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
package mindustry.world.blocks.power;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.input.*;
|
||||
@ -20,6 +23,9 @@ import java.util.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class BeamNode extends PowerBlock{
|
||||
//maximum expected range of any beam node; used for previews
|
||||
private static final int maxRange = 30;
|
||||
|
||||
public int range = 5;
|
||||
|
||||
public @Load(value = "@-beam", fallback = "power-beam") TextureRegion laser;
|
||||
@ -105,12 +111,99 @@ public class BeamNode extends PowerBlock{
|
||||
}
|
||||
}
|
||||
|
||||
/** Iterates through linked nodes of a block at a tile. All returned buildings are beam nodes. */
|
||||
public static void getNodeLinks(Tile tile, Block block, Team team, Cons<Building> others){
|
||||
var tree = team.data().buildingTree;
|
||||
|
||||
if(tree == null) return;
|
||||
|
||||
float cx = tile.worldx() + block.offset, cy = tile.worldy() + block.offset, s = block.size * tilesize/2f, r = maxRange * tilesize;
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
int dx = Geometry.d4[i].x, dy = Geometry.d4[i].y;
|
||||
for(int length = 1; length < maxRange; length++){
|
||||
Tile other = tile.nearby(dx * i, dy * i);
|
||||
if(other == null || other.build == null || other.build.isInsulated()) break;
|
||||
|
||||
Building build = other.build;
|
||||
|
||||
if(build.team == team && build.block.hasPower && build.block.connectedPower){
|
||||
if(build instanceof BeamNodeBuild){
|
||||
if(build.tileX() == tile.x || build.tileY() == tile.y){
|
||||
others.get(build);
|
||||
break;
|
||||
}
|
||||
}else{ //it's a power structure that is blocking the way to any potential beam node.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(i){
|
||||
case 0 -> Tmp.r1.set(cx - s, cy - s, r, s * 2f);
|
||||
case 1 -> Tmp.r1.set(cx - s, cy - s, s * 2f, r);
|
||||
case 2 -> Tmp.r1.set(cx + s, cy - s, -r, s * 2f).normalize();
|
||||
case 3 -> Tmp.r1.set(cx - s, cy + s, s * 2f, -r).normalize();
|
||||
}
|
||||
|
||||
tempBuilds.clear();
|
||||
tree.intersect(Tmp.r1, tempBuilds);
|
||||
int fi = i;
|
||||
Building closest = tempBuilds.min(b -> b instanceof BeamNodeBuild node && node.couldConnect((fi + 2) % 4, block, tile.x, tile.y), b -> b.dst2(cx, cy));
|
||||
if(closest != null){
|
||||
others.get(closest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Note that x1 and y1 are expected to be coordinates of the node to draw the beam from. */
|
||||
public void drawLaser(float x1, float y1, float x2, float y2, int size1, int size2){
|
||||
float w = laserWidth;
|
||||
float dst = Math.max(Math.abs(x1 - x2), Math.abs(y2 - y1)) / tilesize;
|
||||
float sizeOff = dst * tilesize - (size1 + size2) * tilesize/2f;
|
||||
|
||||
//don't draw lasers for adjacent blocks
|
||||
if(dst > 1 + size/2){
|
||||
var point = Geometry.d4(Tile.relativeTo(x1, y1, x2, y2));
|
||||
float poff = tilesize/2f;
|
||||
Drawf.laser(laser, laserEnd, x1 + poff*size*point.x, y1 + poff*size*point.y, x1 + (poff*size + sizeOff) * point.x, y1 + (poff*size + sizeOff) * point.y, w);
|
||||
}
|
||||
}
|
||||
|
||||
public class BeamNodeBuild extends Building{
|
||||
//current links in cardinal directions
|
||||
public Building[] links = new Building[4];
|
||||
public Tile[] dests = new Tile[4];
|
||||
public int lastChange = -2;
|
||||
|
||||
/** @return whether a beam could theoretically connect with the specified block at a position */
|
||||
public boolean couldConnect(int direction, Block target, int targetX, int targetY){
|
||||
int offset = -(target.size - 1) / 2;
|
||||
int minX = targetX + offset, minY = targetY + offset, maxX = targetX + offset + target.size - 1, maxY = targetY + offset + target.size - 1;
|
||||
var dir = Geometry.d4[direction];
|
||||
|
||||
int rangeOffset = size/2;
|
||||
|
||||
//find first block with power in range
|
||||
for(int j = 1 + rangeOffset; j <= range + rangeOffset; j++){
|
||||
var other = world.tile(tile.x + j * dir.x, tile.y + j * dir.y);
|
||||
|
||||
if(other == null) return false;
|
||||
|
||||
//hit insulated wall
|
||||
if((other.build != null && other.build.isInsulated()) || (other.block().hasPower && other.block().connectedPower && other.team() == team)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//within target rectangle
|
||||
if(other.x >= minX && other.y >= minY && other.x <= maxX && other.y <= maxY){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
//TODO this block technically does not need to update every frame, perhaps put it in a special list.
|
||||
|
@ -26,4 +26,4 @@ org.gradle.caching=true
|
||||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
android.enableR8.fullMode=false
|
||||
archash=1fdfcdc213
|
||||
archash=6676d38433
|
||||
|
Loading…
Reference in New Issue
Block a user