WIP conduit graph

This commit is contained in:
Anuken
2023-05-09 12:19:26 -04:00
parent ccd2727ab5
commit 3faf8ca07f
7 changed files with 180 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ manifold=36
mega=5 mega=5
mindustry.entities.comp.BuildingComp=6 mindustry.entities.comp.BuildingComp=6
mindustry.entities.comp.BulletComp=7 mindustry.entities.comp.BulletComp=7
mindustry.entities.comp.ConduitGraphUpdaterComp=48
mindustry.entities.comp.DecalComp=8 mindustry.entities.comp.DecalComp=8
mindustry.entities.comp.EffectStateComp=9 mindustry.entities.comp.EffectStateComp=9
mindustry.entities.comp.FireComp=10 mindustry.entities.comp.FireComp=10

View File

@@ -0,0 +1 @@
{fields:[]}

View File

@@ -1681,6 +1681,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
proximity.clear(); proximity.clear();
} }
public void rotated(int prevRotation, int newRotation){
}
public void updateProximity(){ public void updateProximity(){
tmpTiles.clear(); tmpTiles.clear();
proximity.clear(); proximity.clear();

View File

@@ -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();
}
}

View File

@@ -464,8 +464,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
if(player != null) build.lastAccessed = player.name; 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.updateProximity();
build.rotated(prev, newRotation);
build.noSleep(); build.noSleep();
Fx.rotateBlock.at(build.x, build.y, build.block.size); Fx.rotateBlock.at(build.x, build.y, build.block.size);
} }

View File

@@ -148,10 +148,58 @@ public class Conduit extends LiquidBlock implements Autotiler{
} }
public class ConduitBuild extends LiquidBuild implements ChainedBuilding{ public class ConduitBuild extends LiquidBuild implements ChainedBuilding{
public @Nullable ConduitGraph graph;
public float smoothLiquid; public float smoothLiquid;
public int blendbits, xscl = 1, yscl = 1, blending; public int blendbits, xscl = 1, yscl = 1, blending;
public boolean capped, backCapped = false; 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 @Override
public void draw(){ public void draw(){
int r = this.rotation; 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(capped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg());
if(backCapped && capRegion.found()) Draw.rect(capRegion, x, y, rotdeg() + 180); 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){ 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; 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();
}
}
} }
} }

View File

@@ -25,4 +25,4 @@ org.gradle.caching=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=77461f1c82 archash=eb3b8bdd10