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:
@@ -663,6 +663,7 @@ marker.shapetext.name = Shape Text
|
|||||||
marker.minimap.name = Minimap
|
marker.minimap.name = Minimap
|
||||||
marker.shape.name = Shape
|
marker.shape.name = Shape
|
||||||
marker.text.name = Text
|
marker.text.name = Text
|
||||||
|
marker.line.name = Line
|
||||||
|
|
||||||
marker.background = Background
|
marker.background = Background
|
||||||
marker.outline = Outline
|
marker.outline = Outline
|
||||||
@@ -2301,6 +2302,7 @@ lst.getflag = Check if a global flag is set.
|
|||||||
lst.setprop = Sets a property of a unit or building.
|
lst.setprop = Sets a property of a unit or building.
|
||||||
lst.effect = Create a particle effect.
|
lst.effect = Create a particle effect.
|
||||||
lst.sync = Sync a variable across the network.\nLimited to 20 times a second per variable.
|
lst.sync = Sync a variable across the network.\nLimited to 20 times a second per variable.
|
||||||
|
lst.marker = Control markers displayed in world.\nCannot control markers created by objectives.\nEach marker created by this instruction has its own id.
|
||||||
|
|
||||||
logic.nounitbuild = [red]Unit building logic is not allowed here.
|
logic.nounitbuild = [red]Unit building logic is not allowed here.
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import mindustry.game.MapObjectives.*;
|
|||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
|
import mindustry.logic.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
@@ -60,7 +61,8 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
ShapeTextMarker::new,
|
ShapeTextMarker::new,
|
||||||
MinimapMarker::new,
|
MinimapMarker::new,
|
||||||
ShapeMarker::new,
|
ShapeMarker::new,
|
||||||
TextMarker::new
|
TextMarker::new,
|
||||||
|
LineMarker::new
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,6 +605,8 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
public static abstract class ObjectiveMarker{
|
public static abstract class ObjectiveMarker{
|
||||||
/** Makes sure markers are only added once. */
|
/** Makes sure markers are only added once. */
|
||||||
public transient boolean wasAdded;
|
public transient boolean wasAdded;
|
||||||
|
//** Hides the marker, used by world processors */
|
||||||
|
public boolean hidden = false;
|
||||||
|
|
||||||
/** Called in the overlay draw layer.*/
|
/** Called in the overlay draw layer.*/
|
||||||
public void draw(){}
|
public void draw(){}
|
||||||
@@ -612,6 +616,14 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
public void added(){}
|
public void added(){}
|
||||||
/** Remove any UI elements, if necessary. */
|
/** Remove any UI elements, if necessary. */
|
||||||
public void removed(){}
|
public void removed(){}
|
||||||
|
/** Control marker with world processor code*/
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case toggleVisibility -> hidden = !hidden;
|
||||||
|
case setVisibility -> hidden = ((Math.abs(p1) < 1e-5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void setText(String text, boolean fetch){}
|
||||||
|
|
||||||
/** @return The localized type-name of this objective, defaulting to the class simple name without the "Marker" prefix. */
|
/** @return The localized type-name of this objective, defaulting to the class simple name without the "Marker" prefix. */
|
||||||
public String typeName(){
|
public String typeName(){
|
||||||
@@ -673,6 +685,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
|
if(hidden) return;
|
||||||
|
|
||||||
|
//in case some idiot decides to make 9999999 sides and freeze the game
|
||||||
|
int sides = Math.min(this.sides, 200);
|
||||||
|
|
||||||
Lines.stroke(3f, Pal.gray);
|
Lines.stroke(3f, Pal.gray);
|
||||||
Lines.poly(pos.x, pos.y, sides, radius + 1f, rotation);
|
Lines.poly(pos.x, pos.y, sides, radius + 1f, rotation);
|
||||||
Lines.stroke(1f, color);
|
Lines.stroke(1f, color);
|
||||||
@@ -685,6 +702,50 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
WorldLabel.drawAt(fetchedText, pos.x, pos.y + radius + textHeight, Draw.z(), flags, fontSize);
|
WorldLabel.drawAt(fetchedText, pos.x, pos.y + radius + textHeight, Draw.z(), flags, fontSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case x -> pos.x = (float)p1 * tilesize;
|
||||||
|
case y -> pos.y = (float)p1 * tilesize;
|
||||||
|
case pos -> pos.set((float)p1 * tilesize, (float)p2 * tilesize);
|
||||||
|
case fontSize -> fontSize = (float)p1;
|
||||||
|
case textHeight -> textHeight = (float)p1;
|
||||||
|
case labelBackground -> {
|
||||||
|
if((Math.abs(p1) >= 1e-5)){
|
||||||
|
flags |= WorldLabel.flagBackground;
|
||||||
|
}else{
|
||||||
|
flags &= ~WorldLabel.flagBackground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case labelOutline -> {
|
||||||
|
if((Math.abs(p1) >= 1e-5)){
|
||||||
|
flags |= WorldLabel.flagOutline;
|
||||||
|
}else{
|
||||||
|
flags &= ~WorldLabel.flagOutline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case labelFlags -> {
|
||||||
|
flags = ((Math.abs(p1) >= 1e-5) ? WorldLabel.flagBackground : 0);
|
||||||
|
if((Math.abs(p2) >= 1e-5)) flags |= WorldLabel.flagOutline;
|
||||||
|
}
|
||||||
|
case radius -> radius = (float)p1;
|
||||||
|
case rotation -> rotation = (float)p1;
|
||||||
|
case shapeSides -> sides = (int)p1;
|
||||||
|
case color -> color.set(Tmp.c1.fromDouble(p1));
|
||||||
|
default -> super.control(type, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text, boolean fetch){
|
||||||
|
this.text = text;
|
||||||
|
if(fetch){
|
||||||
|
fetchedText = fetchText(this.text);
|
||||||
|
}else{
|
||||||
|
fetchedText = this.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Displays a circle on the minimap. */
|
/** Displays a circle on the minimap. */
|
||||||
@@ -713,6 +774,8 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawMinimap(MinimapRenderer minimap){
|
public void drawMinimap(MinimapRenderer minimap){
|
||||||
|
if(hidden) return;
|
||||||
|
|
||||||
minimap.transform(Tmp.v1.set(pos.x * tilesize, pos.y * tilesize));
|
minimap.transform(Tmp.v1.set(pos.x * tilesize, pos.y * tilesize));
|
||||||
|
|
||||||
float rad = minimap.scale(radius * tilesize);
|
float rad = minimap.scale(radius * tilesize);
|
||||||
@@ -722,6 +785,19 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
Lines.circle(Tmp.v1.x, Tmp.v1.y, rad * fin);
|
Lines.circle(Tmp.v1.x, Tmp.v1.y, rad * fin);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case x -> pos.x = (int)p1;
|
||||||
|
case y -> pos.y = (int)p1;
|
||||||
|
case pos -> pos.set((int)p1, (int)p2);
|
||||||
|
case radius -> radius = (float)p1;
|
||||||
|
case stroke -> stroke = (float)p1;
|
||||||
|
case color -> color.set(Tmp.c1.fromDouble(p1));
|
||||||
|
default -> super.control(type, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Displays a shape with an outline and color. */
|
/** Displays a shape with an outline and color. */
|
||||||
@@ -746,6 +822,8 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
|
if(hidden) return;
|
||||||
|
|
||||||
//in case some idiot decides to make 9999999 sides and freeze the game
|
//in case some idiot decides to make 9999999 sides and freeze the game
|
||||||
int sides = Math.min(this.sides, 200);
|
int sides = Math.min(this.sides, 200);
|
||||||
|
|
||||||
@@ -764,6 +842,28 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case x -> pos.x = (float)p1 * tilesize;
|
||||||
|
case y -> pos.y = (float)p1 * tilesize;
|
||||||
|
case pos -> pos.set((float)p1 * tilesize, (float)p2 * tilesize);
|
||||||
|
case radius -> radius = (float)p1;
|
||||||
|
case rotation -> rotation = (float)p1;
|
||||||
|
case stroke -> stroke = (float)p1;
|
||||||
|
case shapeSides -> sides = (int)p1;
|
||||||
|
case shapeFill -> fill = (Math.abs(p1) >= 1e-5);
|
||||||
|
case shapeOutline -> outline = (Math.abs(p1) >= 1e-5);
|
||||||
|
case setShape -> {
|
||||||
|
sides = (int)p1;
|
||||||
|
fill = (Math.abs(p2) >= 1e-5);
|
||||||
|
outline = (Math.abs(p3) >= 1e-5);
|
||||||
|
}
|
||||||
|
case color -> color.set(Tmp.c1.fromDouble(p1));
|
||||||
|
default -> super.control(type, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Displays text at a location. */
|
/** Displays text at a location. */
|
||||||
@@ -791,12 +891,103 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
|
if(hidden) return;
|
||||||
|
|
||||||
if(fetchedText == null){
|
if(fetchedText == null){
|
||||||
fetchedText = fetchText(text);
|
fetchedText = fetchText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldLabel.drawAt(fetchedText, pos.x, pos.y, Draw.z(), flags, fontSize);
|
WorldLabel.drawAt(fetchedText, pos.x, pos.y, Draw.z(), flags, fontSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case x -> pos.x = (float)p1 * tilesize;
|
||||||
|
case y -> pos.y = (float)p1 * tilesize;
|
||||||
|
case pos -> pos.set((float)p1 * tilesize, (float)p2 * tilesize);
|
||||||
|
case fontSize -> fontSize = (float)p1;
|
||||||
|
case labelBackground -> {
|
||||||
|
if((Math.abs(p1) >= 1e-5)){
|
||||||
|
flags |= WorldLabel.flagBackground;
|
||||||
|
}else{
|
||||||
|
flags &= ~WorldLabel.flagBackground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case labelOutline -> {
|
||||||
|
if((Math.abs(p1) >= 1e-5)){
|
||||||
|
flags |= WorldLabel.flagOutline;
|
||||||
|
}else{
|
||||||
|
flags &= ~WorldLabel.flagOutline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case labelFlags -> {
|
||||||
|
flags = ((Math.abs(p1) >= 1e-5) ? WorldLabel.flagBackground : 0);
|
||||||
|
if((Math.abs(p2) >= 1e-5)) flags |= WorldLabel.flagOutline;
|
||||||
|
}
|
||||||
|
default -> super.control(type, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text, boolean fetch){
|
||||||
|
this.text = text;
|
||||||
|
if(fetch){
|
||||||
|
fetchedText = fetchText(this.text);
|
||||||
|
}else{
|
||||||
|
fetchedText = this.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Displays a line from pos1 to pos2. */
|
||||||
|
public static class LineMarker extends ObjectiveMarker{
|
||||||
|
public @TilePos Vec2 pos1 = new Vec2(), pos2 = new Vec2();
|
||||||
|
public float stroke = 1f;
|
||||||
|
public boolean outline = true;
|
||||||
|
public Color color = Color.valueOf("ffd37f");
|
||||||
|
|
||||||
|
public LineMarker(String text, float x1, float y1, float x2, float y2, float stroke){
|
||||||
|
this.stroke = stroke;
|
||||||
|
this.pos1.set(x1, y1);
|
||||||
|
this.pos2.set(x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineMarker(String text, float x1, float y1, float x2, float y2){
|
||||||
|
this.pos1.set(x1, y1);
|
||||||
|
this.pos2.set(x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineMarker(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void control(LMarkerControl type, double p1, double p2, double p3){
|
||||||
|
switch(type){
|
||||||
|
case x -> pos1.x = (float)p1 * tilesize;
|
||||||
|
case y -> pos1.y = (float)p1 * tilesize;
|
||||||
|
case pos -> pos1.set((float)p1 * tilesize, (float)p2 * tilesize);
|
||||||
|
case endX -> pos2.x = (float)p1 * tilesize;
|
||||||
|
case endY -> pos2.y = (float)p1 * tilesize;
|
||||||
|
case endPos -> pos2.set((float)p1 * tilesize, (float)p2 * tilesize);
|
||||||
|
case stroke -> stroke = (float)p1;
|
||||||
|
case shapeOutline -> outline = ((Math.abs(p1) >= 1e-5));
|
||||||
|
case color -> color.set(Tmp.c1.fromDouble(p1));
|
||||||
|
default -> super.control(type, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(){
|
||||||
|
if(hidden) return;
|
||||||
|
|
||||||
|
if(outline){
|
||||||
|
Lines.stroke(stroke + 2f, Pal.gray);
|
||||||
|
Lines.line(pos1.x, pos1.y, pos2.x, pos2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lines.stroke(stroke, color);
|
||||||
|
Lines.line(pos1.x, pos1.y, pos2.x, pos2.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For arrays or {@link Seq}s; does not create element rearrangement buttons. */
|
/** For arrays or {@link Seq}s; does not create element rearrangement buttons. */
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import arc.util.serialization.*;
|
|||||||
import arc.util.serialization.Json.*;
|
import arc.util.serialization.Json.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.MapObjectives.*;
|
||||||
import mindustry.graphics.g3d.*;
|
import mindustry.graphics.g3d.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
@@ -145,6 +146,8 @@ public class Rules{
|
|||||||
public MapObjectives objectives = new MapObjectives();
|
public MapObjectives objectives = new MapObjectives();
|
||||||
/** Flags set by objectives. Used in world processors. */
|
/** Flags set by objectives. Used in world processors. */
|
||||||
public ObjectSet<String> objectiveFlags = new ObjectSet<>();
|
public ObjectSet<String> objectiveFlags = new ObjectSet<>();
|
||||||
|
/** Markers not linked to objectives. Controlled by world processors. */
|
||||||
|
public IntMap<ObjectiveMarker> markers = new IntMap<>();
|
||||||
/** If true, fog of war is enabled. Enemy units and buildings are hidden unless in radar view. */
|
/** If true, fog of war is enabled. Enemy units and buildings are hidden unless in radar view. */
|
||||||
public boolean fog = false;
|
public boolean fog = false;
|
||||||
/** If fog = true, this is whether static (black) fog is enabled. */
|
/** If fog = true, this is whether static (black) fog is enabled. */
|
||||||
|
|||||||
@@ -258,6 +258,10 @@ public class MinimapRenderer{
|
|||||||
marker.drawMinimap(this);
|
marker.drawMinimap(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for(var marker : state.rules.markers.values()){
|
||||||
|
if(marker != null)marker.drawMinimap(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawSpawns(float x, float y, float w, float h, float scaling){
|
public void drawSpawns(float x, float y, float w, float h, float scaling){
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ public class OverlayRenderer{
|
|||||||
for(var marker : obj.markers) marker.draw();
|
for(var marker : obj.markers) marker.draw();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for(var marker : state.rules.markers.values()){
|
||||||
|
if(marker != null)marker.draw();
|
||||||
|
}
|
||||||
|
|
||||||
if(player.dead()) return; //dead players don't draw
|
if(player.dead()) return; //dead players don't draw
|
||||||
|
|
||||||
InputHandler input = control.input;
|
InputHandler input = control.input;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
|
import arc.util.serialization.*;
|
||||||
import mindustry.ai.*;
|
import mindustry.ai.*;
|
||||||
import mindustry.ai.types.*;
|
import mindustry.ai.types.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
@@ -16,6 +17,7 @@ import mindustry.entities.abilities.*;
|
|||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
|
import mindustry.game.MapObjectives.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.logic.*;
|
import mindustry.logic.*;
|
||||||
import mindustry.net.Administration.*;
|
import mindustry.net.Administration.*;
|
||||||
@@ -655,6 +657,19 @@ public class TypeIO{
|
|||||||
return JsonIO.read(MapObjectives.class, string);
|
return JsonIO.read(MapObjectives.class, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeObjectiveMarker(Writes write, ObjectiveMarker marker){
|
||||||
|
String string = JsonIO.json.toJson(marker, MapObjectives.ObjectiveMarker.class);
|
||||||
|
byte[] bytes = string.getBytes(charset);
|
||||||
|
write.i(bytes.length);
|
||||||
|
write.b(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjectiveMarker readObjectiveMarker(Reads read){
|
||||||
|
int length = read.i();
|
||||||
|
String string = new String(read.b(new byte[length]), charset);
|
||||||
|
return JsonIO.read(MapObjectives.ObjectiveMarker.class, string);
|
||||||
|
}
|
||||||
|
|
||||||
public static void writeVecNullable(Writes write, @Nullable Vec2 v){
|
public static void writeVecNullable(Writes write, @Nullable Vec2 v){
|
||||||
if(v == null){
|
if(v == null){
|
||||||
write.f(Float.NaN);
|
write.f(Float.NaN);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import mindustry.core.*;
|
|||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
|
import mindustry.game.MapObjectives.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.logic.LogicFx.*;
|
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
|
//endregion
|
||||||
}
|
}
|
||||||
|
|||||||
37
core/src/mindustry/logic/LMarkerControl.java
Normal file
37
core/src/mindustry/logic/LMarkerControl.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import arc.util.*;
|
|||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.logic.LCanvas.*;
|
import mindustry.logic.LCanvas.*;
|
||||||
@@ -1919,4 +1920,86 @@ public class LStatements{
|
|||||||
return LCategory.world;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user