diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index ea2e8abb26..f9e5efdadd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.IntSet; import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.Queue; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.Consume; import io.anuke.mindustry.world.consumers.ConsumePower; import io.anuke.mindustry.world.consumers.Consumers; import io.anuke.ucore.util.Mathf; @@ -48,7 +49,10 @@ public class PowerGraph{ for(Tile consumer : consumers){ Consumers consumes = consumer.block().consumes; if(consumes.has(ConsumePower.class)){ - powerNeeded += consumes.get(ConsumePower.class).requestedPower(consumer.block(), consumer.entity) * consumer.entity.delta(); + ConsumePower consumePower = consumes.get(ConsumePower.class); + if(otherConsumersAreValid(consumer, consumePower)){ + powerNeeded += consumePower.requestedPower(consumer.block(), consumer.entity) * consumer.entity.delta(); + } } } return powerNeeded; @@ -119,12 +123,16 @@ public class PowerGraph{ Consumers consumes = consumer.block().consumes; if(consumes.has(ConsumePower.class)){ ConsumePower consumePower = consumes.get(ConsumePower.class); - if(consumePower.isBuffered){ - // Add an equal percentage of power to all buffers, based on the global power coverage in this graph - float maximumRate = consumePower.requestedPower(consumer.block(), consumer.entity()) * coverage * consumer.entity.delta(); - consumer.entity.power.satisfaction = Mathf.clamp(consumer.entity.power.satisfaction + maximumRate / consumePower.powerCapacity); + if(!otherConsumersAreValid(consumer, consumePower)){ + consumer.entity.power.satisfaction = 0.0f; // Only supply power if the consumer would get valid that way }else{ - consumer.entity.power.satisfaction = coverage; + if(consumePower.isBuffered){ + // Add an equal percentage of power to all buffers, based on the global power coverage in this graph + float maximumRate = consumePower.requestedPower(consumer.block(), consumer.entity()) * coverage * consumer.entity.delta(); + consumer.entity.power.satisfaction = Mathf.clamp(consumer.entity.power.satisfaction + maximumRate / consumePower.powerCapacity); + }else{ + consumer.entity.power.satisfaction = coverage; + } } } } @@ -222,6 +230,15 @@ public class PowerGraph{ } } + private boolean otherConsumersAreValid(Tile tile, Consume consumePower){ + for(Consume cons : tile.block().consumes.all()){ + if(cons != consumePower && !cons.isOptional() && !cons.valid(tile.block(), tile.entity())){ + return false; + } + } + return true; + } + @Override public String toString(){ return "PowerGraph{" + diff --git a/tests/src/test/java/power/DirectConsumerTests.java b/tests/src/test/java/power/DirectConsumerTests.java new file mode 100644 index 0000000000..92812f8079 --- /dev/null +++ b/tests/src/test/java/power/DirectConsumerTests.java @@ -0,0 +1,57 @@ +package power; + +import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.content.UnitTypes; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.power.PowerGenerator; +import io.anuke.mindustry.world.blocks.power.PowerGraph; +import io.anuke.mindustry.world.blocks.units.UnitFactory; +import org.junit.jupiter.api.Test; +import sun.nio.cs.Surrogate; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** Tests for direct power consumers. */ +public class DirectConsumerTests extends PowerTestFixture{ + + @Test + void noPowerRequestedWithNoItems(){ + testUnitFactory(0, 0, 0.08f, 0.08f, 0.0f); + } + + @Test + void noPowerRequestedWithInsufficientItems(){ + testUnitFactory(30, 0, 0.08f, 0.08f, 0.0f); + testUnitFactory(0, 30, 0.08f, 0.08f, 0.0f); + } + + @Test + void powerRequestedWithSufficientItems(){ + testUnitFactory(30, 30, 0.08f, 0.08f, 1.0f); + } + + void testUnitFactory(int siliconAmount, int leadAmount, float producedPower, float requestedPower, float expectedSatisfaction){ + Tile consumerTile = createFakeTile(0, 0, new UnitFactory("fakefactory"){{ + type = UnitTypes.spirit; + produceTime = 60; + consumes.powerDirect(requestedPower); + consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); + }}); + consumerTile.entity.items.add(Items.silicon, siliconAmount); + consumerTile.entity.items.add(Items.lead, leadAmount); + + Tile producerTile = createFakeTile(2, 0, createFakeProducerBlock(producedPower)); + producerTile.entity().productionEfficiency = 0.5f; // 100% + + PowerGraph graph = new PowerGraph(); + graph.add(producerTile); + graph.add(consumerTile); + + consumerTile.entity.update(); + graph.update(); + + assertEquals(expectedSatisfaction, consumerTile.entity.power.satisfaction); + } +} diff --git a/tests/src/test/java/power/PowerTestFixture.java b/tests/src/test/java/power/PowerTestFixture.java index 5728f6bc8e..92d195399b 100644 --- a/tests/src/test/java/power/PowerTestFixture.java +++ b/tests/src/test/java/power/PowerTestFixture.java @@ -99,7 +99,8 @@ public class PowerTestFixture{ } // Assign incredibly high health so the block does not get destroyed on e.g. burning Blast Compound - block.health *= 100.0f; + block.health = 100000; + tile.entity.health = 100000.0f; return tile; }catch(Exception ex){