diff --git a/core/assets-raw/sprites/blocks/logic/logic-display.png b/core/assets-raw/sprites/blocks/logic/logic-display.png index fed3fab176..e9441e179f 100644 Binary files a/core/assets-raw/sprites/blocks/logic/logic-display.png and b/core/assets-raw/sprites/blocks/logic/logic-display.png differ diff --git a/core/assets/sprites/block_colors.png b/core/assets/sprites/block_colors.png index f790ea4ac8..3255514474 100644 Binary files a/core/assets/sprites/block_colors.png and b/core/assets/sprites/block_colors.png differ diff --git a/core/assets/sprites/fallback/sprites2.png b/core/assets/sprites/fallback/sprites2.png index 8e8fd49150..5da35b565b 100644 Binary files a/core/assets/sprites/fallback/sprites2.png and b/core/assets/sprites/fallback/sprites2.png differ diff --git a/core/assets/sprites/fallback/sprites4.png b/core/assets/sprites/fallback/sprites4.png index cd72cd4ae5..86b95c04e4 100644 Binary files a/core/assets/sprites/fallback/sprites4.png and b/core/assets/sprites/fallback/sprites4.png differ diff --git a/core/assets/sprites/fallback/sprites6.png b/core/assets/sprites/fallback/sprites6.png index a916939232..59d4c49cc3 100644 Binary files a/core/assets/sprites/fallback/sprites6.png and b/core/assets/sprites/fallback/sprites6.png differ diff --git a/core/assets/sprites/fallback/sprites7.png b/core/assets/sprites/fallback/sprites7.png index 594121076c..56a25b9a6e 100644 Binary files a/core/assets/sprites/fallback/sprites7.png and b/core/assets/sprites/fallback/sprites7.png differ diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index b163e6076d..17bca86130 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/sprites/sprites2.png b/core/assets/sprites/sprites2.png index f2d62c3ad1..a2b5e48d6f 100644 Binary files a/core/assets/sprites/sprites2.png and b/core/assets/sprites/sprites2.png differ diff --git a/core/assets/sprites/sprites4.png b/core/assets/sprites/sprites4.png index c3009b673b..a8aa1be195 100644 Binary files a/core/assets/sprites/sprites4.png and b/core/assets/sprites/sprites4.png differ diff --git a/core/assets/sprites/sprites5.png b/core/assets/sprites/sprites5.png index 49b9b1cbb9..b151e7da19 100644 Binary files a/core/assets/sprites/sprites5.png and b/core/assets/sprites/sprites5.png differ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 4c0ffa7268..30c65e917b 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1912,7 +1912,7 @@ public class Blocks implements ContentList{ logicDisplay = new LogicDisplay("logic-display"){{ requirements(Category.effect, with(Items.copper, 200, Items.lead, 120, Items.silicon, 100, Items.metaglass, 50)); - displaySize = 64; + displaySize = 80; size = 3; }}; diff --git a/core/src/mindustry/logic/BinaryOp.java b/core/src/mindustry/logic/BinaryOp.java index 6ceeae492c..3f3d0e9f52 100644 --- a/core/src/mindustry/logic/BinaryOp.java +++ b/core/src/mindustry/logic/BinaryOp.java @@ -7,6 +7,7 @@ public enum BinaryOp{ div("/", (a, b) -> a / b), mod("%", (a, b) -> a % b), equal("==", (a, b) -> Math.abs(a - b) < 0.000001 ? 1 : 0), + notEqual("not", (a, b) -> Math.abs(a - b) < 0.000001 ? 0 : 1), lessThan("<", (a, b) -> a < b ? 1 : 0), lessThanEq("<=", (a, b) -> a <= b ? 1 : 0), greaterThan(">", (a, b) -> a > b ? 1 : 0), diff --git a/core/src/mindustry/logic/ConditionOp.java b/core/src/mindustry/logic/ConditionOp.java new file mode 100644 index 0000000000..c85bc6f37a --- /dev/null +++ b/core/src/mindustry/logic/ConditionOp.java @@ -0,0 +1,29 @@ +package mindustry.logic; + +public enum ConditionOp{ + equal("==", (a, b) -> Math.abs(a - b) < 0.000001), + notEqual("not", (a, b) -> Math.abs(a - b) >= 0.000001), + lessThan("<", (a, b) -> a < b), + lessThanEq("<=", (a, b) -> a <= b), + greaterThan(">", (a, b) -> a > b), + greaterThanEq(">=", (a, b) -> a >= b); + + public static final ConditionOp[] all = values(); + + public final CondOpLambda function; + public final String symbol; + + ConditionOp(String symbol, CondOpLambda function){ + this.symbol = symbol; + this.function = function; + } + + @Override + public String toString(){ + return symbol; + } + + interface CondOpLambda{ + boolean get(double a, double b); + } +} diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 53183e7e12..0c0483782d 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -102,19 +102,14 @@ public class LCanvas extends Table{ } void load(String asm){ - statements.clearChildren(); - try{ - Seq statements = LAssembler.read(asm); - for(LStatement st : statements){ - add(st); - } + Seq statements = LAssembler.read(asm); + this.statements.clearChildren(); + for(LStatement st : statements){ + add(st); + } - for(LStatement st : statements){ - st.setupUI(); - } - }catch(Exception e){ - //ignore errors reading asm - e.printStackTrace(); + for(LStatement st : statements){ + st.setupUI(); } this.statements.layout(); @@ -272,6 +267,20 @@ public class LCanvas extends Table{ @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + + if(button == KeyCode.mouseMiddle){ + LStatement copy = st.copy(); + if(copy != null){ + StatementElem s = new StatementElem(copy); + + statements.addChildAfter(StatementElem.this,s); + statements.layout(); + copy.elem = s; + copy.setupUI(); + } + return false; + } + Vec2 v = localToStageCoordinates(Tmp.v1.set(x, y)); lastx = v.x; lasty = v.y; diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 20bf8c904e..d1af571fd8 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -373,19 +373,23 @@ public class LExecutor{ } public static class JumpI implements LInstruction{ - public int cond, to; + public ConditionOp op = ConditionOp.notEqual; + public int value, compare, address; - public JumpI(int cond, int to){ - this.cond = cond; - this.to = to; + public JumpI(ConditionOp op, int value, int compare, int address){ + this.op = op; + this.value = value; + this.compare = compare; + this.address = address; } - JumpI(){} + public JumpI(){ + } @Override public void run(LExecutor exec){ - if(to != -1 && exec.bool(cond)){ - exec.vars[varCounter].numval = to; + if(address != -1 && op.function.get(exec.num(value), exec.num(compare))){ + exec.vars[varCounter].numval = address; } } } diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index 36508ee21e..e26761926e 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -24,6 +24,13 @@ public abstract class LStatement{ public abstract LCategory category(); public abstract LInstruction build(LAssembler builder); + //TODO doesn't work with modded stuff + public LStatement copy(){ + StringBuilder build = new StringBuilder(); + write(build); + return LogicIO.read(build.toString().split(" ")); + } + //protected methods are only for internal UI layout utilities protected Cell field(Table table, String value, Cons setter){ diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index e333565fc1..343411b7fa 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -458,21 +458,31 @@ public class LStatements{ public transient StatementElem dest; public int destIndex; - public String condition = "true"; + + public ConditionOp op = ConditionOp.notEqual; + public String value = "x", compare = "false"; @Override public void build(Table table){ - table.add("if ").padLeft(6); - field(table, condition, str -> condition = str); + table.add("if ").padLeft(4); + + field(table, value, str -> value = str); + + table.button(b -> { + b.label(() -> op.symbol); + b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> op = o)); + }, Styles.logict, () -> {}).size(48f, 40f).pad(4f).color(table.color); + + field(table, compare, str -> compare = str); table.add().growX(); - table.add(new JumpButton(Color.white, () -> dest, s -> dest = s)).size(30).right().padRight(-17); + table.add(new JumpButton(Color.white, () -> dest, s -> dest = s)).size(30).right().padLeft(-8); } //elements need separate conversion logic @Override public void setupUI(){ - if(elem != null){ + if(elem != null && destIndex > 0 && destIndex < elem.parent.getChildren().size){ dest = (StatementElem)elem.parent.getChildren().get(destIndex); } } @@ -486,7 +496,7 @@ public class LStatements{ @Override public LInstruction build(LAssembler builder){ - return new JumpI(builder.var(condition),destIndex); + return new JumpI(op, builder.var(value), builder.var(compare), destIndex); } @Override diff --git a/core/src/mindustry/logic/LogicDialog.java b/core/src/mindustry/logic/LogicDialog.java index 1fa0df2375..3993ea0476 100644 --- a/core/src/mindustry/logic/LogicDialog.java +++ b/core/src/mindustry/logic/LogicDialog.java @@ -1,10 +1,16 @@ package mindustry.logic; +import arc.*; import arc.func.*; +import arc.scene.ui.TextButton.*; import arc.scene.ui.layout.*; import arc.util.*; +import mindustry.gen.*; +import mindustry.ui.*; import mindustry.ui.dialogs.*; +import static mindustry.Vars.*; + public class LogicDialog extends BaseDialog{ LCanvas canvas; Cons consumer = s -> Log.info(s); @@ -17,6 +23,34 @@ public class LogicDialog extends BaseDialog{ canvas = new LCanvas(); addCloseButton(); + buttons.button("@edit", Icon.edit, () -> { + BaseDialog dialog = new BaseDialog("@editor.export"); + dialog.cont.pane(p -> { + p.margin(10f); + p.table(Tex.button, t -> { + TextButtonStyle style = Styles.cleart; + t.defaults().size(280f, 60f).left(); + t.row(); + t.button("@schematic.copy.import", Icon.download, style, () -> { + dialog.hide(); + try{ + canvas.load(Core.app.getClipboardText()); + }catch(Throwable e){ + ui.showException(e); + } + }).marginLeft(12f).disabled(b -> Core.app.getClipboardText() == null); + t.row(); + t.button("@schematic.copy", Icon.copy, style, () -> { + dialog.hide(); + Core.app.setClipboardText(canvas.save()); + }).marginLeft(12f); + }); + }); + + dialog.addCloseButton(); + dialog.show(); + }); + stack(canvas, new Table(t -> { t.bottom(); t.add(buttons); @@ -28,7 +62,12 @@ public class LogicDialog extends BaseDialog{ } public void show(String code, Cons consumer){ - canvas.load(code); + try{ + canvas.load(code); + }catch(Throwable t){ + t.printStackTrace(); + canvas.load(""); + } this.consumer = consumer; show(); diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index 96bf1df6a6..5d9a4abe7e 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -1,6 +1,7 @@ package mindustry.world.blocks.logic; import arc.func.*; +import arc.math.geom.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; @@ -30,7 +31,24 @@ public class LogicBlock extends Block{ update = true; configurable = true; - config(String.class, (LogicEntity entity, String code) -> entity.updateCode(code)); + config(String.class, (LogicEntity entity, String value) -> { + if(value.startsWith("{")){ //it's json + try{ + LogicConfig conf = JsonIO.read(LogicConfig.class, value); + for(int i = 0; i < conf.connections.size; i++){ + int pos = conf.connections.items[i]; + conf.connections.items[i] = Point2.pack(Point2.x(pos) + entity.tileX(), Point2.y(pos) + entity.tileY()); + } + entity.connections = conf.connections; + entity.updateCode(conf.code); + }catch(Exception e){ + //malformed json + e.printStackTrace(); + } + }else{ //it's (probably) asm or just garbage + entity.updateCode(value); + } + }); config(Integer.class, (LogicEntity entity, Integer pos) -> { if(entity.connections.contains(pos)){ @@ -56,10 +74,10 @@ public class LogicBlock extends Block{ } public void updateCode(String str){ - updateCode(str, null); + updateCodeVars(str, null); } - public void updateCode(String str, Cons assemble){ + public void updateCodeVars(String str, Cons assemble){ if(str != null){ code = str; @@ -113,7 +131,6 @@ public class LogicBlock extends Block{ @Override public void updateTile(){ //remove invalid links - //TODO remove variables removal.clear(); for(int i = 0; i < connections.size; i++){ @@ -143,7 +160,13 @@ public class LogicBlock extends Block{ @Override public String config(){ - return code; + //set connections to use relative coordinates, not absolute (TODO maybe just store them like this?) + IntSeq copy = new IntSeq(connections); + for(int i = 0; i < copy.size; i++){ + int pos = copy.items[i]; + copy.items[i] = Point2.pack(Point2.x(pos) - tileX(), Point2.y(pos) - tileY()); + } + return JsonIO.write(new LogicConfig(code, copy)); } @Override @@ -275,7 +298,7 @@ public class LogicBlock extends Block{ memorybank[i] = read.d(); } - updateCode(code, asm -> { + updateCodeVars(code, asm -> { //load up the variables that were stored for(int i = 0; i < varcount; i++){ @@ -289,4 +312,17 @@ public class LogicBlock extends Block{ executor.memory = memorybank; } } + + public static class LogicConfig{ + public String code; + public IntSeq connections; + + public LogicConfig(String code, IntSeq connections){ + this.code = code; + this.connections = connections; + } + + public LogicConfig(){ + } + } } diff --git a/core/src/mindustry/world/blocks/logic/LogicDisplay.java b/core/src/mindustry/world/blocks/logic/LogicDisplay.java index 20743dfdd7..0c301474aa 100644 --- a/core/src/mindustry/world/blocks/logic/LogicDisplay.java +++ b/core/src/mindustry/world/blocks/logic/LogicDisplay.java @@ -22,6 +22,8 @@ public class LogicDisplay extends Block{ commandLinePoly = 7, commandFlush = 8; + public int maxSides = 25; + public int displaySize = 64; public LogicDisplay(String name){ @@ -70,8 +72,8 @@ public class LogicDisplay extends Block{ case commandLine: Lines.line(x, y, p1, p2); break; case commandRect: Fill.crect(x, y, p1, p2); break; case commandLineRect: Lines.rect(x, y, p1, p2); break; - case commandPoly: Fill.poly(x, y, p1, p2, p3); break; - case commandLinePoly: Lines.poly(x, y, p1, p2, p3); break; + case commandPoly: Fill.poly(x, y, Math.min(p1, maxSides), p2, p3); break; + case commandLinePoly: Lines.poly(x, y, Math.min(p1, maxSides), p2, p3); break; case commandColor: this.color = Color.toFloatBits(x, y, p1, 255); Draw.color(this.color); break; case commandStroke: this.stroke = x; Lines.stroke(x); break; }