rewritten PowerGraph

This commit is contained in:
Baltazár Radics
2018-11-18 23:12:54 +01:00
parent 8091bec6bf
commit 285ee665ee
9 changed files with 63 additions and 161 deletions

View File

@@ -43,13 +43,13 @@ public class PowerBlocks extends BlockList implements ContentList{
itemDuration = 220f;
}};
solarPanel = new SolarGenerator("solar-panel"){{
generation = 0.0045f;
solarPanel = new PowerGenerator("solar-panel"){{
powerGeneration = 0.0045f;
}};
largeSolarPanel = new SolarGenerator("solar-panel-large"){{
largeSolarPanel = new PowerGenerator("solar-panel-large"){{
powerGeneration = 0.055f;
size = 3;
generation = 0.055f;
}};
thoriumReactor = new NuclearReactor("thorium-reactor"){{

View File

@@ -28,6 +28,8 @@ public abstract class BaseBlock extends MappableContent{
public boolean consumesPower;
public boolean outputsPower;
public float basePowerUse = 0;
public int itemCapacity;
public float liquidCapacity = 10f;
public float liquidFlowFactor = 4.9f;

View File

@@ -25,7 +25,6 @@ import static io.anuke.mindustry.Vars.tilesize;
public abstract class ItemGenerator extends PowerGenerator{
protected float minItemEfficiency = 0.2f;
protected float powerOutput;
protected float itemDuration = 70f;
protected Effect generateEffect = BlockFx.generatespark, explodeEffect =
BlockFx.generatespark;
@@ -46,13 +45,6 @@ public abstract class ItemGenerator extends PowerGenerator{
topRegion = Draw.region(name + "-top");
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.basePowerGeneration, powerOutput * 60f * 0.5f, StatUnit.powerSecond);
}
@Override
public void setBars(){
super.setBars();
@@ -84,22 +76,16 @@ public abstract class ItemGenerator extends PowerGenerator{
public void update(Tile tile){
ItemGeneratorEntity entity = tile.entity();
float maxPower = Math.min(powerCapacity - entity.power.amount, powerOutput * entity.delta()) * entity.efficiency;
if(entity.generateTime <= 0f && entity.items.total() > 0){
Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f));
Item item = entity.items.take();
entity.efficiency = getItemEfficiency(item);
entity.productionEfficiency = getItemEfficiency(item);
entity.explosiveness = item.explosiveness;
entity.generateTime = 1f;
}
entity.power.graph.update();
if(entity.generateTime > 0f){
entity.generateTime -= 1f / itemDuration * entity.delta();
entity.power.amount += maxPower;
entity.generateTime = Mathf.clamp(entity.generateTime);
entity.generateTime -= Math.min(1f / itemDuration * entity.delta(), entity.generateTime);
if(Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.25f))){
//this block is run last so that in the event of a block destruction, no code relies on the block type
@@ -117,18 +103,6 @@ public abstract class ItemGenerator extends PowerGenerator{
}
public static class ItemGeneratorEntity extends GeneratorEntity{
public float efficiency;
public float explosiveness;
@Override
public void write(DataOutput stream) throws IOException{
stream.writeFloat(efficiency);
}
@Override
public void read(DataInput stream) throws IOException{
efficiency = stream.readFloat();
}
}
}

View File

@@ -1,10 +1,15 @@
package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.util.EnumSet;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.mindustry.world.meta.BlockStat;
public class PowerGenerator extends PowerDistributor{
public float powerProduction;
public BlockStat generationType = BlockStat.basePowerGeneration;
public PowerGenerator(String name){
super(name);
@@ -12,6 +17,17 @@ public class PowerGenerator extends PowerDistributor{
flags = EnumSet.of(BlockFlag.producer);
}
@Override
public void setStats(){
super.setStats();
stats.add(generationType, baseGeneration * 60f, StatUnit.powerSecond);
}
@Override
public float getPowerProduction(Tile tile){
return powerProduction * tile.<GeneratorEntity>entity().productionEfficiency * tile.entity.delta();
}
@Override
public boolean outputsItems(){
return false;
@@ -24,5 +40,6 @@ public class PowerGenerator extends PowerDistributor{
public static class GeneratorEntity extends TileEntity{
public float generateTime;
public float productionEfficiency = 1;
}
}

View File

@@ -17,6 +17,7 @@ public class PowerGraph{
private final ObjectSet<Tile> producers = new ObjectSet<>();
private final ObjectSet<Tile> consumers = new ObjectSet<>();
private final ObjectSet<Tile> batteries = new ObjectSet<>();
private final ObjectSet<Tile> all = new ObjectSet<>();
private long lastFrameUpdated;
@@ -38,38 +39,43 @@ public class PowerGraph{
lastFrameUpdated = threads.getFrameID();
float totalInput = 0f;
float powerProduced = 0f;
for(Tile producer : producers){
totalInput += producer.entity.power.amount;
totalInput += producer.block().getPowerProduction(producer);
}
for(Tile producer : producers){
float accumulator = producer.entity.power.amount;
float powerNeeded = 0f;
for(Tile consumer : consumers){
powerNeeded += consumer.block().basePowerUse + consumer.entity.power.extraUse;
}
if(accumulator <= 0.0001f) continue;
float totalAccumulator = 0f;
float totalCapacity = 0f;
for(Tile battery : batteries){
totalAccumulator += battery.entity.power.satisfaction * battery.block().basePowerUse;
totalCapacity += (1f - battery.entity.power.satisfaction) * battery.block().basePowerUse;
}
float toEach = accumulator / consumers.size;
float outputs = 0f;
for(Tile tile : consumers){
outputs += Math.min(tile.block().powerCapacity - tile.entity.power.amount, toEach) / toEach;
if(powerNeeded > powerProduced){
float accumulatorUsed = Math.min(totalAccumulator, powerNeeded - powerProduced);
float thing = 1f - (accumulatorUsed / totalAccumulator);
for(Tile battery : batteries){
battery.entity.power.satisfaction *= thing;
}
powerProduced += accumulatorUsed;
}
float finalEach = toEach / outputs * Timers.delta();
float buffer = 0f;
float powerSatisfaction = Math.max(1, powerProduced / powerNeeded);
for(Tile consumer : producers){
consumer.power.satisfaction = powerSatisfaction;
}
if(Float.isNaN(finalEach) || Float.isInfinite(finalEach)){
continue;
if(powerProduced > powerNeeded){
powerProduced -= powerNeeded;
float thing = Math.min(1, powerProduced / totalCapacity);
for(tile battery : batteries){
battery.power.satisfaction += (1 - battery.power.satisfaction) * thing;
}
for(Tile tile : consumers){
float used = Math.min(tile.block().powerCapacity - tile.entity.power.amount, finalEach) * accumulator / totalInput;
buffer += used;
tile.entity.power.amount += used;
}
producer.entity.power.amount -= buffer;
}
}
@@ -83,11 +89,11 @@ public class PowerGraph{
tile.entity.power.graph = this;
all.add(tile);
if(tile.block().outputsPower){
if(tile.block().outputsPower && tile.block().consumesPower){
batteries.add(tile);
}else if(tile.block().outputsPower){
producers.add(tile);
}
if(tile.block().consumesPower){
}else if(tile.block().consumesPower){
consumers.add(tile);
}
}
@@ -99,6 +105,7 @@ public class PowerGraph{
all.clear();
producers.clear();
consumers.clear();
batteries.clear();
}
public void reflow(Tile tile){
@@ -146,6 +153,7 @@ public class PowerGraph{
return "PowerGraph{" +
"producers=" + producers +
", consumers=" + consumers +
", batteries=" + batteries +
", all=" + all +
", lastFrameUpdated=" + lastFrameUpdated +
", graphID=" + graphID +

View File

@@ -1,34 +0,0 @@
package io.anuke.mindustry.world.blocks.power;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.EnumSet;
public class SolarGenerator extends PowerGenerator{
/**
* power generated per frame
*/
protected float generation = 0.005f;
public SolarGenerator(String name){
super(name);
flags = EnumSet.of();
}
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.basePowerGeneration, generation * 60f, StatUnit.powerSecond);
}
@Override
public void update(Tile tile){
addPower(tile, generation * Timers.delta());
tile.entity.power.graph.update();
}
}

View File

@@ -1,45 +0,0 @@
package io.anuke.mindustry.world.consumers;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.BlockStats;
import io.anuke.mindustry.world.meta.StatUnit;
public class ConsumePower extends Consume{
protected final float use;
public ConsumePower(float use){
this.use = use;
}
@Override
public void buildTooltip(Table table){
}
@Override
public String getIcon(){
return "icon-power";
}
@Override
public boolean valid(Block block, TileEntity entity){
return entity.power.satisfaction >= 1;
}
@Override
public void display(BlockStats stats){
stats.add(BlockStat.powerUse, use * 60f, StatUnit.powerSecond);
}
public float getUse(Block block, TileEntity entity){
return use * entity.delta();
}
public void addPower(float amount) {
entity.power.satisfaction = amount / getUse();
}
}

View File

@@ -1,21 +0,0 @@
package io.anuke.mindustry.world.consumers;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.consumers.ConsumePower;
public class ConsumePowerBuffered extends ConsumePower{
@Override
public float getUse(Block block, TileEntity entity){
return use * (1 - entity.power.satisfaction);
}
@Override
public void addPower(float amount){
entity.power.satisfaction = Math.min(entity.power.satisfaction + (amount / use), 1);
}
public void usePower(float amount){
entity.power.satisfaction = Math.max(entity.power.satisfaction - (amount / use), 0);
}
}

View File

@@ -9,6 +9,7 @@ import java.io.IOException;
public class PowerModule extends BlockModule{
public float satisfaction;
public float extraUse = 0f;
public PowerGraph graph = new PowerGraph();
public IntArray links = new IntArray();