Experimental flow display
This commit is contained in:
@@ -633,6 +633,7 @@ setting.shadows.name = Shadows
|
|||||||
setting.blockreplace.name = Automatic Block Suggestions
|
setting.blockreplace.name = Automatic Block Suggestions
|
||||||
setting.linear.name = Linear Filtering
|
setting.linear.name = Linear Filtering
|
||||||
setting.hints.name = Hints
|
setting.hints.name = Hints
|
||||||
|
setting.flow.name = Display Resource Flow Rate[scarlet] (experimental)
|
||||||
setting.buildautopause.name = Auto-Pause Building
|
setting.buildautopause.name = Auto-Pause Building
|
||||||
setting.animatedwater.name = Animated Water
|
setting.animatedwater.name = Animated Water
|
||||||
setting.animatedshields.name = Animated Shields
|
setting.animatedshields.name = Animated Shields
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import mindustry.world.*;
|
|||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
import mindustry.world.blocks.power.*;
|
import mindustry.world.blocks.power.*;
|
||||||
import mindustry.world.consumers.*;
|
import mindustry.world.consumers.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
import mindustry.world.modules.*;
|
import mindustry.world.modules.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -47,6 +48,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
transient Tile tile;
|
transient Tile tile;
|
||||||
transient Block block;
|
transient Block block;
|
||||||
transient Array<Tilec> proximity = new Array<>(8);
|
transient Array<Tilec> proximity = new Array<>(8);
|
||||||
|
transient boolean updateFlow;
|
||||||
|
|
||||||
PowerModule power;
|
PowerModule power;
|
||||||
ItemModule items;
|
ItemModule items;
|
||||||
@@ -764,9 +766,49 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
displayBars(bars);
|
displayBars(bars);
|
||||||
}).growX();
|
}).growX();
|
||||||
table.row();
|
table.row();
|
||||||
table.table(ctable -> {
|
table.table(this::displayConsumption).growX();
|
||||||
displayConsumption(ctable);
|
|
||||||
}).growX();
|
boolean displayFlow = (block.category == Category.distribution || block.category == Category.liquid) && Core.settings.getBool("flow");
|
||||||
|
|
||||||
|
if(displayFlow){
|
||||||
|
String ps = " " + StatUnit.perSecond.localized();
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
table.row();
|
||||||
|
table.table(l -> {
|
||||||
|
Bits presence = new Bits(content.items().size);
|
||||||
|
l.left();
|
||||||
|
|
||||||
|
Runnable rebuild = () -> {
|
||||||
|
l.clearChildren();
|
||||||
|
for(Item item : content.items()){
|
||||||
|
if(items.flownBits() != null && items.flownBits().get(item.id)){
|
||||||
|
l.addImage(item.icon(Cicon.small)).padRight(3f);
|
||||||
|
l.label(() -> items.getFlowRate(item) < 0 ? "..." : Strings.fixed(items.getFlowRate(item), 1) + ps).color(Color.lightGray);
|
||||||
|
l.row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rebuild.run();
|
||||||
|
l.update(() -> {
|
||||||
|
if(items.flownBits() != null && !presence.equals(items.flownBits())){
|
||||||
|
presence.set(items.flownBits());
|
||||||
|
rebuild.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(liquids != null){
|
||||||
|
table.row();
|
||||||
|
table.table(l -> {
|
||||||
|
l.left();
|
||||||
|
l.addImage(() -> liquids.current().icon(Cicon.small)).padRight(3f);
|
||||||
|
l.label(() -> liquids.getFlowRate() < 0 ? "..." : Strings.fixed(liquids.getFlowRate(), 2) + ps).color(Color.lightGray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table.marginBottom(-5);
|
table.marginBottom(-5);
|
||||||
}
|
}
|
||||||
@@ -934,8 +976,12 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
|
|
||||||
updateTile();
|
updateTile();
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
items.update(updateFlow);
|
||||||
|
}
|
||||||
|
|
||||||
if(liquids != null){
|
if(liquids != null){
|
||||||
liquids.update();
|
liquids.update(updateFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cons != null){
|
if(cons != null){
|
||||||
@@ -945,6 +991,8 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc{
|
|||||||
if(power != null){
|
if(power != null){
|
||||||
power.graph.update();
|
power.graph.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateFlow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
@@ -360,6 +360,8 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
if(!mobile){
|
if(!mobile){
|
||||||
Core.settings.put("swapdiagonal", false);
|
Core.settings.put("swapdiagonal", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graphics.checkPref("flow", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void back(){
|
private void back(){
|
||||||
|
|||||||
@@ -454,6 +454,9 @@ public class PlacementFragment extends Fragment{
|
|||||||
//setup hovering tile
|
//setup hovering tile
|
||||||
if(!Core.scene.hasMouse() && topTable.hit(v.x, v.y, false) == null){
|
if(!Core.scene.hasMouse() && topTable.hit(v.x, v.y, false) == null){
|
||||||
hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
hoverTile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||||
|
if(hoverTile != null && hoverTile.entity != null){
|
||||||
|
hoverTile.entity.updateFlow(true);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
hoverTile = null;
|
hoverTile = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,54 @@
|
|||||||
package mindustry.world.modules;
|
package mindustry.world.modules;
|
||||||
|
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.type.Item;
|
import mindustry.type.*;
|
||||||
import mindustry.type.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
|
|
||||||
import static mindustry.Vars.content;
|
import static mindustry.Vars.content;
|
||||||
|
|
||||||
public class ItemModule extends BlockModule{
|
public class ItemModule extends BlockModule{
|
||||||
private int[] items = new int[content.items().size];
|
private static final int windowSize = 10;
|
||||||
private int total;
|
|
||||||
|
|
||||||
|
protected int[] items = new int[content.items().size];
|
||||||
|
protected int total;
|
||||||
// Make the take() loop persistent so it does not return the same item twice in a row unless there is nothing else to return.
|
// Make the take() loop persistent so it does not return the same item twice in a row unless there is nothing else to return.
|
||||||
protected int takeRotation;
|
protected int takeRotation;
|
||||||
|
|
||||||
public void forEach(ItemConsumer cons){
|
private @Nullable WindowedMean[] flow;
|
||||||
|
private @Nullable Bits flownIds;
|
||||||
|
|
||||||
|
public void update(boolean showFlow){
|
||||||
|
if(showFlow){
|
||||||
|
if(flow == null){
|
||||||
|
flow = new WindowedMean[items.length];
|
||||||
|
flownIds = new Bits(items.length);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
flow = null;
|
||||||
|
flownIds = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return a specific item's flow rate in items/s; any value < 0 means not ready.*/
|
||||||
|
public float getFlowRate(Item item){
|
||||||
|
if(flow == null || flow[item.id] == null || flow[item.id].getValueCount() <= 2){
|
||||||
|
return - 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO this isn't very accurate
|
||||||
|
return 60f / ((flow[item.id].getLatest() - flow[item.id].getOldest()) / (flow[item.id].getValueCount() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Bits flownBits(){
|
||||||
|
return flownIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void each(ItemConsumer cons){
|
||||||
for(int i = 0; i < items.length; i++){
|
for(int i = 0; i < items.length; i++){
|
||||||
if(items[i] > 0){
|
if(items[i] > 0){
|
||||||
cons.accept(content.item(i), items[i]);
|
cons.accept(content.item(i), items[i]);
|
||||||
@@ -108,6 +141,11 @@ public class ItemModule extends BlockModule{
|
|||||||
public void add(Item item, int amount){
|
public void add(Item item, int amount){
|
||||||
items[item.id] += amount;
|
items[item.id] += amount;
|
||||||
total += amount;
|
total += amount;
|
||||||
|
if(flow != null){
|
||||||
|
if(flow[item.id] == null) flow[item.id] = new WindowedMean(windowSize);
|
||||||
|
flow[item.id].addValue(Time.time());
|
||||||
|
flownIds.set(item.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAll(ItemModule items){
|
public void addAll(ItemModule items){
|
||||||
|
|||||||
@@ -1,21 +1,45 @@
|
|||||||
package mindustry.world.modules;
|
package mindustry.world.modules;
|
||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.type.Liquid;
|
import mindustry.type.*;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
|
|
||||||
import static mindustry.Vars.content;
|
import static mindustry.Vars.content;
|
||||||
|
|
||||||
public class LiquidModule extends BlockModule{
|
public class LiquidModule extends BlockModule{
|
||||||
|
private static final int windowSize = 60, updateInterval = 60;
|
||||||
|
private static Interval flowTimer = new Interval(1);
|
||||||
|
|
||||||
private float[] liquids = new float[content.liquids().size];
|
private float[] liquids = new float[content.liquids().size];
|
||||||
private float total;
|
private float total;
|
||||||
private Liquid current = content.liquid(0);
|
private Liquid current = content.liquid(0);
|
||||||
private float smoothLiquid;
|
private float smoothLiquid;
|
||||||
|
|
||||||
public void update(){
|
private @Nullable WindowedMean flow;
|
||||||
|
private float lastAdded, currentFlowRate;
|
||||||
|
|
||||||
|
public void update(boolean showFlow){
|
||||||
smoothLiquid = Mathf.lerpDelta(smoothLiquid, currentAmount(), 0.1f);
|
smoothLiquid = Mathf.lerpDelta(smoothLiquid, currentAmount(), 0.1f);
|
||||||
|
if(showFlow){
|
||||||
|
if(flow == null) flow = new WindowedMean(windowSize);
|
||||||
|
flow.addValue(lastAdded);
|
||||||
|
lastAdded = 0;
|
||||||
|
if(currentFlowRate < 0 || flowTimer.get(updateInterval)){
|
||||||
|
currentFlowRate = flow.hasEnoughData() ? flow.getMean() : -1f;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
currentFlowRate = -1f;
|
||||||
|
flow = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return current liquid's flow rate in u/s; any value < 0 means 'not ready'. */
|
||||||
|
public float getFlowRate(){
|
||||||
|
return currentFlowRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float smoothAmount(){
|
public float smoothAmount(){
|
||||||
@@ -58,6 +82,10 @@ public class LiquidModule extends BlockModule{
|
|||||||
liquids[liquid.id] += amount;
|
liquids[liquid.id] += amount;
|
||||||
total += amount;
|
total += amount;
|
||||||
current = liquid;
|
current = liquid;
|
||||||
|
|
||||||
|
if(flow != null){
|
||||||
|
lastAdded += Math.max(amount, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(Liquid liquid, float amount){
|
public void remove(Liquid liquid, float amount){
|
||||||
|
|||||||
Reference in New Issue
Block a user