From 285ee665ee23b86574d3f4810c0c0654bdc9fdfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baltaz=C3=A1r=20Radics?= Date: Sun, 18 Nov 2018 23:12:54 +0100 Subject: [PATCH] rewritten PowerGraph --- .../mindustry/content/blocks/PowerBlocks.java | 8 +-- .../io/anuke/mindustry/world/BaseBlock.java | 2 + .../world/blocks/power/ItemGenerator.java | 30 +-------- .../world/blocks/power/PowerGenerator.java | 21 ++++++- .../world/blocks/power/PowerGraph.java | 62 +++++++++++-------- .../world/blocks/power/SolarGenerator.java | 34 ---------- .../world/consumers/ConsumePower.java | 45 -------------- .../world/consumers/ConsumePowerBuffered.java | 21 ------- .../mindustry/world/modules/PowerModule.java | 1 + 9 files changed, 63 insertions(+), 161 deletions(-) delete mode 100644 core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java delete mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePower.java delete mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 1420f0c838..1c13f76742 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -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"){{ diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 258ecc0bb6..bb4466221f 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -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; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java index 285cebb5fc..a8d8da9699 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java @@ -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(); - } } - } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java index 8423ffefa2..64c7c836eb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java @@ -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.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; } } 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 5fecfbeba3..d817d423a2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -17,6 +17,7 @@ public class PowerGraph{ private final ObjectSet producers = new ObjectSet<>(); private final ObjectSet consumers = new ObjectSet<>(); + private final ObjectSet batteries = new ObjectSet<>(); private final ObjectSet 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 + diff --git a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java deleted file mode 100644 index 02c3bfc245..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java +++ /dev/null @@ -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(); - } - -} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java deleted file mode 100644 index 135e53cea3..0000000000 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ /dev/null @@ -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(); - } -} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java deleted file mode 100644 index 3d06635dd6..0000000000 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java +++ /dev/null @@ -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); - } -} diff --git a/core/src/io/anuke/mindustry/world/modules/PowerModule.java b/core/src/io/anuke/mindustry/world/modules/PowerModule.java index 25dafb4ae2..363a406661 100644 --- a/core/src/io/anuke/mindustry/world/modules/PowerModule.java +++ b/core/src/io/anuke/mindustry/world/modules/PowerModule.java @@ -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();