Many things
This commit is contained in:
@@ -131,7 +131,7 @@ public class Annotations{
|
|||||||
/** Registers a logic node's slot. */
|
/** Registers a logic node's slot. */
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface NodeSlotDef{
|
public @interface Slot{
|
||||||
boolean input() default false;
|
boolean input() default false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import javax.annotation.processing.*;
|
|||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.type.*;
|
import javax.lang.model.type.*;
|
||||||
|
|
||||||
@SupportedAnnotationTypes("mindustry.annotations.Annotations.NodeSlotDef")
|
@SupportedAnnotationTypes("mindustry.annotations.Annotations.Slot")
|
||||||
public class NodeSlotProcessor extends BaseProcessor{
|
public class NodeSlotProcessor extends BaseProcessor{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -20,10 +20,10 @@ public class NodeSlotProcessor extends BaseProcessor{
|
|||||||
.addModifiers(Modifier.PUBLIC);
|
.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
ObjectMap<Stype, Seq<String>> fields = new ObjectMap<>();
|
ObjectMap<Stype, Seq<String>> fields = new ObjectMap<>();
|
||||||
for(Svar var : fields(NodeSlotDef.class)){
|
for(Svar var : fields(Slot.class)){
|
||||||
String type = var.mirror().toString();
|
String type = var.mirror().toString();
|
||||||
|
|
||||||
boolean overrideInput = var.annotation(NodeSlotDef.class).input();
|
boolean overrideInput = var.annotation(Slot.class).input();
|
||||||
boolean output = (type.contains("SetObj") || type.contains("SetNum") || type.contains("Runnable")) && !overrideInput;
|
boolean output = (type.contains("SetObj") || type.contains("SetNum") || type.contains("Runnable")) && !overrideInput;
|
||||||
|
|
||||||
String objType = output ?
|
String objType = output ?
|
||||||
|
|||||||
Binary file not shown.
BIN
core/assets/fonts/font.woff
Normal file
BIN
core/assets/fonts/font.woff
Normal file
Binary file not shown.
@@ -501,8 +501,8 @@ public class Blocks implements ContentList{
|
|||||||
siliconCrucible = new AttributeSmelter("silicon-crucible"){{
|
siliconCrucible = new AttributeSmelter("silicon-crucible"){{
|
||||||
requirements(Category.crafting, with(Items.titanium, 120, Items.metaglass, 80, Items.plastanium, 35, Items.silicon, 60));
|
requirements(Category.crafting, with(Items.titanium, 120, Items.metaglass, 80, Items.plastanium, 35, Items.silicon, 60));
|
||||||
craftEffect = Fx.smeltsmoke;
|
craftEffect = Fx.smeltsmoke;
|
||||||
outputItem = new ItemStack(Items.silicon, 5);
|
outputItem = new ItemStack(Items.silicon, 6);
|
||||||
craftTime = 140f;
|
craftTime = 90f;
|
||||||
size = 3;
|
size = 3;
|
||||||
hasPower = true;
|
hasPower = true;
|
||||||
hasLiquids = false;
|
hasLiquids = false;
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ public class Bullets implements ContentList{
|
|||||||
|
|
||||||
fragGlass = new FlakBulletType(4f, 3){{
|
fragGlass = new FlakBulletType(4f, 3){{
|
||||||
lifetime = 70f;
|
lifetime = 70f;
|
||||||
ammoMultiplier = 5f;
|
ammoMultiplier = 3f;
|
||||||
shootEffect = Fx.shootSmall;
|
shootEffect = Fx.shootSmall;
|
||||||
reloadMultiplier = 0.8f;
|
reloadMultiplier = 0.8f;
|
||||||
width = 6f;
|
width = 6f;
|
||||||
@@ -221,8 +221,8 @@ public class Bullets implements ContentList{
|
|||||||
fragExplosive = new FlakBulletType(4f, 5){{
|
fragExplosive = new FlakBulletType(4f, 5){{
|
||||||
shootEffect = Fx.shootBig;
|
shootEffect = Fx.shootBig;
|
||||||
ammoMultiplier = 4f;
|
ammoMultiplier = 4f;
|
||||||
splashDamage = 15f;
|
splashDamage = 18f;
|
||||||
splashDamageRadius = 34f;
|
splashDamageRadius = 55f;
|
||||||
collidesGround = true;
|
collidesGround = true;
|
||||||
|
|
||||||
status = StatusEffects.blasted;
|
status = StatusEffects.blasted;
|
||||||
@@ -230,7 +230,8 @@ public class Bullets implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
fragSurge = new FlakBulletType(4.5f, 13){{
|
fragSurge = new FlakBulletType(4.5f, 13){{
|
||||||
splashDamage = 45f;
|
ammoMultiplier = 4f;
|
||||||
|
splashDamage = 50f;
|
||||||
splashDamageRadius = 40f;
|
splashDamageRadius = 40f;
|
||||||
lightning = 2;
|
lightning = 2;
|
||||||
lightningLength = 7;
|
lightningLength = 7;
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ import arc.scene.*;
|
|||||||
import arc.scene.event.*;
|
import arc.scene.event.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.io.*;
|
||||||
import mindustry.logic.LogicNode.*;
|
import mindustry.logic.LogicNode.*;
|
||||||
|
import mindustry.logic.LogicNodes.*;
|
||||||
|
import mindustry.logic.SavedLogic.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
public class LogicCanvas extends WidgetGroup{
|
public class LogicCanvas extends WidgetGroup{
|
||||||
@@ -22,9 +24,38 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
|
|
||||||
private Element selected;
|
private Element selected;
|
||||||
private Element entered;
|
private Element entered;
|
||||||
private Seq<LogicNode> nodes = new Seq<>();
|
private Vec2 offset = new Vec2();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
addListener(new InputListener(){
|
||||||
|
float lastX, lastY;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void touchDragged(InputEvent event, float mx, float my, int pointer){
|
||||||
|
if(Core.app.isMobile() && pointer != 0) return;
|
||||||
|
|
||||||
|
float dx = mx - lastX, dy = my - lastY;
|
||||||
|
offset.add(dx, dy);
|
||||||
|
|
||||||
|
for(Element e : getChildren()){
|
||||||
|
e.moveBy(dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastX = mx;
|
||||||
|
lastY = my;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){
|
||||||
|
if((Core.app.isMobile() && pointer != 0) || (Core.app.isDesktop() && button != KeyCode.mouseMiddle)) return false;
|
||||||
|
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO debug stuff
|
||||||
add(new BinaryOpNode());
|
add(new BinaryOpNode());
|
||||||
add(new BinaryOpNode());
|
add(new BinaryOpNode());
|
||||||
add(new BinaryOpNode());
|
add(new BinaryOpNode());
|
||||||
@@ -34,15 +65,73 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
add(new ConditionNode());
|
add(new ConditionNode());
|
||||||
add(new ConditionNode());
|
add(new ConditionNode());
|
||||||
add(new SignalNode());
|
add(new SignalNode());
|
||||||
|
add(new SequenceNode());
|
||||||
|
|
||||||
|
Log.info(JsonIO.print(JsonIO.write(save())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(LogicNode node){
|
private void add(LogicNode node){
|
||||||
LogicElement e = new LogicElement(node);
|
NodeElement e = new NodeElement(node);
|
||||||
e.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f);
|
e.setPosition(Core.graphics.getWidth()/2f, Core.graphics.getHeight()/2f);
|
||||||
addChild(e);
|
addChild(e);
|
||||||
e.pack();
|
e.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SavedLogic save(){
|
||||||
|
|
||||||
|
//convert elements to saved nodes for writing to JSON
|
||||||
|
return new SavedLogic(getChildren().<NodeElement>as().map(e -> {
|
||||||
|
SavedNode node = new SavedNode();
|
||||||
|
node.state = e.node;
|
||||||
|
node.x = e.x;
|
||||||
|
node.y = e.y;
|
||||||
|
node.connections = new SavedConnection[e.slots.length];
|
||||||
|
|
||||||
|
for(int i = 0; i < e.slots.length; i++){
|
||||||
|
SavedConnection con = (node.connections[i] = new SavedConnection());
|
||||||
|
SlotElement slot = e.slots[i];
|
||||||
|
|
||||||
|
if(slot.connection != null){
|
||||||
|
SlotElement to = slot.connection;
|
||||||
|
|
||||||
|
con.node = getChildren().indexOf(to.node);
|
||||||
|
con.slot = Structs.indexOf(to.node.slots, to);
|
||||||
|
}else{
|
||||||
|
con.node = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}).toArray(SavedNode.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(SavedLogic state){
|
||||||
|
clear();
|
||||||
|
|
||||||
|
//add nodes as children first to make sure they can be accessed.
|
||||||
|
for(SavedNode node : state.nodes){
|
||||||
|
NodeElement elem = new NodeElement(node.state);
|
||||||
|
elem.setPosition(node.x, node.y);
|
||||||
|
addChild(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//assign connection data
|
||||||
|
for(int i = 0; i < state.nodes.length; i++){
|
||||||
|
SavedNode node = state.nodes[i];
|
||||||
|
NodeElement elem = (NodeElement)getChildren().get(i);
|
||||||
|
|
||||||
|
for(int j = 0; j < node.connections.length; j++){
|
||||||
|
SavedConnection con = node.connections[j];
|
||||||
|
if(con.node >= 0 && con.node < state.nodes.length){
|
||||||
|
SlotElement slot = elem.slots[j];
|
||||||
|
slot.connection = ((NodeElement)getChildren().get(con.node)).slots[con.slot];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.pack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.color(backgroundCol);
|
Draw.color(backgroundCol);
|
||||||
@@ -52,17 +141,18 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
Draw.color(gridCol);
|
Draw.color(gridCol);
|
||||||
|
|
||||||
float spacing = Scl.scl(50f);
|
float spacing = Scl.scl(50f);
|
||||||
int xbars = (int)(width / spacing) + 1, ybars = (int)(width / spacing) + 1;
|
int xbars = (int)(width / spacing) + 2, ybars = (int)(width / spacing) + 2;
|
||||||
|
float ox = offset.x % spacing, oy = offset.y % spacing;
|
||||||
|
|
||||||
Lines.stroke(Scl.scl(3f));
|
Lines.stroke(Scl.scl(3f));
|
||||||
|
|
||||||
for(int i = 0; i < xbars; i++){
|
for(int i = 0; i < xbars; i++){
|
||||||
float cx = x + width/2f + (i - xbars/2) * spacing;
|
float cx = x + width/2f + (i - xbars/2) * spacing + ox;
|
||||||
Lines.line(cx, y, cx, y + height);
|
Lines.line(cx, y, cx, y + height);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < ybars; i++){
|
for(int i = 0; i < ybars; i++){
|
||||||
float cy = y + height/2f + (i - ybars/2) * spacing;
|
float cy = y + height/2f + (i - ybars/2) * spacing + oy;
|
||||||
Lines.line(0, cy, x + width, cy);
|
Lines.line(0, cy, x + width, cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,17 +161,17 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
super.draw();
|
super.draw();
|
||||||
|
|
||||||
for(Element e : getChildren()){
|
for(Element e : getChildren()){
|
||||||
if(e instanceof LogicElement){
|
if(e instanceof NodeElement){
|
||||||
LogicElement l = (LogicElement)e;
|
NodeElement l = (NodeElement)e;
|
||||||
|
|
||||||
for(SlotTable field : l.slots){
|
for(SlotElement field : l.slots){
|
||||||
field.drawConnection();
|
field.drawConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selected != null){
|
if(selected != null){
|
||||||
SlotTable field = (SlotTable)selected.userObject;
|
SlotElement field = (SlotElement)selected.userObject;
|
||||||
Vec2 dest = selected.localToStageCoordinates(Tmp.v1.set(selected.getWidth()/2f, selected.getHeight()/2f));
|
Vec2 dest = selected.localToStageCoordinates(Tmp.v1.set(selected.getWidth()/2f, selected.getHeight()/2f));
|
||||||
Vec2 mouse = Core.input.mouse();
|
Vec2 mouse = Core.input.mouse();
|
||||||
drawCurve(dest.x, dest.y, mouse.x, mouse.y, field.color);
|
drawCurve(dest.x, dest.y, mouse.x, mouse.y, field.color);
|
||||||
@@ -104,20 +194,13 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogicElement extends Table{
|
class NodeElement extends Table{
|
||||||
final LogicNode node;
|
final LogicNode node;
|
||||||
final SlotTable[] slots;
|
SlotElement[] slots;
|
||||||
|
Table slotTable;
|
||||||
|
|
||||||
LogicElement(LogicNode node){
|
NodeElement(LogicNode node){
|
||||||
this.node = node;
|
this.node = node;
|
||||||
nodes.add(node);
|
|
||||||
|
|
||||||
NodeSlot[] nslots = node.slots();
|
|
||||||
|
|
||||||
this.slots = new SlotTable[nslots.length];
|
|
||||||
for(int i = 0; i < nslots.length; i++){
|
|
||||||
this.slots[i] = new SlotTable(nslots[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
background(Tex.whitePane);
|
background(Tex.whitePane);
|
||||||
setColor(node.category().color);
|
setColor(node.category().color);
|
||||||
@@ -136,7 +219,6 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
t.button(Icon.cancel, Styles.onlyi, () -> {
|
t.button(Icon.cancel, Styles.onlyi, () -> {
|
||||||
//TODO disconnect things
|
//TODO disconnect things
|
||||||
remove();
|
remove();
|
||||||
nodes.remove(node);
|
|
||||||
});
|
});
|
||||||
t.addListener(new InputListener(){
|
t.addListener(new InputListener(){
|
||||||
float lastx, lasty;
|
float lastx, lasty;
|
||||||
@@ -167,16 +249,32 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
|
|
||||||
row();
|
row();
|
||||||
|
|
||||||
defaults().height(30);
|
table(t -> slotTable = t).fill();
|
||||||
|
|
||||||
for(SlotTable field : slots){
|
rebuildSlots();
|
||||||
add(field).align(field.slot.input ? Align.left : Align.right);
|
|
||||||
row();
|
|
||||||
}
|
|
||||||
|
|
||||||
marginBottom(7);
|
marginBottom(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebuildSlots(){
|
||||||
|
slotTable.clear();
|
||||||
|
slotTable.defaults().height(30);
|
||||||
|
|
||||||
|
NodeSlot[] nslots = node.slots();
|
||||||
|
|
||||||
|
this.slots = new SlotElement[nslots.length];
|
||||||
|
for(int i = 0; i < nslots.length; i++){
|
||||||
|
this.slots[i] = new SlotElement(this, nslots[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(SlotElement field : slots){
|
||||||
|
slotTable.add(field).growX().align(field.slot.input ? Align.left : Align.right);
|
||||||
|
slotTable.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
pack();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
float pad = 10f;
|
float pad = 10f;
|
||||||
@@ -190,14 +288,16 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SlotTable extends Table{
|
class SlotElement extends Table{
|
||||||
final NodeSlot slot;
|
final NodeSlot slot;
|
||||||
|
final NodeElement node;
|
||||||
|
|
||||||
ImageButton button;
|
ImageButton button;
|
||||||
Element connection;
|
SlotElement connection;
|
||||||
|
|
||||||
SlotTable(NodeSlot slot){
|
SlotElement(NodeElement node, NodeSlot slot){
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
|
this.node = node;
|
||||||
|
|
||||||
setColor(slot.type.color);
|
setColor(slot.type.color);
|
||||||
|
|
||||||
@@ -221,8 +321,9 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
|
|
||||||
void drawConnection(){
|
void drawConnection(){
|
||||||
if(connection != null){
|
if(connection != null){
|
||||||
Vec2 from = localToStageCoordinates(Tmp.v2.set(button.getX() + button.getWidth()/2f, button.getY() + button.getHeight()/2f));
|
ImageButton cb = connection.button;
|
||||||
Vec2 to = connection.localToStageCoordinates(Tmp.v1.set(connection.getWidth()/2f, connection.getHeight()/2f));
|
Vec2 from = localToStageCoordinates(Tmp.v2.set(button.x + button.getWidth()/2f, button.y + button.getHeight()/2f));
|
||||||
|
Vec2 to = cb.localToStageCoordinates(Tmp.v1.set(cb.getWidth()/2f, cb.getHeight()/2f));
|
||||||
|
|
||||||
drawCurve(from.x, from.y, to.x, to.y, color);
|
drawCurve(from.x, from.y, to.x, to.y, color);
|
||||||
}
|
}
|
||||||
@@ -249,10 +350,13 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
button.addListener(new InputListener(){
|
button.addListener(new InputListener(){
|
||||||
@Override
|
@Override
|
||||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode code){
|
public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode code){
|
||||||
if(selected == null){
|
|
||||||
|
if(selected == null && !slot.input){
|
||||||
selected = button;
|
selected = button;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -265,11 +369,11 @@ public class LogicCanvas extends WidgetGroup{
|
|||||||
localToStageCoordinates(Tmp.v1.set(x, y));
|
localToStageCoordinates(Tmp.v1.set(x, y));
|
||||||
Element element = entered;
|
Element element = entered;
|
||||||
|
|
||||||
if(element != null && element.userObject instanceof SlotTable){
|
if(element != null && element.userObject instanceof SlotElement){
|
||||||
SlotTable field = (SlotTable)element.userObject;
|
SlotElement field = (SlotElement)element.userObject;
|
||||||
//make sure inputs are matched to outputs, and that slot types match
|
//make sure inputs are matched to outputs, and that slot types match
|
||||||
if(field != SlotTable.this && field.slot.input != slot.input && field.slot.type == slot.type){
|
if(field != SlotElement.this && field.slot.input != slot.input && field.slot.type == slot.type){
|
||||||
connection = element;
|
connection = field;
|
||||||
//field.connection = button;
|
//field.connection = button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
|
|
||||||
public class LogicDialog extends BaseDialog{
|
public class LogicDialog extends BaseDialog{
|
||||||
@@ -9,8 +10,12 @@ public class LogicDialog extends BaseDialog{
|
|||||||
super("logic");
|
super("logic");
|
||||||
|
|
||||||
canvas = new LogicCanvas();
|
canvas = new LogicCanvas();
|
||||||
|
addCloseButton();
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
add(canvas).grow();
|
stack(canvas, new Table(t -> {
|
||||||
|
t.bottom();
|
||||||
|
t.add(buttons);
|
||||||
|
})).grow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
45
core/src/mindustry/logic/LogicExecutor.java
Normal file
45
core/src/mindustry/logic/LogicExecutor.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import mindustry.logic.LogicNode.*;
|
||||||
|
import mindustry.logic.SavedLogic.*;
|
||||||
|
|
||||||
|
public class LogicExecutor{
|
||||||
|
/** all logical operations to be executed */
|
||||||
|
private LogicOp[] ops = {};
|
||||||
|
/** current operation index */
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
/** Set up executor state based on saved data. */
|
||||||
|
public void setup(SavedLogic save){
|
||||||
|
LogicNode[] out = new LogicNode[save.nodes.length];
|
||||||
|
|
||||||
|
//copy over the state so connections can be assigned
|
||||||
|
for(int i = 0; i < out.length; i++){
|
||||||
|
out[i] = save.nodes[i].state;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < out.length; i++){
|
||||||
|
LogicNode node = out[i];
|
||||||
|
NodeSlot[] slots = node.slots();
|
||||||
|
|
||||||
|
//connect node's slots to other nodes' slots
|
||||||
|
for(int j = 0; j < save.nodes[i].connections.length; j++){
|
||||||
|
SavedConnection con = save.nodes[i].connections[j];
|
||||||
|
NodeSlot slot = slots[j];
|
||||||
|
|
||||||
|
if(con.node != -1){
|
||||||
|
LogicNode other = out[con.node];
|
||||||
|
NodeSlot[] otherSlots = other.slots();
|
||||||
|
NodeSlot otherSlot = otherSlots[con.slot];
|
||||||
|
|
||||||
|
//slot.objOutput = (aslot, aobj) -> ((ObjOutput)otherSlot.objOutput).set(other, aobj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A single logical statement. */
|
||||||
|
static class LogicOp{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
package mindustry.logic;
|
package mindustry.logic;
|
||||||
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.scene.ui.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.*;
|
|
||||||
import mindustry.annotations.Annotations.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.*;
|
|
||||||
|
|
||||||
/** Base class for a type of logic node. */
|
/** Base class for a type of logic node. */
|
||||||
public abstract class LogicNode{
|
public abstract class LogicNode{
|
||||||
@@ -27,96 +23,6 @@ public abstract class LogicNode{
|
|||||||
return getClass().getSimpleName().replace("Node", "");
|
return getClass().getSimpleName().replace("Node", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BinaryOpNode extends LogicNode{
|
|
||||||
public BinaryOp op = BinaryOp.add;
|
|
||||||
@NodeSlotDef
|
|
||||||
public double a, b;
|
|
||||||
@NodeSlotDef
|
|
||||||
public SetNum result = val -> {};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void build(Table table){
|
|
||||||
//TODO replace with dropdown menu
|
|
||||||
TextButton[] button = {null};
|
|
||||||
button[0] = table.button(op.symbol, Styles.cleart, () -> {
|
|
||||||
op = BinaryOp.all[(op.ordinal() + 1) % BinaryOp.all.length];
|
|
||||||
button[0].setText(op.symbol);
|
|
||||||
}).size(100f, 40f).pad(2f).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
result.set(op.function.get(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeCategory category(){
|
|
||||||
return NodeCategory.operations;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ConditionNode extends LogicNode{
|
|
||||||
@NodeSlotDef(input = true)
|
|
||||||
public Runnable input = this::run;
|
|
||||||
@NodeSlotDef
|
|
||||||
public double condition;
|
|
||||||
@NodeSlotDef
|
|
||||||
public Runnable yes, no;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
if(condition > 0){
|
|
||||||
yes.run();
|
|
||||||
}else{
|
|
||||||
no.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeCategory category(){
|
|
||||||
return NodeCategory.controlFlow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NumberNode extends LogicNode{
|
|
||||||
@NodeSlotDef
|
|
||||||
public SetNum value;
|
|
||||||
public double var;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void build(Table table){
|
|
||||||
table.field(var + "", Styles.nodeField, str -> var = Strings.parseDouble(str, var))
|
|
||||||
.valid(Strings::canParsePositiveFloat)
|
|
||||||
.size(100f, 40f).pad(2f).color(table.color)
|
|
||||||
.update(f -> f.setColor(f.isValid() ? table.color : Color.white));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
value.set(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeCategory category(){
|
|
||||||
return NodeCategory.controlFlow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SignalNode extends LogicNode{
|
|
||||||
@NodeSlotDef
|
|
||||||
public Runnable run;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
run.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeCategory category(){
|
|
||||||
return NodeCategory.controlFlow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A field for a node, either an input or output. */
|
/** A field for a node, either an input or output. */
|
||||||
public static class NodeSlot{
|
public static class NodeSlot{
|
||||||
/** The slot's display name. */
|
/** The slot's display name. */
|
||||||
@@ -138,10 +44,6 @@ public abstract class LogicNode{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static{
|
|
||||||
new NodeSlot("a", true, DataType.number, (BinaryOpNode node, double val) -> node.a = val, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface NumOutput<N>{
|
public interface NumOutput<N>{
|
||||||
void set(N node, double val);
|
void set(N node, double val);
|
||||||
}
|
}
|
||||||
|
|||||||
123
core/src/mindustry/logic/LogicNodes.java
Normal file
123
core/src/mindustry/logic/LogicNodes.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package mindustry.logic;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.scene.ui.*;
|
||||||
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
public class LogicNodes{
|
||||||
|
public static class BinaryOpNode extends LogicNode{
|
||||||
|
public BinaryOp op = BinaryOp.add;
|
||||||
|
@Slot
|
||||||
|
public double a, b;
|
||||||
|
@Slot
|
||||||
|
public transient SetNum result = val -> {};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
//TODO replace with dropdown menu
|
||||||
|
TextButton[] button = {null};
|
||||||
|
button[0] = table.button(op.symbol, Styles.cleart, () -> {
|
||||||
|
op = BinaryOp.all[(op.ordinal() + 1) % BinaryOp.all.length];
|
||||||
|
button[0].setText(op.symbol);
|
||||||
|
}).size(100f, 40f).pad(2f).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
result.set(op.function.get(a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeCategory category(){
|
||||||
|
return NodeCategory.operations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConditionNode extends LogicNode{
|
||||||
|
@Slot(input = true)
|
||||||
|
public transient Runnable input = this::run;
|
||||||
|
@Slot
|
||||||
|
public double condition;
|
||||||
|
@Slot
|
||||||
|
public transient Runnable yes, no;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
if(condition > 0){
|
||||||
|
yes.run();
|
||||||
|
}else{
|
||||||
|
no.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeCategory category(){
|
||||||
|
return NodeCategory.controlFlow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NumberNode extends LogicNode{
|
||||||
|
@Slot
|
||||||
|
public transient SetNum value;
|
||||||
|
public double var;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
table.field(var + "", Styles.nodeField, str -> var = parseDouble(str))
|
||||||
|
.size(100f, 40f).pad(2f).color(table.color)
|
||||||
|
.update(f -> f.setColor(f.isValid() ? table.color : Color.white));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
value.set(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeCategory category(){
|
||||||
|
return NodeCategory.controlFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double parseDouble(String s){
|
||||||
|
return s.equals("yes") || s.equals("true") ? 1 :
|
||||||
|
s.equals("no") || s.equals("false") ? 0 :
|
||||||
|
Strings.parseDouble(s, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SequenceNode extends LogicNode{
|
||||||
|
@Slot(input = true)
|
||||||
|
public transient Runnable input = this::run;
|
||||||
|
@Slot
|
||||||
|
public transient Runnable first, second;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
first.run();
|
||||||
|
second.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeCategory category(){
|
||||||
|
return NodeCategory.controlFlow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SignalNode extends LogicNode{
|
||||||
|
@Slot
|
||||||
|
public transient Runnable run;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
run.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeCategory category(){
|
||||||
|
return NodeCategory.controlFlow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
core/src/mindustry/logic/SavedLogic.java
Normal file
26
core/src/mindustry/logic/SavedLogic.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package mindustry.logic;
|
||||||
|
|
||||||
|
/** The saved state of a logic board. */
|
||||||
|
public class SavedLogic{
|
||||||
|
public SavedNode[] nodes;
|
||||||
|
|
||||||
|
public SavedLogic(SavedNode[] nodes){
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SavedNode{
|
||||||
|
/** Uninitialized state containing only relevant configuration. */
|
||||||
|
public LogicNode state;
|
||||||
|
/** Connections of this node. */
|
||||||
|
public SavedConnection[] connections;
|
||||||
|
/** x/y positions of the bottom left corner of the node */
|
||||||
|
public float x, y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SavedConnection{
|
||||||
|
/** Node ID (in the array) that is being connected to. -1 means no connection */
|
||||||
|
public int node;
|
||||||
|
/** Slot number in the node */
|
||||||
|
public int slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,15 +52,14 @@ public class MirrorFilter extends GenerateFilter{
|
|||||||
float imageHeight = Math.max(vsize.y, vsize.x);
|
float imageHeight = Math.max(vsize.y, vsize.x);
|
||||||
|
|
||||||
float size = Math.max(image.getWidth() *2, image.getHeight()*2);
|
float size = Math.max(image.getWidth() *2, image.getHeight()*2);
|
||||||
Cons<Vec2> clamper = v ->
|
Cons<Vec2> clamper = v -> v.clamp(
|
||||||
v.clamp(
|
image.x + image.getWidth()/2f - imageWidth/2f,
|
||||||
image.getX() + image.getWidth()/2f - imageWidth/2f,
|
image.x + image.getWidth()/2f + imageWidth/2f,
|
||||||
image.getX() + image.getWidth()/2f + imageWidth/2f,
|
image.y + image.getHeight()/2f - imageHeight/2f,
|
||||||
image.getY() + image.getHeight()/2f - imageHeight/2f,
|
image.y + image.getHeight()/2f + imageHeight/2f);
|
||||||
image.getY() + image.getHeight()/2f + imageHeight/2f);
|
|
||||||
|
|
||||||
clamper.get(Tmp.v1.trns(angle - 90, size).add(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()));
|
clamper.get(Tmp.v1.trns(angle - 90, size).add(image.getWidth()/2f + image.x, image.getHeight()/2f + image.y));
|
||||||
clamper.get(Tmp.v2.set(Tmp.v1).sub(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()).rotate(180f).add(image.getWidth()/2f + image.getX(), image.getHeight()/2f + image.getY()));
|
clamper.get(Tmp.v2.set(Tmp.v1).sub(image.getWidth()/2f + image.x, image.getHeight()/2f + image.y).rotate(180f).add(image.getWidth()/2f + image.x, image.getHeight()/2f + image.y));
|
||||||
|
|
||||||
Lines.stroke(Scl.scl(3f), Pal.accent);
|
Lines.stroke(Scl.scl(3f), Pal.accent);
|
||||||
Lines.line(Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
Lines.line(Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import mindustry.core.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Fonts{
|
public class Fonts{
|
||||||
|
private static final String mainFont = "fonts/font.woff";
|
||||||
private static ObjectIntMap<String> unicodeIcons = new ObjectIntMap<>();
|
private static ObjectIntMap<String> unicodeIcons = new ObjectIntMap<>();
|
||||||
private static ObjectMap<String, String> stringIcons = new ObjectMap<>();
|
private static ObjectMap<String, String> stringIcons = new ObjectMap<>();
|
||||||
|
|
||||||
@@ -58,12 +59,10 @@ public class Fonts{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadFonts(){
|
public static void loadFonts(){
|
||||||
String fontName = "fonts/font.ttf";
|
|
||||||
|
|
||||||
FreeTypeFontParameter param = fontParameter();
|
FreeTypeFontParameter param = fontParameter();
|
||||||
|
|
||||||
Core.assets.load("default", Font.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.def = (Font)f;
|
Core.assets.load("default", Font.class, new FreeTypeFontLoaderParameter(mainFont, param)).loaded = f -> Fonts.def = (Font)f;
|
||||||
Core.assets.load("chat", Font.class, new FreeTypeFontLoaderParameter(fontName, param)).loaded = f -> Fonts.chat = (Font)f;
|
Core.assets.load("chat", Font.class, new FreeTypeFontLoaderParameter(mainFont, param)).loaded = f -> Fonts.chat = (Font)f;
|
||||||
Core.assets.load("icon", Font.class, new FreeTypeFontLoaderParameter("fonts/icon.ttf", new FreeTypeFontParameter(){{
|
Core.assets.load("icon", Font.class, new FreeTypeFontLoaderParameter("fonts/icon.ttf", new FreeTypeFontParameter(){{
|
||||||
size = 30;
|
size = 30;
|
||||||
incremental = true;
|
incremental = true;
|
||||||
@@ -146,7 +145,7 @@ public class Fonts{
|
|||||||
size = 18;
|
size = 18;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Core.assets.load("outline", Font.class, new FreeTypeFontLoaderParameter("fonts/font.ttf", param)).loaded = t -> Fonts.outline = (Font)t;
|
Core.assets.load("outline", Font.class, new FreeTypeFontLoaderParameter(mainFont, param)).loaded = t -> Fonts.outline = (Font)t;
|
||||||
|
|
||||||
Core.assets.load("tech", Font.class, new FreeTypeFontLoaderParameter("fonts/tech.ttf", new FreeTypeFontParameter(){{
|
Core.assets.load("tech", Font.class, new FreeTypeFontLoaderParameter("fonts/tech.ttf", new FreeTypeFontParameter(){{
|
||||||
size = 18;
|
size = 18;
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ public class GridImage extends Element{
|
|||||||
int jumpy = (int)(Math.max(minspace, yspace) / yspace);
|
int jumpy = (int)(Math.max(minspace, yspace) / yspace);
|
||||||
|
|
||||||
for(int x = 0; x <= imageWidth; x += jumpx){
|
for(int x = 0; x <= imageWidth; x += jumpx){
|
||||||
Fill.crect((int)(getX() + xspace * x - s), getY() - s, 2, getHeight() + (x == imageWidth ? 1 : 0));
|
Fill.crect((int)(this.x + xspace * x - s), y - s, 2, getHeight() + (x == imageWidth ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int y = 0; y <= imageHeight; y += jumpy){
|
for(int y = 0; y <= imageHeight; y += jumpy){
|
||||||
Fill.crect(getX() - s, (int)(getY() + y * yspace - s), getWidth(), 2);
|
Fill.crect(x - s, (int)(this.y + y * yspace - s), getWidth(), 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
infoTable.update(() -> infoTable.setPosition(button.getX() + button.getWidth(), button.getY() + button.getHeight(), Align.topLeft));
|
infoTable.update(() -> infoTable.setPosition(button.x + button.getWidth(), button.y + button.getHeight(), Align.topLeft));
|
||||||
|
|
||||||
infoTable.left();
|
infoTable.left();
|
||||||
infoTable.background(Tex.button).margin(8f);
|
infoTable.background(Tex.button).margin(8f);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class ChatFragment extends Table{
|
|||||||
Draw.color(shadowColor);
|
Draw.color(shadowColor);
|
||||||
|
|
||||||
if(shown){
|
if(shown){
|
||||||
Fill.crect(offsetx, chatfield.getY(), chatfield.getWidth() + 15f, chatfield.getHeight() - 1);
|
Fill.crect(offsetx, chatfield.y, chatfield.getWidth() + 15f, chatfield.getHeight() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.draw();
|
super.draw();
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class ScriptConsoleFragment extends Table{
|
|||||||
Draw.color(shadowColor);
|
Draw.color(shadowColor);
|
||||||
|
|
||||||
if(open){
|
if(open){
|
||||||
Fill.crect(offsetx, chatfield.getY(), chatfield.getWidth() + 15f, chatfield.getHeight() - 1);
|
Fill.crect(offsetx, chatfield.y, chatfield.getWidth() + 15f, chatfield.getHeight() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.draw();
|
super.draw();
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class GenericCrafter extends Block{
|
|||||||
update = true;
|
update = true;
|
||||||
solid = true;
|
solid = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
health = 60;
|
|
||||||
idleSound = Sounds.machine;
|
idleSound = Sounds.machine;
|
||||||
sync = true;
|
sync = true;
|
||||||
idleSoundVolume = 0.03f;
|
idleSoundVolume = 0.03f;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class FontGenerator{
|
|||||||
Log.info("Icon font...");
|
Log.info("Icon font...");
|
||||||
|
|
||||||
ZipFi zip = new ZipFi(folder.child("font.zip"));
|
ZipFi zip = new ZipFi(folder.child("font.zip"));
|
||||||
Fi dest = folder.child("font.ttf");
|
Fi dest = folder.child("font.woff");
|
||||||
zip.list()[0].child("font").child("fontello.ttf").copyTo(dest);
|
zip.list()[0].child("font").child("fontello.ttf").copyTo(dest);
|
||||||
dest.copyTo(Fi.get("core/assets/fonts/icon.ttf"));
|
dest.copyTo(Fi.get("core/assets/fonts/icon.ttf"));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user