Compare commits
6 Commits
v155.1
...
new-liquid
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c89d7d273 | ||
|
|
3ea742b06d | ||
|
|
9bedadac79 | ||
|
|
5ccadcf38f | ||
|
|
a32462971b | ||
|
|
3faf8ca07f |
@@ -15,6 +15,7 @@ manifold=36
|
||||
mega=5
|
||||
mindustry.entities.comp.BuildingComp=6
|
||||
mindustry.entities.comp.BulletComp=7
|
||||
mindustry.entities.comp.ConduitGraphUpdaterComp=48
|
||||
mindustry.entities.comp.DecalComp=8
|
||||
mindustry.entities.comp.EffectStateComp=9
|
||||
mindustry.entities.comp.FireComp=10
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{fields:[]}
|
||||
@@ -99,7 +99,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
private transient boolean sleeping;
|
||||
private transient float sleepTime;
|
||||
private transient boolean initialized;
|
||||
private transient boolean initialized, wasAdded;
|
||||
|
||||
/** Sets this tile entity data to this and adds it if necessary. */
|
||||
public Building init(Tile tile, Team team, boolean shouldAdd, int rotation){
|
||||
@@ -174,6 +174,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
//endregion
|
||||
//region io
|
||||
|
||||
/** certain blocks merge liquid graphs, so it is necessary to provide a fake one at write-time */
|
||||
public LiquidModule writeLiquids(){
|
||||
return liquids;
|
||||
}
|
||||
|
||||
public final void writeBase(Writes write){
|
||||
boolean writeVisibility = state.rules.fog && visibleFlags != 0;
|
||||
|
||||
@@ -186,7 +191,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
write.b(moduleBitmask());
|
||||
if(items != null) items.write(write);
|
||||
if(power != null) power.write(write);
|
||||
if(liquids != null) liquids.write(write);
|
||||
if(liquids != null) writeLiquids().write(write);
|
||||
|
||||
//efficiency is written as two bytes to save space
|
||||
write.b((byte)(Mathf.clamp(efficiency) * 255f));
|
||||
@@ -820,6 +825,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
if(!net.client() && state.isCampaign() && team == state.rules.defaultTeam) liquid.unlock();
|
||||
|
||||
float selfCapacity = liquidCapacity();
|
||||
|
||||
for(int i = 0; i < proximity.size; i++){
|
||||
incrementDump(proximity.size);
|
||||
|
||||
@@ -829,10 +836,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
other = other.getLiquidDestination(self(), liquid);
|
||||
|
||||
if(other != null && other.team == team && other.block.hasLiquids && canDumpLiquid(other, liquid) && other.liquids != null){
|
||||
float ofract = other.liquids.get(liquid) / other.block.liquidCapacity;
|
||||
float fract = liquids.get(liquid) / block.liquidCapacity;
|
||||
float ofract = other.liquids.get(liquid) / other.liquidCapacity();
|
||||
float fract = liquids.get(liquid) / selfCapacity;
|
||||
|
||||
if(ofract < fract) transferLiquid(other, (fract - ofract) * block.liquidCapacity / scaling, liquid);
|
||||
if(ofract < fract) transferLiquid(other, (fract - ofract) * selfCapacity / scaling, liquid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -842,7 +849,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
}
|
||||
|
||||
public void transferLiquid(Building next, float amount, Liquid liquid){
|
||||
float flow = Math.min(next.block.liquidCapacity - next.liquids.get(liquid), amount);
|
||||
float flow = Math.min(next.liquidCapacity() - next.liquids.get(liquid), amount);
|
||||
|
||||
if(next.acceptLiquid(self(), liquid)){
|
||||
next.handleLiquid(self(), liquid, flow);
|
||||
@@ -869,19 +876,20 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
if(next == null) return 0;
|
||||
|
||||
next = next.getLiquidDestination(self(), liquid);
|
||||
float selfCapacity = liquidCapacity(), nextCapacity = next.liquidCapacity();
|
||||
|
||||
if(next.team == team && next.block.hasLiquids && liquids.get(liquid) > 0f){
|
||||
float ofract = next.liquids.get(liquid) / next.block.liquidCapacity;
|
||||
float fract = liquids.get(liquid) / block.liquidCapacity * block.liquidPressure;
|
||||
float flow = Math.min(Mathf.clamp((fract - ofract)) * (block.liquidCapacity), liquids.get(liquid));
|
||||
flow = Math.min(flow, next.block.liquidCapacity - next.liquids.get(liquid));
|
||||
float ofract = next.liquids.get(liquid) / nextCapacity;
|
||||
float fract = liquids.get(liquid) / selfCapacity * block.liquidPressure;
|
||||
float flow = Math.min(Mathf.clamp((fract - ofract)) * selfCapacity, liquids.get(liquid));
|
||||
flow = Math.min(flow, nextCapacity - next.liquids.get(liquid));
|
||||
|
||||
if(flow > 0f && ofract <= fract && next.acceptLiquid(self(), liquid)){
|
||||
next.handleLiquid(self(), liquid, flow);
|
||||
liquids.remove(liquid, flow);
|
||||
return flow;
|
||||
//handle reactions between different liquid types ▼
|
||||
}else if(!next.block.consumesLiquid(liquid) && next.liquids.currentAmount() / next.block.liquidCapacity > 0.1f && fract > 0.1f){
|
||||
}else if(!next.block.consumesLiquid(liquid) && next.liquids.currentAmount() / nextCapacity > 0.1f && fract > 0.1f){
|
||||
//TODO !IMPORTANT! uses current(), which is 1) wrong for multi-liquid blocks and 2) causes unwanted reactions, e.g. hydrogen + slag in pump
|
||||
//TODO these are incorrect effect positions
|
||||
float fx = (x + next.x) / 2f, fy = (y + next.y) / 2f;
|
||||
@@ -907,6 +915,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Override to set a custom liquid capacity, e.g. for blocks with shared inventories. */
|
||||
public float liquidCapacity(){
|
||||
return block.liquidCapacity;
|
||||
}
|
||||
|
||||
public Building getLiquidDestination(Building from, Liquid liquid){
|
||||
return self();
|
||||
}
|
||||
@@ -1074,6 +1087,9 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
noSleep();
|
||||
}
|
||||
|
||||
/** Like onProximityAdded, but only called once. Essentially does what onProximityAdded was supposed to. */
|
||||
public void onAdded(){}
|
||||
|
||||
public void updatePowerGraph(){
|
||||
for(Building other : getPowerConnections(tempBuilds)){
|
||||
if(other.power != null){
|
||||
@@ -1679,6 +1695,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
other.onProximityUpdate();
|
||||
}
|
||||
proximity.clear();
|
||||
wasAdded = false;
|
||||
}
|
||||
|
||||
public void rotated(int prevRotation, int newRotation){
|
||||
|
||||
}
|
||||
|
||||
public void updateProximity(){
|
||||
@@ -1701,6 +1722,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
proximity.add(tile);
|
||||
}
|
||||
|
||||
if(!wasAdded){
|
||||
onAdded();
|
||||
wasAdded = true;
|
||||
}
|
||||
onProximityAdded();
|
||||
onProximityUpdate();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
addBar("liquid-" + liq.name, entity -> !liq.unlockedNow() ? null : new Bar(
|
||||
() -> liq.localizedName,
|
||||
liq::barColor,
|
||||
() -> entity.liquids.get(liq) / liquidCapacity
|
||||
() -> entity.liquids.get(liq) / entity.liquidCapacity()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -567,7 +567,7 @@ public class Block extends UnlockableContent implements Senseable{
|
||||
addBar("liquid", entity -> new Bar(
|
||||
() -> current.get((T)entity) == null || entity.liquids.get(current.get((T)entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get((T)entity).localizedName,
|
||||
() -> current.get((T)entity) == null ? Color.clear : current.get((T)entity).barColor(),
|
||||
() -> current.get((T)entity) == null ? 0f : entity.liquids.get(current.get((T)entity)) / liquidCapacity)
|
||||
() -> current.get((T)entity) == null ? 0f : entity.liquids.get(current.get((T)entity)) / entity.liquidCapacity())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
@@ -15,17 +16,22 @@ import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.input.*;
|
||||
import mindustry.logic.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.distribution.*;
|
||||
import mindustry.world.modules.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.type.Liquid.*;
|
||||
|
||||
public class Conduit extends LiquidBlock implements Autotiler{
|
||||
static final boolean debugGraphs = false;
|
||||
static final float mergeThreshold = 0.2f;
|
||||
static final float rotatePad = 6, hpad = rotatePad / 2f / 4f;
|
||||
static final float[][] rotateOffsets = {{hpad, hpad}, {-hpad, hpad}, {-hpad, -hpad}, {hpad, -hpad}};
|
||||
static final LiquidModule tempLiquids = new LiquidModule();
|
||||
|
||||
public final int timerFlow = timers++;
|
||||
|
||||
@@ -51,6 +57,10 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
noUpdateDisabled = true;
|
||||
canOverdrive = false;
|
||||
priority = TargetPriority.transport;
|
||||
|
||||
//conduits don't need to update
|
||||
update = false;
|
||||
destructible = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,10 +158,78 @@ 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(){
|
||||
//connect self to every nearby graph
|
||||
getConnections(other -> {
|
||||
if(other.graph != null){
|
||||
other.graph.merge(this);
|
||||
}
|
||||
});
|
||||
|
||||
//nothing to connect to
|
||||
if(graph == null){
|
||||
new ConduitGraph().merge(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void removeGraphs(){
|
||||
//graph is getting recalculated, no longer valid
|
||||
if(graph != null){
|
||||
graph.checkRemove();
|
||||
graph.remove(this);
|
||||
graph = null; //TODO ?????
|
||||
}
|
||||
|
||||
getConnections(other -> new ConduitGraph().reflow(this, other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void control(LAccess type, double p1, double p2, double p3, double p4){
|
||||
if(type == LAccess.enabled){
|
||||
boolean shouldEnable = !Mathf.zero((float)p1);
|
||||
if(enabled != shouldEnable){
|
||||
|
||||
if(graph != null){
|
||||
//keep track of how many conduits are disabled, so the graph can stop working
|
||||
if(shouldEnable){
|
||||
graph.disabledConduits --;
|
||||
}else{
|
||||
graph.disabledConduits ++;
|
||||
}
|
||||
}
|
||||
|
||||
enabled = shouldEnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdded(){
|
||||
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 +251,21 @@ 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);
|
||||
|
||||
if(debugGraphs){
|
||||
//simple visualization that assigns random color to each graph
|
||||
Mathf.rand.setSeed(graph == null ? -1 : graph.id);
|
||||
Draw.color(Tmp.c1.rand());
|
||||
|
||||
Drawf.selected(tileX(), tileY(), block, Tmp.c1);
|
||||
Draw.color(Pal.accent);
|
||||
|
||||
if(this == graph.head){
|
||||
Fill.poly(x, y, 3, 2f, rotdeg());
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawAt(float x, float y, int bits, int rotation, SliceMode slice){
|
||||
@@ -196,7 +289,7 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
//the drawing state machine sure was a great design choice with no downsides or hidden behavior!!!
|
||||
float xscl = Draw.xscl, yscl = Draw.yscl;
|
||||
Draw.scl(1f, 1f);
|
||||
Drawf.liquid(sliced(liquidr, slice), x + ox, y + oy, smoothLiquid, liquids.current().color.write(Tmp.c1).a(1f));
|
||||
Drawf.liquid(sliced(liquidr, slice), x + ox, y + oy, graph == null ? smoothLiquid : graph.smoothLiquid, liquids.current().color.write(Tmp.c1).a(1f));
|
||||
Draw.scl(xscl, yscl);
|
||||
|
||||
Draw.rect(sliced(topRegions[bits], slice), x, y, angle);
|
||||
@@ -225,15 +318,15 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTile(){
|
||||
smoothLiquid = Mathf.lerpDelta(smoothLiquid, liquids.currentAmount() / liquidCapacity, 0.05f);
|
||||
public LiquidModule writeLiquids(){
|
||||
//"saved" liquids are based on a fraction, essentially splitting apart and re-joining
|
||||
tempLiquids.set(liquids, graph == null ? 1f : block.liquidCapacity / graph.totalCapacity);
|
||||
return tempLiquids;
|
||||
}
|
||||
|
||||
if(liquids.currentAmount() > 0.0001f && timer(timerFlow, 1)){
|
||||
moveLiquidForward(leaks, liquids.current());
|
||||
noSleep();
|
||||
}else{
|
||||
sleep();
|
||||
}
|
||||
@Override
|
||||
public float liquidCapacity(){
|
||||
return graph == null ? block.liquidCapacity : graph.totalCapacity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -245,5 +338,195 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAll(Writes write){
|
||||
super.writeAll(write);
|
||||
}
|
||||
|
||||
/** Calls callback with every conduit that transfers fluids to this one. */
|
||||
public void getConnections(Cons<ConduitBuild> cons){
|
||||
for(var other : proximity){
|
||||
if(canMerge(other)){
|
||||
cons.get((ConduitBuild)other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canMerge(Building other){
|
||||
return
|
||||
other instanceof ConduitBuild conduit && other.team == team &&
|
||||
(front() == conduit || other.front() == this) &&
|
||||
(other.liquids.current() == liquids.current() || other.liquids.currentAmount() <= mergeThreshold || liquids.currentAmount() <= mergeThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- [X] liquids shared as one inventory
|
||||
- [X] liquids merged when placing
|
||||
- [X] liquids split when breaking
|
||||
- [X] liquids saved
|
||||
- [X] liquids accept input
|
||||
- [X] liquids transfer forward
|
||||
- [X] liquids leak
|
||||
- [X] liquids display properly (including flow rate)
|
||||
- [X] liquids merge different types correctly
|
||||
- [X] conduits can (or can't) be disabled
|
||||
*/
|
||||
public static class ConduitGraph{
|
||||
private static final IntSet closedSet = new IntSet(), headSet = new IntSet();
|
||||
private static final Queue<ConduitBuild> queue = new Queue<>();
|
||||
|
||||
static int lastId = 0;
|
||||
|
||||
public final int id = lastId ++;
|
||||
public float smoothLiquid;
|
||||
|
||||
/** if any are disabled, does not update */
|
||||
private int disabledConduits;
|
||||
private Seq<ConduitBuild> conduits = new Seq<>();
|
||||
private final @Nullable ConduitGraphUpdater entity;
|
||||
private LiquidModule liquids = new LiquidModule();
|
||||
private float totalCapacity;
|
||||
|
||||
public @Nullable ConduitBuild head;
|
||||
|
||||
public ConduitGraph(){
|
||||
entity = ConduitGraphUpdater.create();
|
||||
entity.graph = this;
|
||||
}
|
||||
|
||||
public void update(){
|
||||
smoothLiquid = Mathf.lerpDelta(smoothLiquid, liquids.currentAmount() / totalCapacity, 0.05f);
|
||||
|
||||
if(disabledConduits > 0) return;
|
||||
|
||||
if(head != null){
|
||||
|
||||
//move forward as the head
|
||||
if(liquids.currentAmount() > 0.0001f && head.timer(((Conduit)head.block).timerFlow, 1)){
|
||||
head.moveLiquidForward(((Conduit)head.block).leaks, liquids.current());
|
||||
}
|
||||
|
||||
//merge with front if one of the conduits becomes empty
|
||||
if(head.front() instanceof ConduitBuild build && build.graph != this && head.canMerge(build)){
|
||||
merge(build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkAdd(){
|
||||
if(entity != null) entity.add();
|
||||
}
|
||||
|
||||
public void checkRemove(){
|
||||
if(entity != null) entity.remove();
|
||||
}
|
||||
|
||||
public void remove(ConduitBuild build){
|
||||
float fraction = build.block.liquidCapacity / totalCapacity;
|
||||
//remove fraction of liquids based on what part this conduit constituted
|
||||
//e.g. 70% of capacity was made up by this conduit = multiply liquids by 0.3 (remove 70%)
|
||||
liquids.mul(1f - fraction);
|
||||
|
||||
totalCapacity -= build.block.liquidCapacity;
|
||||
}
|
||||
|
||||
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, ignore);
|
||||
|
||||
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, like power graphs?
|
||||
for(var cond : other.graph.conduits){
|
||||
assign(cond);
|
||||
}
|
||||
}else{
|
||||
assign(other);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assign(ConduitBuild build){
|
||||
assign(build, null);
|
||||
}
|
||||
|
||||
protected void assign(ConduitBuild build, @Nullable Building ignore){
|
||||
if(build.graph != this){
|
||||
|
||||
//merge graph liquids - TODO - how does this react to different types
|
||||
if(build.graph != null){
|
||||
build.graph.checkRemove();
|
||||
|
||||
//add liquids based on what fraction it made up
|
||||
liquids.add(build.liquids, build.block.liquidCapacity / build.graph.totalCapacity);
|
||||
}else{
|
||||
//simple direct liquid merge
|
||||
liquids.add(build.liquids);
|
||||
}
|
||||
|
||||
totalCapacity += build.block.liquidCapacity;
|
||||
build.graph = this;
|
||||
build.liquids = liquids;
|
||||
conduits.add(build);
|
||||
checkAdd();
|
||||
|
||||
//re-validate head
|
||||
if(head == null){
|
||||
head = build;
|
||||
}
|
||||
|
||||
//find the best head block
|
||||
headSet.clear();
|
||||
headSet.add(head.id);
|
||||
|
||||
while(true){
|
||||
var next = head.front();
|
||||
|
||||
if(next instanceof ConduitBuild cond && cond.team == head.team && next != ignore && cond.graph == this){
|
||||
if(!headSet.add(next.id)){
|
||||
//there's a loop, which means a head does not exist
|
||||
head = null;
|
||||
break;
|
||||
}else{
|
||||
head = cond;
|
||||
}
|
||||
}else{
|
||||
//found the end
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//snap smoothLiquid so it doesn't start at 0
|
||||
smoothLiquid = liquids.currentAmount() / totalCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class DrawLiquidRegion extends DrawBlock{
|
||||
public void draw(Building build){
|
||||
Liquid drawn = drawLiquid != null ? drawLiquid : build.liquids.current();
|
||||
Drawf.liquid(liquid, build.x, build.y,
|
||||
build.liquids.get(drawn) / build.block.liquidCapacity * alpha,
|
||||
build.liquids.get(drawn) / build.liquidCapacity() * alpha,
|
||||
drawn.color
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,12 @@ public class LiquidModule extends BlockModule{
|
||||
}
|
||||
}
|
||||
|
||||
public void mul(float amount){
|
||||
for(int i = 0; i < liquids.length; i ++){
|
||||
liquids[i] *= amount;
|
||||
}
|
||||
}
|
||||
|
||||
public void stopFlow(){
|
||||
flow = null;
|
||||
}
|
||||
@@ -107,6 +113,27 @@ public class LiquidModule extends BlockModule{
|
||||
Arrays.fill(liquids, 0);
|
||||
}
|
||||
|
||||
public void add(LiquidModule other){
|
||||
add(other, 1f);
|
||||
}
|
||||
|
||||
public void add(LiquidModule other, float mul){
|
||||
for(int i = 0; i < liquids.length; i ++){
|
||||
liquids[i] += other.liquids[i] * mul;
|
||||
|
||||
if(liquids[i] > liquids[current.id]){
|
||||
current = content.liquid(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void set(LiquidModule other, float mul){
|
||||
current = other.current;
|
||||
for(int i = 0; i < liquids.length; i ++){
|
||||
liquids[i] = other.liquids[i] * mul;
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Liquid liquid, float amount){
|
||||
liquids[liquid.id] += amount;
|
||||
current = liquid;
|
||||
@@ -180,6 +207,20 @@ public class LiquidModule extends BlockModule{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
var res = new StringBuilder();
|
||||
res.append("LiquidModule{ current=").append(current).append(", ");
|
||||
for(int i = 0; i < liquids.length; i++){
|
||||
if(liquids[i] > 0){
|
||||
res.append(content.liquid(i).name).append(":").append(liquids[i]).append(", ");
|
||||
}
|
||||
}
|
||||
res.setLength(res.length() - 2);
|
||||
res.append("}");
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
public interface LiquidConsumer{
|
||||
void accept(Liquid liquid, float amount);
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@ org.gradle.caching=true
|
||||
#used for slow jitpack builds; TODO see if this actually works
|
||||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
archash=77461f1c82
|
||||
archash=eb3b8bdd10
|
||||
|
||||
Reference in New Issue
Block a user