WIP conduit graph
This commit is contained in:
@@ -1681,6 +1681,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
proximity.clear();
|
||||
}
|
||||
|
||||
public void rotated(int prevRotation, int newRotation){
|
||||
|
||||
}
|
||||
|
||||
public void updateProximity(){
|
||||
tmpTiles.clear();
|
||||
proximity.clear();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package mindustry.entities.comp;
|
||||
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.blocks.liquid.Conduit.*;
|
||||
|
||||
@EntityDef(value = ConduitGraphUpdaterc.class, serialize = false, genio = false)
|
||||
@Component
|
||||
abstract class ConduitGraphUpdaterComp implements Entityc{
|
||||
public transient ConduitGraph graph;
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
graph.update();
|
||||
}
|
||||
}
|
||||
@@ -464,8 +464,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
if(player != null) build.lastAccessed = player.name;
|
||||
build.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4);
|
||||
int newRotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4), prev = build.rotation;
|
||||
build.rotation = newRotation;
|
||||
build.updateProximity();
|
||||
build.rotated(prev, newRotation);
|
||||
build.noSleep();
|
||||
Fx.rotateBlock.at(build.x, build.y, build.block.size);
|
||||
}
|
||||
|
||||
@@ -148,10 +148,58 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
}
|
||||
|
||||
public class ConduitBuild extends LiquidBuild implements ChainedBuilding{
|
||||
public @Nullable ConduitGraph graph;
|
||||
|
||||
public float smoothLiquid;
|
||||
public int blendbits, xscl = 1, yscl = 1, blending;
|
||||
public boolean capped, backCapped = false;
|
||||
|
||||
protected void addGraphs(){
|
||||
graph = null;
|
||||
//connect self to every nearby graph
|
||||
getConnections(other -> {
|
||||
if(other.graph != null){
|
||||
other.graph.merge(this);
|
||||
}
|
||||
});
|
||||
|
||||
if(graph == null){
|
||||
new ConduitGraph().merge(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeGraphs(){
|
||||
//graph is getting recalculated, no longer valid
|
||||
if(graph != null){
|
||||
graph.checkRemove();
|
||||
}
|
||||
|
||||
getConnections(other -> new ConduitGraph().reflow(this, other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProximityAdded(){
|
||||
super.onProximityAdded();
|
||||
|
||||
addGraphs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProximityRemoved(){
|
||||
super.onProximityRemoved();
|
||||
|
||||
removeGraphs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotated(int prevRot, int newRot){
|
||||
//essentially simulates the conduit being removed and re-placed - hacky, but it works
|
||||
rotation = prevRot;
|
||||
removeGraphs();
|
||||
rotation = newRot;
|
||||
addGraphs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
int r = this.rotation;
|
||||
@@ -173,6 +221,15 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
|
||||
if(capped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg());
|
||||
if(backCapped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg() + 180);
|
||||
|
||||
//TODO this is for debuggig only
|
||||
Mathf.rand.setSeed(graph == null ? -1 : graph.id);
|
||||
Draw.color(Tmp.c1.rand());
|
||||
Draw.alpha(0.4f);
|
||||
|
||||
Fill.square(x, y, 4f);
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
protected void drawAt(float x, float y, int bits, int rotation, SliceMode slice){
|
||||
@@ -245,5 +302,102 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Calls callback with every conduit that transfers fluids to this one. */
|
||||
public void getConnections(Cons<ConduitBuild> cons){
|
||||
for(var other : proximity){
|
||||
if(other instanceof ConduitBuild conduit){
|
||||
if(
|
||||
front() == conduit ||
|
||||
other.front() == this
|
||||
){
|
||||
cons.get(conduit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConduitGraph{
|
||||
private static final IntSet closedSet = new IntSet();
|
||||
private static final Queue<ConduitBuild> queue = new Queue<>();
|
||||
|
||||
static int lastId = -1;
|
||||
|
||||
public final int id = lastId ++;
|
||||
|
||||
private Seq<ConduitBuild> conduits = new Seq<>();
|
||||
private final @Nullable ConduitGraphUpdater entity;
|
||||
|
||||
public ConduitGraph(){
|
||||
entity = ConduitGraphUpdater.create();
|
||||
entity.graph = this;
|
||||
}
|
||||
|
||||
public void update(){
|
||||
//TODO
|
||||
}
|
||||
|
||||
public void checkAdd(){
|
||||
if(entity != null) entity.add();
|
||||
}
|
||||
|
||||
public void checkRemove(){
|
||||
if(entity != null) entity.remove();
|
||||
}
|
||||
|
||||
public void reflow(@Nullable ConduitBuild ignore, ConduitBuild conduit){
|
||||
closedSet.clear();
|
||||
queue.clear();
|
||||
|
||||
//ignore the starting point and don't add it, as it is being removed
|
||||
if(ignore != null) closedSet.add(ignore.id);
|
||||
|
||||
closedSet.add(conduit.id);
|
||||
queue.add(conduit);
|
||||
|
||||
while(queue.size > 0){
|
||||
var parent = queue.removeFirst();
|
||||
assign(parent);
|
||||
|
||||
parent.getConnections(child -> {
|
||||
if(closedSet.add(child.id)){
|
||||
queue.addLast(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
closedSet.clear();
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
public void merge(ConduitBuild other){
|
||||
if(other.graph == this) return;
|
||||
|
||||
if(other.graph != null){
|
||||
|
||||
//merge graphs - TODO - flip if it is larger
|
||||
for(var cond : other.graph.conduits){
|
||||
assign(cond);
|
||||
}
|
||||
}else{
|
||||
assign(other);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assign(ConduitBuild build){
|
||||
if(build.graph != this){
|
||||
|
||||
//invalidate older graph
|
||||
if(build.graph != null){
|
||||
build.graph.checkRemove();
|
||||
}
|
||||
|
||||
build.graph = this;
|
||||
conduits.add(build);
|
||||
checkAdd();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user