Turret-based radar

This commit is contained in:
Anuken
2020-08-10 23:04:52 -04:00
parent 4f7d6fc018
commit 75ada3cca1
19 changed files with 377 additions and 29 deletions

View File

@@ -1,5 +1,7 @@
package mindustry.logic;
import arc.math.*;
public enum BinaryOp{
add("+", (a, b) -> a + b),
sub("-", (a, b) -> a - b),
@@ -20,7 +22,8 @@ public enum BinaryOp{
xor("xor", (a, b) -> (int)a ^ (int)b),
max("max", Math::max),
min("min", Math::min),
atan2("atan2", Math::atan2);
atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg),
dst("dst", (x, y) -> Mathf.dst((float)x, (float)y));
public static final BinaryOp[] all = values();

View File

@@ -20,6 +20,9 @@ public enum LAccess{
rotation,
x,
y,
shootX,
shootY,
shooting,
//values with parameters are considered controllable
enabled("to"), //"to" is standard for single parameter access

View File

@@ -5,10 +5,14 @@ import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.blocks.logic.LogicDisplay.*;
import mindustry.world.blocks.logic.MessageBlock.*;
import static mindustry.Vars.*;
public class LExecutor{
//special variables
public static final int
@@ -87,7 +91,7 @@ public class LExecutor{
double num(int index){
Var v = vars[index];
return v.isobj ? 0 : v.numval;
return v.isobj ? 1 : v.numval;
}
int numi(int index){
@@ -229,6 +233,85 @@ public class LExecutor{
}
}
public static class RadarI implements LInstruction{
public RadarTarget target1 = RadarTarget.enemy, target2 = RadarTarget.any, target3 = RadarTarget.any;
public RadarSort sort = RadarSort.distance;
public int radar, sortOrder, output;
//radar instructions are special in that they cache their output and only change it at fixed intervals.
//this prevents lag from spam of radar instructions
public Healthc lastTarget;
public Interval timer = new Interval();
static float bestValue = 0f;
static Unit best = null;
public RadarI(RadarTarget target1, RadarTarget target2, RadarTarget target3, RadarSort sort, int radar, int sortOrder, int output){
this.target1 = target1;
this.target2 = target2;
this.target3 = target3;
this.sort = sort;
this.radar = radar;
this.sortOrder = sortOrder;
this.output = output;
}
public RadarI(){
}
@Override
public void run(LExecutor exec){
Building target = exec.building(radar);
int sortDir = exec.bool(sortOrder) ? 1 : -1;
if(target instanceof Ranged){
float range = ((Ranged)target).range();
Healthc targeted;
if(timer.get(20f)){
//if any of the targets involve enemies
boolean enemies = target1 == RadarTarget.enemy || target2 == RadarTarget.enemy || target3 == RadarTarget.enemy;
best = null;
bestValue = 0;
if(enemies){
for(Team enemy : state.teams.enemiesOf(target.team)){
find(target, range, sortDir, enemy);
}
}else{
find(target, range, sortDir, target.team);
}
lastTarget = targeted = best;
}else{
targeted = lastTarget;
}
exec.setobj(output, targeted);
}
}
void find(Building b, float range, int sortDir, Team team){
Units.nearby(team, b.x, b.y, range, u -> {
boolean valid =
target1.func.get(b.team, u) &&
target2.func.get(b.team, u) &&
target3.func.get(b.team, u);
if(!valid) return;
float val = sort.func.get(b, u) * sortDir;
if(val > bestValue || best == null){
bestValue = val;
best = u;
}
});
}
}
public static class SetI implements LInstruction{
public int from, to;

View File

@@ -1,5 +1,6 @@
package mindustry.logic;
import arc.func.*;
import arc.graphics.*;
import arc.scene.style.*;
import arc.scene.ui.*;
@@ -266,7 +267,7 @@ public class LStatements{
table.left();
table.add("set ");
table.add(" set ");
table.button(b -> {
b.label(() -> type.name());
@@ -304,6 +305,62 @@ public class LStatements{
}
}
@RegisterStatement("radar")
public static class RadarStatement extends LStatement{
public RadarTarget target1 = RadarTarget.enemy, target2 = RadarTarget.any, target3 = RadarTarget.any;
public RadarSort sort = RadarSort.distance;
public String radar = "@0", sortOrder = "0", output = "result";
@Override
public void build(Table table){
table.defaults().left();
table.add(" from ");
fields(table, radar, v -> radar = v);
table.row();
for(int i = 0; i < 3; i++){
int fi = i;
Prov<RadarTarget> get = () -> (fi == 0 ? target1 : fi == 1 ? target2 : target3);
table.add(i == 0 ? " target " : " and ");
table.button(b -> {
b.label(() -> get.get().name());
b.clicked(() -> showSelect(b, RadarTarget.all, get.get(), t -> {
if(fi == 0) target1 = t; else if(fi == 1) target2 = t; else target3 = t;
}, 2, cell -> cell.size(100, 50)));
}, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2);
if(i == 1){
table.row();
}
}
table.add(" order ");
fields(table, sortOrder, v -> sortOrder = v);
table.row();
table.add(" output ");
fields(table, output, v -> output = v);
}
@Override
public LCategory category(){
return LCategory.blocks;
}
@Override
public LInstruction build(LAssembler builder){
return new RadarI(target1, target2, target3, sort, builder.var(radar), builder.var(sortOrder), builder.var(output));
}
}
@RegisterStatement("sensor")
public static class SensorStatement extends LStatement{
public String to = "result";

View File

@@ -0,0 +1,20 @@
package mindustry.logic;
import arc.math.geom.*;
import mindustry.gen.*;
public enum RadarSort{
distance((pos, other) -> -pos.dst2(other)),
health((pos, other) -> other.health()),
maxHealth((pos, other) -> other.maxHealth());
public final RadarSortFunc func;
RadarSort(RadarSortFunc func){
this.func = func;
}
public interface RadarSortFunc{
float get(Position pos, Healthc other);
}
}

View File

@@ -0,0 +1,25 @@
package mindustry.logic;
import mindustry.game.*;
import mindustry.gen.*;
public enum RadarTarget{
any((team, other) -> true),
enemy((team, other) -> team != other.team),
ally((team, other) -> team == other.team),
player((team, other) -> other.isPlayer()),
flying((team, other) -> other.isFlying()),
ground((team, other) -> other.isGrounded());
public final RadarTargetFunc func;
public static final RadarTarget[] all = values();
RadarTarget(RadarTargetFunc func){
this.func = func;
}
public interface RadarTargetFunc{
boolean get(Team team, Unit other);
}
}

View File

@@ -0,0 +1,7 @@
package mindustry.logic;
import mindustry.gen.*;
public interface Ranged extends Posc, Teamc{
float range();
}