Add marker instruction to world processors (#9087)

* Basic implementation of world processor marker control

* Add line marker, some marker control fixes

* Add remote for setting markers, add marker writer/reader to TypeIO

* Add sides cap to ShapeTextMarker's draw() method

* Marker instruction code refactor, revert accident auto-formatting, fix marker control bugs

* Cleanup LMarkerControl.java

* Remove deleted marker controls from MapObjectives

* Marker control method refactor, fix minimap marker rendering

* Refactor, proper double comparsion in MapObjectives

* Fix line marker's color not changing through world processors
This commit is contained in:
ApsZoldat
2023-09-28 00:17:59 +03:00
committed by GitHub
parent 6310d54b53
commit 8c777e79fa
9 changed files with 400 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.game.*;
import mindustry.game.MapObjectives.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.logic.LogicFx.*;
@@ -1841,5 +1842,63 @@ public class LExecutor{
}
}
public static class MarkerI implements LInstruction{
public LMarkerControl type = LMarkerControl.create;
public int id, p1, p2, p3;
public MarkerI(LMarkerControl type, int id, int p1, int p2, int p3){
this.type = type;
this.id = id;
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
public MarkerI(){
}
@Override
public void run(LExecutor exec){
ObjectiveMarker marker = null;
if(type == LMarkerControl.create){
int type = exec.numi(p1);
if(0 <= type && type < MapObjectives.allMarkerTypes.size){
marker = MapObjectives.allMarkerTypes.get(type).get();
if(marker != null){
state.rules.markers.put(exec.numi(id), marker);
marker.control(LMarkerControl.pos, exec.num(p2), exec.num(p3), 0);
}
}
return;
}else if(type == LMarkerControl.remove){
state.rules.markers.remove(exec.numi(id));
}else{
marker = state.rules.markers.get(exec.numi(id));
}
if(marker == null) return;
Var var = exec.var(p1);
if(!var.isobj){
marker.control(type, exec.num(p1), exec.num(p2), exec.num(p3));
}else{
if(type == LMarkerControl.text){
marker.setText((exec.obj(p1) != null ? exec.obj(p1).toString() : "null"), true);
}else if(type == LMarkerControl.flushText){
marker.setText(exec.textBuffer.toString(), false);
exec.textBuffer.setLength(0);
}
}
Call.setMarker(exec.numi(id), marker);
}
}
@Remote(called = Loc.server, variants = Variant.both, unreliable = true)
public static void setMarker(int id, ObjectiveMarker marker){
state.rules.markers.put(id, marker);
}
//endregion
}

View File

@@ -0,0 +1,37 @@
package mindustry.logic;
public enum LMarkerControl{
create("type", "x", "y"),
remove,
setVisibility("true/false"),
toggleVisibility,
text("text"),
flushText,
x("x"),
y("y"),
pos("x", "y"),
endX("x"),
endY("y"),
endPos("x", "y"),
fontSize("size"),
textHeight("height"),
labelBackground("true/false"),
labelOutline("true/false"),
labelFlags("background", "outline"),
radius("radius"),
stroke("stroke"),
rotation("rotation"),
shapeSides("sides"),
shapeFill("true/false"),
shapeOutline("true/false"),
setShape("sides", "fill", "outline"),
color("color");
public final String[] params;
public static final LMarkerControl[] all = values();
LMarkerControl(String... params){
this.params = params;
}
}

View File

@@ -10,6 +10,7 @@ import arc.util.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.logic.LCanvas.*;
@@ -1394,7 +1395,7 @@ public class LStatements{
}
case ban, unban -> {
table.add(" block/unit ");
field(table, value, s -> value = s);
}
default -> {
@@ -1919,4 +1920,86 @@ public class LStatements{
return LCategory.world;
}
}
@RegisterStatement("marker")
public static class MarkerStatement extends LStatement{
public LMarkerControl type = LMarkerControl.create;
public String id = "0", p1 = "0", p2 = "0", p3 = "0";
@Override
public void build(Table table){
rebuild(table);
}
void rebuild(Table table){
table.clearChildren();
table.button(b -> {
b.label(() -> type.name());
b.clicked(() -> showSelect(b, LMarkerControl.all, type, t -> {
type = t;
rebuild(table);
}, 2, cell -> cell.size(140, 50)));
}, Styles.logict, () -> {}).size(190, 40).color(table.color).left().padLeft(2);
table.add(" marker# ");
fields(table, id, str -> id = str);
if(type == LMarkerControl.create){
fields(table, type.params[0], p1, v -> p1 = v).padRight(0f).left();
table.button(b -> {
b.image(Icon.pencilSmall);
b.clicked(() -> showSelectTable(b, (t, hide) -> {
t.row();
t.table(i -> {
i.left();
int c = 0;
for(var gen : MapObjectives.allMarkerTypes){
var marker = gen.get();
i.button(marker.typeName(), Styles.flatt, () -> {
p1 = Integer.toString(MapObjectives.allMarkerTypes.indexOf(gen));
rebuild(table);
hide.run();
}).size(140, 40);
if(++c % 2 == 0) i.row();
}
}).colspan(3).width(280f).left();
}));
}, Styles.logict, () -> {}).size(40f).padLeft(-2).color(table.color);
fields(table, type.params[1], p2, v -> p2 = v);
fields(table, type.params[2], p3, v -> p3 = v);
}else{
//Q: why don't you just use arrays for this?
//A: arrays aren't as easy to serialize so the code generator doesn't handle them
int c = 0;
for(int i = 0; i < type.params.length; i++){
fields(table, type.params[i], i == 0 ? p1 : i == 1 ? p2 : p3, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : v -> p3 = v).width(100f);
if(++c % 2 == 0) row(table);
if(i == 3){
table.row();
}
}
}
}
@Override
public boolean privileged(){
return true;
}
@Override
public LInstruction build(LAssembler builder){
return new MarkerI(type, builder.var(id), builder.var(p1), builder.var(p2), builder.var(p3));
}
@Override
public LCategory category(){
return LCategory.world;
}
}
}