isNull op / Return null for null block sense/NaNs
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -98,6 +99,10 @@ public class LExecutor{
|
|||||||
|
|
||||||
//region utility
|
//region utility
|
||||||
|
|
||||||
|
private static boolean invalid(double d){
|
||||||
|
return Double.isNaN(d) || Double.isInfinite(d);
|
||||||
|
}
|
||||||
|
|
||||||
public Var var(int index){
|
public Var var(int index){
|
||||||
//global constants have variable IDs < 0, and they are fetched from the global constants object after being negated
|
//global constants have variable IDs < 0, and they are fetched from the global constants object after being negated
|
||||||
return index < 0 ? constants.get(-index) : vars[index];
|
return index < 0 ? constants.get(-index) : vars[index];
|
||||||
@@ -120,12 +125,12 @@ public class LExecutor{
|
|||||||
|
|
||||||
public double num(int index){
|
public double num(int index){
|
||||||
Var v = var(index);
|
Var v = var(index);
|
||||||
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : v.numval;
|
return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : v.numval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float numf(int index){
|
public float numf(int index){
|
||||||
Var v = var(index);
|
Var v = var(index);
|
||||||
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : (float)v.numval;
|
return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : (float)v.numval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int numi(int index){
|
public int numi(int index){
|
||||||
@@ -139,9 +144,14 @@ public class LExecutor{
|
|||||||
public void setnum(int index, double value){
|
public void setnum(int index, double value){
|
||||||
Var v = var(index);
|
Var v = var(index);
|
||||||
if(v.constant) return;
|
if(v.constant) return;
|
||||||
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value;
|
if(invalid(value)){
|
||||||
v.objval = null;
|
v.objval = null;
|
||||||
v.isobj = false;
|
v.isobj = true;
|
||||||
|
}else{
|
||||||
|
v.numval = value;
|
||||||
|
v.objval = null;
|
||||||
|
v.isobj = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setobj(int index, Object value){
|
public void setobj(int index, Object value){
|
||||||
@@ -622,21 +632,21 @@ public class LExecutor{
|
|||||||
|
|
||||||
//note that remote units/buildings can be sensed as well
|
//note that remote units/buildings can be sensed as well
|
||||||
if(target instanceof Senseable se){
|
if(target instanceof Senseable se){
|
||||||
if(sense instanceof Content){
|
if(sense instanceof Content co){
|
||||||
exec.setnum(to, se.sense(((Content)sense)));
|
exec.setnum(to, se.sense(co));
|
||||||
}else if(sense instanceof LAccess){
|
}else if(sense instanceof LAccess la){
|
||||||
Object objOut = se.senseObject((LAccess)sense);
|
Object objOut = se.senseObject(la);
|
||||||
|
|
||||||
if(objOut == Senseable.noSensed){
|
if(objOut == Senseable.noSensed){
|
||||||
//numeric output
|
//numeric output
|
||||||
exec.setnum(to, se.sense((LAccess)sense));
|
exec.setnum(to, se.sense(la));
|
||||||
}else{
|
}else{
|
||||||
//object output
|
//object output
|
||||||
exec.setobj(to, objOut);
|
exec.setobj(to, objOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
exec.setnum(to, 0);
|
exec.setobj(to, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -752,7 +762,7 @@ public class LExecutor{
|
|||||||
v.objval = f.objval;
|
v.objval = f.objval;
|
||||||
v.isobj = true;
|
v.isobj = true;
|
||||||
}else{
|
}else{
|
||||||
v.numval = Double.isNaN(f.numval) || Double.isInfinite(f.numval) ? 0 : f.numval;
|
v.numval = invalid(f.numval) ? 0 : f.numval;
|
||||||
v.isobj = false;
|
v.isobj = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -774,7 +784,10 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
if(op.unary){
|
if(op == LogicOp.isNull){
|
||||||
|
var v = exec.var(a);
|
||||||
|
exec.setnum(dest, v.isobj && v.objval == null ? 1 : 0);
|
||||||
|
}else if(op.unary){
|
||||||
exec.setnum(dest, op.function1.get(exec.num(a)));
|
exec.setnum(dest, op.function1.get(exec.num(a)));
|
||||||
}else{
|
}else{
|
||||||
Var va = exec.var(a);
|
Var va = exec.var(a);
|
||||||
@@ -965,5 +978,37 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class WaitI implements LInstruction{
|
||||||
|
public int value;
|
||||||
|
|
||||||
|
public float curTime;
|
||||||
|
public double wait;
|
||||||
|
public long frameId;
|
||||||
|
|
||||||
|
public WaitI(int value){
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WaitI(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(LExecutor exec){
|
||||||
|
if(curTime >= exec.num(value)){
|
||||||
|
curTime = 0f;
|
||||||
|
}else{
|
||||||
|
//skip back to self.
|
||||||
|
exec.var(varCounter).numval --;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Core.graphics.getFrameId() != frameId){
|
||||||
|
curTime += Time.delta / 60f;
|
||||||
|
frameId = Core.graphics.getFrameId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -637,6 +637,28 @@ public class LStatements{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO untested
|
||||||
|
//@RegisterStatement("wait")
|
||||||
|
public static class WaitStatement extends LStatement{
|
||||||
|
public String value = "0.5";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
field(table, value, str -> value = str);
|
||||||
|
table.add(" sec");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color color(){
|
||||||
|
return Pal.logicOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LInstruction build(LAssembler builder){
|
||||||
|
return new WaitI(builder.var(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RegisterStatement("end")
|
@RegisterStatement("end")
|
||||||
public static class EndStatement extends LStatement{
|
public static class EndStatement extends LStatement{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public enum LogicOp{
|
|||||||
xor("xor", (a, b) -> (long)a ^ (long)b),
|
xor("xor", (a, b) -> (long)a ^ (long)b),
|
||||||
not("flip", a -> ~(long)(a)),
|
not("flip", a -> ~(long)(a)),
|
||||||
|
|
||||||
|
isNull("isNull", v -> v == 0 ? 1 : 0), //this lambda is not actually used
|
||||||
max("max", Math::max),
|
max("max", Math::max),
|
||||||
min("min", Math::min),
|
min("min", Math::min),
|
||||||
atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg),
|
atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg),
|
||||||
|
|||||||
Reference in New Issue
Block a user