From a60772a81ec277b330e6b41f6213c858920e6161 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 7 Mar 2021 17:54:43 -0500 Subject: [PATCH] Fixed #4891 --- core/src/mindustry/io/TypeIO.java | 20 +++++- .../world/blocks/logic/LogicBlock.java | 65 +++++++++++++------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index e91ebedb6f..6e1ee0bd36 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -92,6 +92,9 @@ public class TypeIO{ }else if(object instanceof UnitCommand c){ write.b((byte)15); write.b(c.ordinal()); + }else if(object instanceof BuildingBox b){ + write.b(12); + write.i(b.pos); }else{ throw new IllegalArgumentException("Unknown object type: " + object.getClass()); } @@ -99,6 +102,12 @@ public class TypeIO{ @Nullable public static Object readObject(Reads read){ + return readObjectBoxed(read, false); + } + + /** Reads an object, but boxes buildings. */ + @Nullable + public static Object readObjectBoxed(Reads read, boolean box){ byte type = read.b(); switch(type){ case 0: return null; @@ -113,7 +122,7 @@ public class TypeIO{ case 9: return TechTree.getNotNull(content.getByID(ContentType.all[read.b()], read.s())); case 10: return read.bool(); case 11: return read.d(); - case 12: return world.build(read.i()); + case 12: return !box ? world.build(read.i()) : new BuildingBox(read.i()); case 13: return LAccess.all[read.s()]; case 14: int blen = read.i(); byte[] bytes = new byte[blen]; read.b(bytes); return bytes; case 15: return UnitCommand.all[read.b()]; @@ -600,4 +609,13 @@ public class TypeIO{ return null; } } + + /** Representes a building that has not been resolved yet. */ + public static class BuildingBox{ + public int pos; + + public BuildingBox(int pos){ + this.pos = pos; + } + } } diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index dace504cae..7cd1d031c6 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -1,5 +1,6 @@ package mindustry.world.blocks.logic; +import arc.*; import arc.func.*; import arc.math.geom.*; import arc.scene.ui.layout.*; @@ -13,6 +14,7 @@ import mindustry.core.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.io.*; +import mindustry.io.TypeIO.*; import mindustry.logic.*; import mindustry.logic.LAssembler.*; import mindustry.logic.LExecutor.*; @@ -195,7 +197,7 @@ public class LogicBlock extends Block{ public LExecutor executor = new LExecutor(); public float accumulator = 0; public Seq links = new Seq<>(); - public boolean checkedDuplicates = false; + public boolean checkedDuplicates = false, unboxed = false; public void readCompressed(byte[] data, boolean relative){ DataInputStream stream = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))); @@ -237,7 +239,7 @@ public class LogicBlock extends Block{ } } - links.add(new LogicLink(x, y, name, validLink(world.build(x, y)))); + links.add(new LogicLink(x, y, name, false)); } } @@ -247,6 +249,21 @@ public class LogicBlock extends Block{ } } + @Override + public void onProximityAdded(){ + super.onProximityAdded(); + + //unbox buildings after reading + if(!unboxed){ + for(var v : executor.vars){ + if(v.objval instanceof BuildingBox b){ + v.objval = world.build(b.pos); + } + } + unboxed = true; + } + } + public String findLinkName(Block block){ String bname = getLinkName(block); Bits taken = new Bits(links.size); @@ -300,6 +317,7 @@ public class LogicBlock extends Block{ //store link objects executor.links = new Building[links.count(l -> l.valid && l.active)]; executor.linkIds.clear(); + int index = 0; for(LogicLink link : links){ if(link.active && link.valid){ @@ -378,30 +396,35 @@ public class LogicBlock extends Block{ } //check for previously invalid links to add after configuration - boolean changed = false; + boolean changed = false, updates = true; - for(int i = 0; i < links.size; i++){ - LogicLink l = links.get(i); + while(updates){ + updates = false; - if(!l.active) continue; + for(int i = 0; i < links.size; i++){ + LogicLink l = links.get(i); - boolean valid = validLink(world.build(l.x, l.y)); - if(valid != l.valid){ - changed = true; - l.valid = valid; - if(valid){ - Building lbuild = world.build(l.x, l.y); + if(!l.active) continue; - //this prevents conflicts - l.name = ""; - //finds a new matching name after toggling - l.name = findLinkName(lbuild.block); + boolean valid = validLink(world.build(l.x, l.y)); + if(valid != l.valid){ + changed = true; + l.valid = valid; + if(valid){ + Building lbuild = world.build(l.x, l.y); - //remove redundant links - links.removeAll(o -> world.build(o.x, o.y) == lbuild && o != l); + //this prevents conflicts + l.name = ""; + //finds a new matching name after toggling + l.name = findLinkName(lbuild.block); - //break to prevent concurrent modification - break; + //remove redundant links + links.removeAll(o -> world.build(o.x, o.y) == lbuild && o != l); + + //break to prevent concurrent modification + updates = true; + break; + } } } } @@ -555,7 +578,7 @@ public class LogicBlock extends Block{ for(int i = 0; i < varcount; i++){ String name = read.str(); - Object value = TypeIO.readObject(read); + Object value = TypeIO.readObjectBoxed(read, true); names[i] = name; values[i] = value;