Consumers only draw power when all other required inputs are valid

This commit is contained in:
Timmeey86 2018-12-05 18:56:07 +01:00
parent e5dabc63c2
commit 329dac77ee
3 changed files with 82 additions and 7 deletions

View File

@ -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{" +

View File

@ -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.<PowerGenerator.GeneratorEntity>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);
}
}

View File

@ -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){