diff --git a/core/src/mindustry/editor/MapView.java b/core/src/mindustry/editor/MapView.java index 4db21dec66..69ae67d7c9 100644 --- a/core/src/mindustry/editor/MapView.java +++ b/core/src/mindustry/editor/MapView.java @@ -243,14 +243,14 @@ public class MapView extends Element implements GestureListener{ image.setImageSize(editor.width(), editor.height()); - if(!ScissorStack.push(rect.set(x, y, width, height))){ + if(!ScissorStack.push(rect.set(x, y + Core.scene.marginBottom, width, height))){ return; } Draw.color(Pal.remove); Lines.stroke(2f); Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2); - editor.renderer.draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight); + editor.renderer.draw(centerx - sclwidth / 2, centery - sclheight / 2 + Core.scene.marginBottom, sclwidth, sclheight); Draw.reset(); if(grid){ diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 6dd6c6e1e4..28dfdd3d4a 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -84,8 +84,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, }else{ if(block.hasPower){ //reinit power graph - power.graph = new PowerGraph(); - power.graph.add(self()); + new PowerGraph().add(self()); } } this.rotation = rotation; diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 6793838128..29811c8205 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -44,6 +44,7 @@ public class LExecutor{ public LInstruction[] instructions = {}; public Var[] vars = {}; + public int[] binds; public LongSeq graphicsBuffer = new LongSeq(); public StringBuilder textBuffer = new StringBuilder(); @@ -182,9 +183,6 @@ public class LExecutor{ public static class UnitBindI implements LInstruction{ public int type; - //iteration index - private int index; - public UnitBindI(int type){ this.type = type; } @@ -195,17 +193,21 @@ public class LExecutor{ @Override public void run(LExecutor exec){ + if(exec.binds == null || exec.binds.length != content.units().size){ + exec.binds = new int[content.units().size]; + } + //binding to `null` was previously possible, but was too powerful and exploitable if(exec.obj(type) instanceof UnitType type){ Seq seq = exec.team.data().unitCache(type); if(seq != null && seq.any()){ - index %= seq.size; - if(index < seq.size){ + exec.binds[type.id] %= seq.size; + if(exec.binds[type.id] < seq.size){ //bind to the next unit - exec.setconst(varUnit, seq.get(index)); + exec.setconst(varUnit, seq.get(exec.binds[type.id])); } - index++; + exec.binds[type.id] ++; }else{ //no units of this type found exec.setconst(varUnit, null); diff --git a/core/src/mindustry/world/blocks/power/PowerGraph.java b/core/src/mindustry/world/blocks/power/PowerGraph.java index fdb19dc05c..813b183e3f 100644 --- a/core/src/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/mindustry/world/blocks/power/PowerGraph.java @@ -12,11 +12,22 @@ public class PowerGraph{ private static final Seq outArray1 = new Seq<>(); private static final Seq outArray2 = new Seq<>(); private static final IntSet closedSet = new IntSet(); + private static final PowerGraph nullGraph = new PowerGraph(){ + @Override + public void add(Building build){ + throw new RuntimeException("cannot add to null graph"); + } - private final ObjectSet producers = new ObjectSet<>(); - private final ObjectSet consumers = new ObjectSet<>(); - private final ObjectSet batteries = new ObjectSet<>(); - private final ObjectSet all = new ObjectSet<>(); + @Override + public void addGraph(PowerGraph graph){ + throw new RuntimeException("cannot add to null graph"); + } + }; + + private final Seq producers = new Seq<>(false); + private final Seq consumers = new Seq<>(false); + private final Seq batteries = new Seq<>(false); + private final Seq all = new Seq<>(false); private final WindowedMean powerBalance = new WindowedMean(60); private float lastPowerProduced, lastPowerNeeded, lastPowerStored; @@ -209,7 +220,6 @@ public class PowerGraph{ float powerNeeded = getPowerNeeded(); float powerProduced = getPowerProduced(); - float rawProduced = powerProduced; lastPowerNeeded = powerNeeded; lastPowerProduced = powerProduced; @@ -244,20 +254,24 @@ public class PowerGraph{ } } - public void add(Building tile){ - if(tile == null || tile.power == null) return; - tile.power.graph = this; - all.add(tile); + public void add(Building build){ + if(build == null || build.power == null) return; - if(tile.block.outputsPower && tile.block.consumesPower && !tile.block.consumes.getPower().buffered){ - producers.add(tile); - consumers.add(tile); - }else if(tile.block.outputsPower && tile.block.consumesPower){ - batteries.add(tile); - }else if(tile.block.outputsPower){ - producers.add(tile); - }else if(tile.block.consumesPower){ - consumers.add(tile); + if(build.power.graph != this || !build.power.init){ + build.power.graph = this; + build.power.init = true; + all.add(build); + + if(build.block.outputsPower && build.block.consumesPower && !build.block.consumes.getPower().buffered){ + producers.add(build); + consumers.add(build); + }else if(build.block.outputsPower && build.block.consumesPower){ + batteries.add(build); + }else if(build.block.outputsPower){ + producers.add(build); + }else if(build.block.consumesPower){ + consumers.add(build); + } } } @@ -278,10 +292,10 @@ public class PowerGraph{ } private void removeSingle(Building tile){ - all.remove(tile); - producers.remove(tile); - consumers.remove(tile); - batteries.remove(tile); + all.remove(tile, true); + producers.remove(tile, true); + consumers.remove(tile, true); + batteries.remove(tile, true); } public void remove(Building tile){ diff --git a/core/src/mindustry/world/blocks/power/PowerNode.java b/core/src/mindustry/world/blocks/power/PowerNode.java index 64f0bd38dc..33ac673c92 100644 --- a/core/src/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/mindustry/world/blocks/power/PowerNode.java @@ -318,8 +318,7 @@ public class PowerNode extends PowerBlock{ public void dropped(){ power.links.clear(); //create new power graph to manually unlink (this may be redundant) - power.graph = new PowerGraph(); - power.graph.add(this); + new PowerGraph().add(this); } @Override diff --git a/core/src/mindustry/world/modules/PowerModule.java b/core/src/mindustry/world/modules/PowerModule.java index c93a7d845f..99a45deefc 100644 --- a/core/src/mindustry/world/modules/PowerModule.java +++ b/core/src/mindustry/world/modules/PowerModule.java @@ -11,6 +11,7 @@ public class PowerModule extends BlockModule{ * In case of buffered consumers, this is the percentage of power stored in relation to the maximum capacity. */ public float status = 0.0f; + public boolean init; public PowerGraph graph = new PowerGraph(); public IntSeq links = new IntSeq(); diff --git a/tests/src/test/java/power/PowerTestFixture.java b/tests/src/test/java/power/PowerTestFixture.java index 701899a11e..457421a85c 100644 --- a/tests/src/test/java/power/PowerTestFixture.java +++ b/tests/src/test/java/power/PowerTestFixture.java @@ -95,14 +95,13 @@ public class PowerTestFixture{ // Simulate the "changed" method. Calling it through reflections would require half the game to be initialized. tile.build = block.newBuilding().init(tile, Team.sharded, false, 0); if(block.hasPower){ - tile.build.power.graph = new PowerGraph(){ + new PowerGraph(){ //assume there's always something consuming power @Override public float getUsageFraction(){ return 1f; } - }; - tile.build.power.graph.add(tile.build); + }.add(tile.build); } // Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound