Sensor types

This commit is contained in:
Anuken 2020-08-08 18:01:54 -04:00
parent 4008d88f0b
commit da19c5ae19
16 changed files with 138 additions and 61 deletions

View file

@ -64,9 +64,9 @@ public class LogicStatementProcessor extends BaseProcessor{
reader.addStatement("$T result = new $T()", c.mirror(), c.mirror());
for(int i = 0; i < fields.size; i++){
Svar field = fields.get(i);
int index = 0;
for(Svar field : fields){
if(field.is(Modifier.TRANSIENT)) continue;
writer.addStatement("out.append(\" \")");
@ -74,12 +74,14 @@ public class LogicStatementProcessor extends BaseProcessor{
//reading primitives, strings and enums is supported; nothing else is
reader.addStatement("result.$L = $L(tokens[$L])",
field.name(),
field.mirror().toString().equals("java.lang.String") ?
"" : (field.tname().isPrimitive() ? field.tname().box().toString() :
field.mirror().toString()) + ".valueOf", //if it's not a string, it must have a valueOf method
i + 1
field.name(),
field.mirror().toString().equals("java.lang.String") ?
"" : (field.tname().isPrimitive() ? field.tname().box().toString() :
field.mirror().toString()) + ".valueOf", //if it's not a string, it must have a valueOf method
index + 1
);
index ++;
}
reader.addStatement("return result");

View file

@ -18,11 +18,13 @@ import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.audio.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
@ -37,7 +39,7 @@ import static mindustry.Vars.*;
@EntityDef(value = {Buildingc.class}, isFinal = false, genio = false, serialize = false)
@Component(base = true)
abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable{
abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Senseable{
//region vars and initialization
static final float timeToSleep = 60f * 1;
static final ObjectSet<Building> tmpTiles = new ObjectSet<>();
@ -1165,6 +1167,26 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
}
}
@Override
public double sense(LSensor sensor){
if(sensor == LSensor.health) return health;
if(sensor == LSensor.efficiency) return efficiency();
if(sensor == LSensor.totalItems && items != null) return items.total();
if(sensor == LSensor.totalLiquids && liquids != null) return liquids.total();
if(sensor == LSensor.totalPower && power != null) return power.status * (block.consumes.getPower().buffered ? block.consumes.getPower().capacity : 1f);
if(sensor == LSensor.powerNetIn && power != null) return power.graph.getPowerProduced();
if(sensor == LSensor.powerNetOut && power != null) return power.graph.getPowerNeeded();
if(sensor == LSensor.powerNetStored && power != null) return power.graph.getLastPowerStored();
return 0;
}
@Override
public double sense(Content content){
if(content instanceof Item && items != null) return items.get((Item)content);
if(content instanceof Liquid && liquids != null) return liquids.get((Liquid)content);
return 0;
}
@Override
public void remove(){
if(sound != null){

View file

@ -9,12 +9,14 @@ import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
@ -23,7 +25,7 @@ import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*;
@Component(base = true)
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable{
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Displayable, Senseable{
@Import boolean hovering;
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health;
@ -67,6 +69,19 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
return type.region.getWidth() * 2f;
}
@Override
public double sense(LSensor sensor){
if(sensor == LSensor.totalItems) return stack().amount;
if(sensor == LSensor.health) return health;
return 0;
}
@Override
public double sense(Content content){
if(content == stack().item) return stack().amount;
return 0;
}
@Override
public int itemCapacity(){
return type.itemCapacity;

View file

@ -16,6 +16,7 @@ import mindustry.entities.bullet.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.logic.*;
import mindustry.net.Administration.*;
import mindustry.net.Packets.*;
import mindustry.type.*;
@ -85,6 +86,9 @@ public class TypeIO{
}else if(object instanceof Building){
write.b((byte)12);
write.i(((Building)object).pos());
}else if(object instanceof LSensor){
write.b((byte)13);
write.s(((LSensor)object).ordinal());
}else{
throw new IllegalArgumentException("Unknown object type: " + object.getClass());
}
@ -107,6 +111,7 @@ public class TypeIO{
case 10: return read.bool();
case 11: return read.d();
case 12: return world.build(read.i());
case 13: return LSensor.all[read.s()];
default: throw new IllegalArgumentException("Unknown object type: " + type);
}
}

View file

@ -12,14 +12,14 @@ import mindustry.type.*;
public class LAssembler{
public static ObjectMap<String, Func<String[], LStatement>> customParsers = new ObjectMap<>();
private transient int lastVar;
private int lastVar;
/** Maps names to variable IDs. */
ObjectMap<String, BVar> vars = new ObjectMap<>();
/** All instructions to be executed. */
LInstruction[] instructions;
public LAssembler(){
putVar("@counter");
putVar("@counter").value = 0;
putConst("@time", 0);
//add default constants
@ -36,6 +36,12 @@ public class LAssembler{
for(Liquid liquid : Vars.content.liquids()){
putConst("@" + liquid.name, liquid);
}
//store sensor constants
for(LSensor sensor : LSensor.all){
putConst("@" + sensor.name(), sensor);
}
}
public static LAssembler assemble(String data){

View file

@ -3,8 +3,8 @@ package mindustry.logic;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.*;
import mindustry.ctype.*;
import mindustry.gen.*;
import mindustry.type.*;
public class LExecutor{
//special variables
@ -192,16 +192,16 @@ public class LExecutor{
@Override
public void run(LExecutor exec){
Building build = exec.building(from);
Object target = exec.obj(from);
Object sense = exec.obj(type);
double output = 0;
if(build != null){
if(sense instanceof Item && build.items != null){
output = build.items.get((Item)sense);
}else if(sense instanceof Liquid && build.liquids != null){
output = build.liquids.get((Liquid)sense);
if(target instanceof Senseable){
if(sense instanceof Content){
output = ((Senseable)target).sense(((Content)sense));
}else if(sense instanceof LSensor){
output = ((Senseable)target).sense(((LSensor)sense));
}
}
@ -285,7 +285,7 @@ public class LExecutor{
//this should avoid any garbage allocation
Var v = exec.vars[value];
if(v.isobj){
if(v.isobj && value != 0){
if(v.objval instanceof String){
b.handleString(v.objval);
}else if(v.objval == null){

View file

@ -0,0 +1,15 @@
package mindustry.logic;
public enum LSensor{
totalItems,
totalLiquids,
totalPower,
powerNetStored,
powerNetIn,
powerNetOut,
health,
heat,
efficiency;
public static final LSensor[] all = values();
}

View file

@ -1,10 +1,12 @@
package mindustry.logic;
import arc.func.*;
import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
import mindustry.gen.*;
import mindustry.logic.LCanvas.*;
import mindustry.logic.LExecutor.*;
import mindustry.ui.*;
/**
* A statement is an intermediate representation of an instruction, to be used mostly in UI.
@ -16,6 +18,11 @@ public abstract class LStatement{
public abstract LCategory category();
public abstract LInstruction build(LAssembler builder);
protected void field(Table table, String value, Cons<String> setter){
table.field(value, Styles.nodeField, setter)
.size(130f, 40f).pad(2f).color(table.color);
}
public void write(StringBuilder builder){
LogicIO.write(this,builder);
}

View file

@ -3,7 +3,6 @@ package mindustry.logic;
import arc.graphics.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.logic.LCanvas.*;
import mindustry.logic.LExecutor.*;
@ -18,15 +17,11 @@ public class LStatements{
@Override
public void build(Table table){
Log.info("mem:: ");
table.field(to, Styles.nodeField, str -> to = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, to, str -> to = str);
table.add(" = ");
table.field(from, Styles.nodeField, str -> from = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, from, str -> from = str);
}
@Override
@ -47,13 +42,11 @@ public class LStatements{
@Override
public void build(Table table){
table.field(to, Styles.nodeField, str -> to = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, to, str -> to = str);
table.add(" = mem:: ");
table.field(from, Styles.nodeField, str -> from = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, from, str -> from = str);
}
@Override
@ -74,18 +67,17 @@ public class LStatements{
@Override
public void build(Table table){
table.field(to, Styles.nodeField, str -> to = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, to, str -> to = str);
table.add(" = ");
table.field(type, Styles.nodeField, str -> type = str)
.size(100f, 40f).pad(2f).color(table.color);
table.row();
field(table, type, str -> type = str);
table.add(" in ");
table.field(from, Styles.nodeField, str -> from = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, from, str -> from = str);
}
@Override
@ -106,13 +98,11 @@ public class LStatements{
@Override
public void build(Table table){
table.field(to, Styles.nodeField, str -> to = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, to, str -> to = str);
table.add(" = ");
table.field(from, Styles.nodeField, str -> from = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, from, str -> from = str);
}
@Override
@ -133,13 +123,11 @@ public class LStatements{
@Override
public void build(Table table){
table.field(target, Styles.nodeField, str -> target = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, target, str -> target = str);
table.add(" -> ");
table.field(value, Styles.nodeField, str -> value = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, value, str -> value = str);
}
@Override
@ -160,14 +148,13 @@ public class LStatements{
@Override
public void build(Table table){
table.field(dest, Styles.nodeField, str -> dest = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, dest, str -> dest = str);
table.add(" = ");
table.field(a, Styles.nodeField, str -> a = str)
.size(90f, 40f).pad(2f).color(table.color);
table.row();
field(table, a, str -> a = str);
TextButton[] button = {null};
button[0] = table.button(op.symbol, Styles.cleart, () -> {
@ -175,8 +162,7 @@ public class LStatements{
button[0].setText(op.symbol);
}).size(50f, 30f).pad(4f).get();
table.field(b, Styles.nodeField, str -> b = str)
.size(90f, 40f).pad(2f).color(table.color);
field(table, b, str -> b = str);
}
@Override
@ -215,13 +201,11 @@ public class LStatements{
@Override
public void build(Table table){
table.field(value, Styles.nodeField, str -> value = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, value, str -> value = str);
table.add(" to ");
table.field(target, Styles.nodeField, str -> target = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, target, str -> target = str);
}
@Override
@ -245,8 +229,8 @@ public class LStatements{
@Override
public void build(Table table){
table.add("if ").padLeft(6);
table.field(condition, Styles.nodeField, str -> condition = str)
.size(100f, 40f).pad(2f).color(table.color);
field(table, condition, str -> condition = str);
table.add().growX();
table.add(new JumpButton(Color.white, () -> dest, s -> dest = s)).size(30).right().padRight(-17);
}

View file

@ -0,0 +1,8 @@
package mindustry.logic;
import mindustry.ctype.*;
public interface Senseable{
double sense(LSensor sensor);
double sense(Content content);
}

View file

@ -17,6 +17,7 @@ public class Router extends Block{
itemCapacity = 1;
group = BlockGroup.transportation;
unloadable = false;
noUpdateDisabled = true;
}
public class RouterEntity extends Building{

View file

@ -96,7 +96,7 @@ public class Sorter extends Block{
if(dir == -1) return null;
Building to;
if((item == sortItem) != invert){
if(((item == sortItem) != invert) == enabled){
//prevent 3-chains
if(isSame(source) && isSame(nearby(dir))){
return null;

View file

@ -13,6 +13,7 @@ import mindustry.entities.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.consumers.*;
@ -107,6 +108,12 @@ public class NuclearReactor extends PowerGenerator{
}
}
@Override
public double sense(LSensor sensor){
if(sensor == LSensor.heat) return heat;
return super.sense(sensor);
}
@Override
public void onDestroyed(){
super.onDestroyed();

View file

@ -39,7 +39,7 @@ public class PowerDiode extends Block{
// battery % of the graph on either side, defaults to zero
public float bar(Building tile){
return (tile != null && tile.block().hasPower) ? tile.power.graph.getBatteryStored() / tile.power.graph.getTotalBatteryCapacity() : 0f;
return (tile != null && tile.block().hasPower) ? tile.power.graph.getLastPowerStored() / tile.power.graph.getTotalBatteryCapacity() : 0f;
}
public class PowerDiodeEntity extends Building{

View file

@ -19,7 +19,7 @@ public class PowerGraph{
private final ObjectSet<Building> all = new ObjectSet<>();
private final WindowedMean powerBalance = new WindowedMean(60);
private float lastPowerProduced, lastPowerNeeded, lastUsageFraction;
private float lastPowerProduced, lastPowerNeeded, lastUsageFraction, lastPowerStored;
private long lastFrameUpdated = -1;
private final int graphID;
@ -45,6 +45,10 @@ public class PowerGraph{
return lastPowerProduced;
}
public float getLastPowerStored(){
return lastPowerStored;
}
public float getSatisfaction(){
if(Mathf.zero(lastPowerProduced)){
return 0f;
@ -196,6 +200,7 @@ public class PowerGraph{
lastPowerNeeded = powerNeeded;
lastPowerProduced = powerProduced;
lastPowerStored = getBatteryStored();
powerBalance.add((lastPowerProduced - lastPowerNeeded) / Time.delta);

View file

@ -109,9 +109,9 @@ public class PowerNode extends PowerBlock{
bars.add("batteries", entity -> new Bar(() ->
Core.bundle.format("bar.powerstored",
(UI.formatAmount((int)entity.power.graph.getBatteryStored())), UI.formatAmount((int)entity.power.graph.getTotalBatteryCapacity())),
(UI.formatAmount((int)entity.power.graph.getLastPowerStored())), UI.formatAmount((int)entity.power.graph.getTotalBatteryCapacity())),
() -> Pal.powerBar,
() -> Mathf.clamp(entity.power.graph.getBatteryStored() / entity.power.graph.getTotalBatteryCapacity())));
() -> Mathf.clamp(entity.power.graph.getLastPowerStored() / entity.power.graph.getTotalBatteryCapacity())));
}
@Override