From 222d41c84adb8dd0c5bdf5047adb293ece2865ba Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Tue, 20 Nov 2018 20:58:46 +0100 Subject: [PATCH 1/7] Added Test stub --- tests/src/test/java/PowerTests.java | 91 +++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tests/src/test/java/PowerTests.java diff --git a/tests/src/test/java/PowerTests.java b/tests/src/test/java/PowerTests.java new file mode 100644 index 0000000000..d0ea1e218c --- /dev/null +++ b/tests/src/test/java/PowerTests.java @@ -0,0 +1,91 @@ +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.content.blocks.PowerBlocks; +import io.anuke.mindustry.content.blocks.ProductionBlocks; +import io.anuke.mindustry.core.ContentLoader; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.Floor; +import io.anuke.mindustry.world.blocks.power.PowerGraph; +import io.anuke.mindustry.world.blocks.production.SolidPump; +import io.anuke.mindustry.world.modules.PowerModule; +import org.junit.jupiter.api.*; + +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; + +import static io.anuke.mindustry.Vars.threads; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class PowerTests{ + + @BeforeAll + static void initializeDependencies(){ + Vars.content = new ContentLoader(); + Vars.content.load(); + } + + @BeforeEach + void initTest(){ + } + + /** + * Creates a fake tile on the given location using the given floor and block. + * @param x The X coordinate. + * @param y The y coordinate. + * @param floor The floor. + * @param block The block on the tile. + * @return The created tile or null in case of exceptions. + */ + private static Tile createFakeTile(int x, int y, Floor floor, Block block){ + try{ + Tile tile = new Tile(x, y); + Field field = Tile.class.getDeclaredField("wall"); + field.setAccessible(true); + field.set(tile, block); + field = Tile.class.getDeclaredField("floor"); + field.setAccessible(true); + field.set(tile, floor); + tile.entity = block.newEntity(); + tile.entity.power = new PowerModule(); + return tile; + }catch(Exception ex){ + return null; + } + } + + /** Makes sure calculations are accurate for the case where produced power = consumed power. */ + @Test + void test_balancedPower(){ + PowerGraph powerGraph = new PowerGraph(); + + // Create one water extractor (5.4 power consumed) + Tile waterExtractorTile = createFakeTile(0, 0, (Floor)Blocks.sand, ProductionBlocks.waterExtractor); + powerGraph.add(waterExtractorTile); + + // Create 20 small solar panels (20*0.27=5.4 power produced) + List solarPanelTiles = new LinkedList<>(); + float producedPowerSum = 0.0f; + for(int counter = 0; counter < 20; counter++){ + Tile solarPanelTile = createFakeTile( 2 + counter / 2, counter % 2, (Floor)Blocks.sand, PowerBlocks.solarPanel); + powerGraph.add(solarPanelTile); + solarPanelTiles.add(solarPanelTile); + } + + // If these lines fail, you probably changed power production/consumption and need to adapt this test + // TODO: Create fake blocks which are independent of such changes + powerGraph.update(); + + powerGraph.getPowerNeeded(); + powerGraph.getPowerProduced(); + +/* if(powerNeeded > powerProduced){ + powerProduced += useBatteries(powerNeeded - powerProduced); + }else if(powerProduced > powerNeeded){ + powerProduced -= chargeBatteries(powerProduced - powerNeeded); + } + + distributePower(powerNeeded, powerProduced);*/ + } +} From 558c89cc30b74a368066710fed94b88577146dae Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 00:04:26 +0100 Subject: [PATCH 2/7] Finished first unit test (equal power input and output) and fixed bugs detected by it --- .../io/anuke/mindustry/world/BaseBlock.java | 4 +-- .../world/blocks/power/PowerGraph.java | 10 ++++--- tests/src/test/java/PowerTests.java | 28 +++++++++---------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 6a729435ce..6111e5a197 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -25,8 +25,8 @@ public abstract class BaseBlock extends MappableContent{ public boolean outputsLiquid = false; public boolean singleLiquid = true; - public boolean consumesPower; - public boolean outputsPower; + public boolean consumesPower = true; + public boolean outputsPower = false; public boolean bufferedPowerConsumer = false; /** In case of unbuffered consumers, this stores the amount of power which is required per tick in order to work at maximum efficiency. 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 68afdec034..9045ffb284 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -109,10 +109,12 @@ public class PowerGraph{ float powerNeeded = getPowerNeeded(); float powerProduced = getPowerProduced(); - if(powerNeeded > powerProduced){ - powerProduced += useBatteries(powerNeeded - powerProduced); - }else if(powerProduced > powerNeeded){ - powerProduced -= chargeBatteries(powerProduced - powerNeeded); + if(Math.abs(powerNeeded - powerProduced) > 0.0001f){ + if(powerNeeded > powerProduced){ + powerProduced += useBatteries(powerNeeded-powerProduced); + }else if(powerProduced > powerNeeded){ + powerProduced -= chargeBatteries(powerProduced-powerNeeded); + } } distributePower(powerNeeded, powerProduced); diff --git a/tests/src/test/java/PowerTests.java b/tests/src/test/java/PowerTests.java index d0ea1e218c..07f7e6e2ba 100644 --- a/tests/src/test/java/PowerTests.java +++ b/tests/src/test/java/PowerTests.java @@ -16,6 +16,7 @@ import java.util.LinkedList; import java.util.List; import static io.anuke.mindustry.Vars.threads; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class PowerTests{ @@ -60,32 +61,31 @@ public class PowerTests{ void test_balancedPower(){ PowerGraph powerGraph = new PowerGraph(); - // Create one water extractor (5.4 power consumed) + // Create one water extractor (5.4 power/Second = 0.09/tick) Tile waterExtractorTile = createFakeTile(0, 0, (Floor)Blocks.sand, ProductionBlocks.waterExtractor); powerGraph.add(waterExtractorTile); - // Create 20 small solar panels (20*0.27=5.4 power produced) + // Create 20 small solar panels (20*0.27=5.4 power/second = 0.09/tick) List solarPanelTiles = new LinkedList<>(); - float producedPowerSum = 0.0f; for(int counter = 0; counter < 20; counter++){ Tile solarPanelTile = createFakeTile( 2 + counter / 2, counter % 2, (Floor)Blocks.sand, PowerBlocks.solarPanel); powerGraph.add(solarPanelTile); solarPanelTiles.add(solarPanelTile); } + float powerNeeded = powerGraph.getPowerNeeded(); + float powerProduced = powerGraph.getPowerProduced(); + // If these lines fail, you probably changed power production/consumption and need to adapt this test + // OR their implementation is corrupt. // TODO: Create fake blocks which are independent of such changes - powerGraph.update(); + float epsilon = 0.00001f; + assertEquals(powerNeeded, 0.09f, epsilon); + assertEquals(powerProduced, 0.09f, epsilon); + // Note: The assertions above induce that powerNeeded = powerProduced (with floating point inaccuracy) - powerGraph.getPowerNeeded(); - powerGraph.getPowerProduced(); - -/* if(powerNeeded > powerProduced){ - powerProduced += useBatteries(powerNeeded - powerProduced); - }else if(powerProduced > powerNeeded){ - powerProduced -= chargeBatteries(powerProduced - powerNeeded); - } - - distributePower(powerNeeded, powerProduced);*/ + // Distribute power and make sure the water extractor is powered + powerGraph.distributePower(powerNeeded, powerProduced); + assertEquals(waterExtractorTile.entity.power.satisfaction, 1.0f, epsilon); } } From f789a3590197dd400420d112f7898dcf48fb3b4a Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 20:07:05 +0100 Subject: [PATCH 3/7] Readded buffered and direct consumers as three classes --- .../world/consumers/ConsumePower.java | 48 +++++++++++++++++++ .../world/consumers/ConsumePowerBuffered.java | 43 +++++++++++++++++ .../world/consumers/ConsumePowerDirect.java | 43 +++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePower.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java new file mode 100644 index 0000000000..8f4e829d1d --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -0,0 +1,48 @@ +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; + +/** Consumer class for blocks which consume power while being connected to a power graph. */ +public abstract class ConsumePower extends Consume{ + /** The maximum amount of power which can be processed per tick. This might influence efficiency or load a buffer. */ + protected final float powerPerTick; + + public ConsumePower(float powerPerTick){ + this.powerPerTick = powerPerTick; + } + + @Override + public void buildTooltip(Table table){ + // No tooltip for power + } + + @Override + public String getIcon(){ + return "icon-power"; + } + + @Override + public void update(Block block, TileEntity entity){ + // Nothing to do since PowerGraph directly updates entity.power.satisfaction + } + + // valid(...) is implemented in subclass + // display(...) is implemented in subclass + + /** + * Retrieves the amount of power which is requested for the given block and entity. + * @param block The block which needs power. + * @param entity The entity which contains the power module. + * @return The amount of power which is requested per tick. + */ + public float requestedPower(Block block, TileEntity entity){ + // TODO Is it possible to make the block not consume power while items/liquids are missing? + return powerPerTick; + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java new file mode 100644 index 0000000000..62eebdfb21 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java @@ -0,0 +1,43 @@ +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; + +/** Consumer class for blocks which directly consume power without buffering it. */ +public class ConsumePowerBuffered extends ConsumePower{ + /** The maximum power capacity in power units. */ + protected final float powerCapacity; + + /** + * Adds a power buffer to the owner which takes ticksToFill number of ticks to be filled. + * Note that this object does not remove power from the buffer. + * @param powerCapacity The maximum capacity in power units. + * @param ticksToFill The number of ticks it shall take to fill the buffer. + */ + public ConsumePowerBuffered(float powerCapacity, float ticksToFill){ + super(powerCapacity / ticksToFill); + this.powerCapacity = powerCapacity; + } + + @Override + public boolean valid(Block block, TileEntity entity){ + // TODO - Verify: It might be necessary to know about the power required per shot/event here. + return true; + } + + @Override + public void display(BlockStats stats){ + stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerSecond); + } + + @Override + public float requestedPower(Block block, TileEntity entity){ + // Only request power until the capacity is full + return Math.max(powerPerTick, powerCapacity * (1 - entity.power.satisfaction)); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java new file mode 100644 index 0000000000..0ce7d593a2 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java @@ -0,0 +1,43 @@ +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; + +/** Consumer class for blocks which directly consume power without buffering it. */ +public class ConsumePowerDirect extends ConsumePower{ + /** The minimum power satisfaction (fraction of powerPerTick) which must be achieved before the module may work. */ + protected final float minimumSatisfaction; + + /** + * Makes the owner consume powerPerTick each tick and disables it unless 60% of that power is being supplied. + * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. + */ + public ConsumePowerDirect(float powerPerTick){ + this(powerPerTick, 0.75f); + } + + /** + * Makes the owner consume powerPerTick each tick and disables it unless minimumSatisfaction (1.0 = 100%) of that power is being supplied. + * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. + * @param minimumSatisfaction The percentage of powerPerTick which must be available for the module to work. + */ + public ConsumePowerDirect(float powerPerTick, float minimumSatisfaction){ + super(powerPerTick); + this.minimumSatisfaction = minimumSatisfaction; + } + + @Override + public boolean valid(Block block, TileEntity entity){ + return entity.power.satisfaction >= minimumSatisfaction; + } + + @Override + public void display(BlockStats stats){ + stats.add(BlockStat.powerUse, powerPerTick * 60f, StatUnit.powerSecond); + } +} From 405f153439b31dab089fd7986553d2a6799a2cec Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 21:54:43 +0100 Subject: [PATCH 4/7] Reverted/Adapted blocks to new Consume interfaces --- .../content/blocks/CraftingBlocks.java | 24 +++---- .../mindustry/content/blocks/DebugBlocks.java | 2 +- .../content/blocks/DefenseBlocks.java | 6 +- .../content/blocks/DistributionBlocks.java | 2 +- .../content/blocks/LiquidBlocks.java | 10 +-- .../mindustry/content/blocks/PowerBlocks.java | 4 +- .../content/blocks/ProductionBlocks.java | 12 ++-- .../content/blocks/TurretBlocks.java | 6 +- .../mindustry/content/blocks/UnitBlocks.java | 16 ++--- .../content/blocks/UpgradeBlocks.java | 17 +++-- .../io/anuke/mindustry/world/BaseBlock.java | 6 -- core/src/io/anuke/mindustry/world/Block.java | 14 ++-- .../world/blocks/defense/ForceProjector.java | 2 +- .../blocks/defense/turrets/PowerTurret.java | 3 - .../world/blocks/distribution/MassDriver.java | 15 +++-- .../world/blocks/power/PowerGraph.java | 64 +++++++++++-------- .../world/blocks/production/Incinerator.java | 2 +- .../mindustry/world/blocks/units/MechPad.java | 1 - .../world/blocks/units/Reconstructor.java | 3 +- .../world/blocks/units/RepairPoint.java | 3 +- .../world/consumers/ConsumePowerBuffered.java | 2 +- .../world/consumers/ConsumePowerDirect.java | 8 --- .../mindustry/world/consumers/Consumers.java | 59 +++++++++++++++++ 23 files changed, 169 insertions(+), 112 deletions(-) diff --git a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java index 8666f382c0..6229ee9fb3 100644 --- a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java @@ -38,7 +38,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ fluxNeeded = 2; consumes.items(new ItemStack[]{new ItemStack(Items.copper, 1), new ItemStack(Items.lead, 2)}); - basePowerUse = 0.1f; + consumes.powerDirect(0.1f); }}; siliconsmelter = new PowerSmelter("silicon-smelter"){{ @@ -51,7 +51,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ flameColor = Color.valueOf("ffef99"); consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)}); - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); }}; plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor"){{ @@ -67,7 +67,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ updateEffect = BlockFx.plasticburn; consumes.liquid(Liquids.oil, 0.25f); - basePowerUse = 0.3f; + consumes.powerDirect(0.3f); consumes.item(Items.titanium, 2); }}; @@ -78,7 +78,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ size = 2; consumes.items(new ItemStack[]{new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10)}); - basePowerUse = 0.5f; + consumes.powerDirect(0.5f); }}; alloySmelter = new PowerSmelter("alloy-smelter"){{ @@ -90,7 +90,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ useFlux = true; fluxNeeded = 3; - basePowerUse = 0.4f; + consumes.powerDirect(0.4f); consumes.items(new ItemStack[]{new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.copper, 3)}); }}; @@ -101,7 +101,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ size = 2; hasPower = true; - basePowerUse = 0.1f; + consumes.powerDirect(0.1f); consumes.item(Items.titanium); consumes.liquid(Liquids.water, 0.3f); }}; @@ -116,7 +116,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ consumes.liquid(Liquids.oil, 0.05f); consumes.item(Items.pyratite, 1); - basePowerUse = 0.04f; + consumes.powerDirect(0.04f); }}; pyratiteMixer = new PowerSmelter("pyratite-mixer"){{ @@ -128,7 +128,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ size = 2; - basePowerUse = 0.02f; + consumes.powerDirect(0.02f); consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)}); }}; @@ -140,7 +140,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ craftTime = 10f; hasLiquids = hasPower = true; - basePowerUse = 0.1f; + consumes.powerDirect(0.1f); consumes.item(Items.stone, 2); }}; @@ -185,7 +185,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ size = 2; consumes.item(Items.stone, 2); - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); consumes.liquid(Liquids.water, 0.5f); }}; @@ -200,7 +200,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ hasLiquids = true; consumes.item(Items.biomatter, 1); - basePowerUse = 0.06f; + consumes.powerDirect(0.06f); }}; pulverizer = new Pulverizer("pulverizer"){{ @@ -213,7 +213,7 @@ public class CraftingBlocks extends BlockList implements ContentList{ hasItems = hasPower = true; consumes.item(Items.stone, 1); - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); }}; solidifier = new GenericCrafter("solidifer"){{ diff --git a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java index c7d034b89c..a2fff36077 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DebugBlocks.java @@ -41,7 +41,7 @@ public class DebugBlocks extends BlockList implements ContentList{ powerVoid = new PowerBlock("powervoid"){ { // TODO Adapt to new power system if necessary - basePowerUse = Float.MAX_VALUE; + consumes.powerDirect(Float.MAX_VALUE); shadow = "shadow-round-1"; } diff --git a/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java index aeac0daeb3..e3038d569e 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DefenseBlocks.java @@ -71,19 +71,19 @@ public class DefenseBlocks extends BlockList implements ContentList{ }}; mendProjector = new MendProjector("mend-projector"){{ - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); size = 2; consumes.item(Items.phasefabric).optional(true); }}; overdriveProjector = new OverdriveProjector("overdrive-projector"){{ - basePowerUse = 0.35f; + consumes.powerDirect(0.35f); size = 2; consumes.item(Items.phasefabric).optional(true); }}; forceProjector = new ForceProjector("force-projector"){{ - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); size = 3; consumes.item(Items.phasefabric).optional(true); }}; diff --git a/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java index 3d3df81740..15904f7e09 100644 --- a/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/DistributionBlocks.java @@ -35,7 +35,7 @@ public class DistributionBlocks extends BlockList implements ContentList{ phaseConveyor = new ItemBridge("phase-conveyor"){{ range = 11; hasPower = true; - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); }}; sorter = new Sorter("sorter"); diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index 69fd859c9a..b489a21611 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -20,10 +20,10 @@ public class LiquidBlocks extends BlockList implements ContentList{ rotaryPump = new Pump("rotary-pump"){{ shadow = "shadow-rounded-2"; pumpAmount = 0.2f; - basePowerUse = 0.015f; + consumes.powerDirect(0.015f); liquidCapacity = 30f; // TODO Verify: No longer buffered - basePowerUse = 20f / 60f; + consumes.powerDirect(20f / 60f); hasPower = true; size = 2; tier = 1; @@ -32,11 +32,11 @@ public class LiquidBlocks extends BlockList implements ContentList{ thermalPump = new Pump("thermal-pump"){{ shadow = "shadow-rounded-2"; pumpAmount = 0.275f; - basePowerUse = 0.03f; + consumes.powerDirect(0.03f); liquidCapacity = 40f; hasPower = true; // TODO Verify: No longer buffered - basePowerUse = 20f / 60f; + consumes.powerDirect(20f / 60f); size = 2; tier = 2; }}; @@ -71,7 +71,7 @@ public class LiquidBlocks extends BlockList implements ContentList{ phaseConduit = new LiquidBridge("phase-conduit"){{ range = 11; hasPower = true; - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); }}; } } diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 25ce084e29..6b47d31a67 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -62,12 +62,12 @@ public class PowerBlocks extends BlockList implements ContentList{ }}; battery = new Battery("battery"){{ - basePowerUse = 320f; + consumes.powerBuffered(320f, 120f); }}; batteryLarge = new Battery("battery-large"){{ size = 3; - basePowerUse = 2000f; + consumes.powerBuffered(2000f, 600f); }}; powerNode = new PowerNode("power-node"){{ diff --git a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java index b1e8bff026..2e68c38b99 100644 --- a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java @@ -38,7 +38,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ updateEffect = BlockFx.pulverizeMedium; drillEffect = BlockFx.mineBig; - basePowerUse = 0.11f; + consumes.powerDirect(0.11f); }}; blastDrill = new Drill("blast-drill"){{ @@ -53,7 +53,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ rotateSpeed = 6f; warmupSpeed = 0.01f; - basePowerUse = 0.3f; + consumes.powerDirect(0.3f); }}; plasmaDrill = new Drill("plasma-drill"){{ @@ -70,7 +70,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ drillEffect = BlockFx.mineHuge; warmupSpeed = 0.005f; - basePowerUse = 0.7f; + consumes.powerDirect(0.7f); }}; waterExtractor = new SolidPump("water-extractor"){{ @@ -80,7 +80,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ liquidCapacity = 30f; rotateSpeed = 1.4f; - basePowerUse = 0.09f; + consumes.powerDirect(0.09f); }}; oilExtractor = new Fracker("oil-extractor"){{ @@ -93,7 +93,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ liquidCapacity = 30f; consumes.item(Items.sand); - basePowerUse = 0.3f; + consumes.powerDirect(0.3f); consumes.liquid(Liquids.water, 0.15f); }}; @@ -104,7 +104,7 @@ public class ProductionBlocks extends BlockList implements ContentList{ hasLiquids = true; hasPower = true; - basePowerUse = 0.08f; + consumes.powerDirect(0.08f); consumes.liquid(Liquids.water, 0.2f); }}; diff --git a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java index b33c665ab3..6e3fc0dc03 100644 --- a/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/TurretBlocks.java @@ -103,7 +103,7 @@ public class TurretBlocks extends BlockList implements ContentList{ reload = 100f; cooldown = 0.03f; powerUsed = 1 / 3f; - basePowerUse = 60f; // capacity + consumes.powerBuffered(60f); shootShake = 2f; shootEffect = ShootFx.lancerLaserShoot; smokeEffect = ShootFx.lancerLaserShootSmoke; @@ -122,7 +122,7 @@ public class TurretBlocks extends BlockList implements ContentList{ shootCone = 40f; rotatespeed = 8f; powerUsed = 7 / 30f; - basePowerUse = 30f; // capacity + consumes.powerBuffered(30f); range = 150f; shootEffect = ShootFx.lightningShoot; heatColor = Color.RED; @@ -256,7 +256,7 @@ public class TurretBlocks extends BlockList implements ContentList{ size = 4; shootShake = 2f; powerUsed = 0.5f; - basePowerUse = 120f; // capacity + consumes.powerBuffered(120f); range = 160f; reload = 200f; firingMoveFract = 0.1f; diff --git a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 1aa39afd22..54560e6ab9 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -20,7 +20,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.spirit; produceTime = 5700; size = 2; - basePowerUse = 0.08f; + consumes.powerDirect(0.08f); consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)}); }}; @@ -28,7 +28,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.phantom; produceTime = 7300; size = 2; - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)}); }}; @@ -36,7 +36,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.wraith; produceTime = 1800; size = 2; - basePowerUse = 0.1f; + consumes.powerDirect(0.1f); consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 10)}); }}; @@ -44,7 +44,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.ghoul; produceTime = 3600; size = 3; - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); shadow = "shadow-round-3"; consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 30), new ItemStack(Items.plastanium, 20)}); }}; @@ -53,7 +53,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.revenant; produceTime = 8000; size = 4; - basePowerUse = 0.3f; + consumes.powerDirect(0.3f); shadow = "shadow-round-4"; consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80), new ItemStack(Items.plastanium, 50)}); }}; @@ -62,7 +62,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.dagger; produceTime = 1700; size = 2; - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 10)}); }}; @@ -70,7 +70,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.titan; produceTime = 3400; size = 3; - basePowerUse = 0.15f; + consumes.powerDirect(0.15f); shadow = "shadow-round-3"; consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 20), new ItemStack(Items.thorium, 30)}); }}; @@ -79,7 +79,7 @@ public class UnitBlocks extends BlockList implements ContentList{ type = UnitTypes.fortress; produceTime = 5000; size = 3; - basePowerUse = 0.2f; + consumes.powerDirect(0.2f); shadow = "shadow-round-3"; consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 40), new ItemStack(Items.thorium, 50)}); }}; diff --git a/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java index 7cb28cdd28..a5e20a0cca 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UpgradeBlocks.java @@ -9,57 +9,56 @@ public class UpgradeBlocks extends BlockList{ @Override public void load(){ - // Note: MechPads are buffered; all basePowerUse values represent total capacity alphaPad = new MechPad("alpha-mech-pad"){{ mech = Mechs.alpha; size = 2; - basePowerUse = 50f; + consumes.powerBuffered(50f); }}; deltaPad = new MechPad("delta-mech-pad"){{ mech = Mechs.delta; size = 2; - basePowerUse = 70f; + consumes.powerBuffered(70f); }}; tauPad = new MechPad("tau-mech-pad"){{ mech = Mechs.tau; size = 2; - basePowerUse = 100f; + consumes.powerBuffered(100f); }}; omegaPad = new MechPad("omega-mech-pad"){{ mech = Mechs.omega; size = 3; - basePowerUse = 120f; + consumes.powerBuffered(120f); }}; dartPad = new MechPad("dart-ship-pad"){{ mech = Mechs.dart; size = 2; - basePowerUse = 50f; + consumes.powerBuffered(50f); shadow = "shadow-rounded-2"; }}; javelinPad = new MechPad("javelin-ship-pad"){{ mech = Mechs.javelin; size = 2; - basePowerUse = 80f; + consumes.powerBuffered(80f); shadow = "shadow-rounded-2"; }}; tridentPad = new MechPad("trident-ship-pad"){{ mech = Mechs.trident; size = 2; - basePowerUse = 100f; + consumes.powerBuffered(100f); shadow = "shadow-rounded-2"; }}; glaivePad = new MechPad("glaive-ship-pad"){{ mech = Mechs.glaive; size = 3; - basePowerUse = 120f; + consumes.powerBuffered(120f); shadow = "shadow-round-3"; }}; } diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index 6111e5a197..9a1b7dbfb1 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -28,12 +28,6 @@ public abstract class BaseBlock extends MappableContent{ public boolean consumesPower = true; public boolean outputsPower = false; - public boolean bufferedPowerConsumer = false; - /** In case of unbuffered consumers, this stores the amount of power which is required per tick in order to work at maximum efficiency. - * In case of buffered consumers, this stores the maximum power capacity. - */ - 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/Block.java b/core/src/io/anuke/mindustry/world/Block.java index c04987bdd1..36c80a493d 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -20,6 +20,7 @@ import io.anuke.mindustry.input.CursorType; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.world.consumers.ConsumePowerBuffered; import io.anuke.mindustry.world.meta.*; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -330,17 +331,16 @@ public class Block extends BaseBlock { consumes.forEach(cons -> cons.display(stats)); - if(hasPower){ - if(bufferedPowerConsumer) stats.add(BlockStat.powerCapacity, basePowerUse, StatUnit.powerUnits); - else stats.add(BlockStat.powerUse, basePowerUse * 60, StatUnit.powerUnits); - } + // Note: Power stats are added by the consumers. if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits); if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); } //TODO make this easier to config. public void setBars(){ - if(bufferedPowerConsumer) bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.satisfaction)); + if(consumes.has(ConsumePowerBuffered.class)){ + bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.satisfaction)); + } if(hasLiquids) bars.add(new BlockBar(BarType.liquid, true, tile -> tile.entity.liquids.total() / liquidCapacity)); if(hasItems) @@ -406,8 +406,8 @@ public class Block extends BaseBlock { explosiveness += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); } - if(bufferedPowerConsumer){ - power += tile.entity.power.satisfaction * tile.block().basePowerUse; + if(consumes.has(ConsumePowerBuffered.class)){ + power += tile.entity.power.satisfaction * consumes.get(ConsumePowerBuffered.class).powerCapacity; } tempColor.mul(1f / units); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java index c89cee750b..9af93e6fa4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java @@ -51,10 +51,10 @@ public class ForceProjector extends Block { hasPower = true; canOverdrive = false; hasLiquids = true; - basePowerUse = 60f; hasItems = true; itemCapacity = 10; consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).optional(true).update(false); + consumes.powerBuffered(60f); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java index 1625953a3c..3f8f6682fd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/PowerTurret.java @@ -13,8 +13,6 @@ public abstract class PowerTurret extends CooledTurret{ public PowerTurret(String name){ super(name); hasPower = true; - // TODO Verify for new power system - bufferedPowerConsumer = true; } @Override @@ -26,7 +24,6 @@ public abstract class PowerTurret extends CooledTurret{ @Override public boolean hasAmmo(Tile tile){ - // TODO Verify for new power system // Allow shooting as long as the turret is at least at 50% power return tile.entity.power.satisfaction >= powerUsed; } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index e5c7141dce..db665d79f6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -19,6 +19,7 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumePowerBuffered; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Effects; @@ -48,6 +49,7 @@ public class MassDriver extends Block{ protected Effect smokeEffect = ShootFx.shootBigSmoke2; protected Effect recieveEffect = BlockFx.mineBig; protected float shake = 3f; + protected final static float powerPercentageUsed = 0.8f; protected TextureRegion turretRegion; public MassDriver(String name){ @@ -58,6 +60,7 @@ public class MassDriver extends Block{ hasItems = true; layer = Layer.turret; hasPower = true; + consumes.powerBuffered(30f); } @Remote(targets = Loc.both, called = Loc.server, forward = true) @@ -80,7 +83,7 @@ public class MassDriver extends Block{ entity.reload = 1f; - entity.power.satisfaction = 0f; + entity.power.satisfaction -= Math.min(entity.power.satisfaction, powerPercentageUsed); DriverBulletData data = Pooling.obtain(DriverBulletData.class, DriverBulletData::new); data.from = entity; @@ -128,7 +131,10 @@ public class MassDriver extends Block{ public void setStats(){ super.setStats(); - stats.add(BlockStat.powerShot, basePowerUse, StatUnit.powerUnits); + if(!consumes.hasSubclassOf(ConsumePowerBuffered.class)){ + throw new RuntimeException("Mass Driver did not have a buffered power consumer object attached."); + } + stats.add(BlockStat.powerShot, consumes.getFirstSubclassOf(ConsumePowerBuffered.class).powerCapacity, StatUnit.powerUnits); } @Override @@ -167,9 +173,8 @@ public class MassDriver extends Block{ entity.rotation = Mathf.slerpDelta(entity.rotation, tile.angleTo(waiter), rotateSpeed); }else if(tile.entity.items.total() >= minDistribute && - linkValid(tile) && //only fire when at least at half-capacity and power - // TODO adapt - //tile.entity.power.amount >= powerCapacity * 0.8f && + linkValid(tile) && //only fire when at least at 80% power capacity + tile.entity.power.satisfaction > powerPercentageUsed && link.block().itemCapacity - link.entity.items.total() >= minDistribute && entity.reload <= 0.0001f){ MassDriverEntity other = link.entity(); 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 9045ffb284..d8276f16c3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -1,10 +1,15 @@ package io.anuke.mindustry.world.blocks.power; +import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; 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.ConsumePowerBuffered; +import io.anuke.mindustry.world.consumers.Consumers; import static io.anuke.mindustry.Vars.threads; @@ -42,10 +47,9 @@ public class PowerGraph{ public float getPowerNeeded(){ float powerNeeded = 0f; for(Tile consumer : consumers){ - if(consumer.block().bufferedPowerConsumer){ - powerNeeded += (1f - consumer.entity.power.satisfaction) * consumer.block().basePowerUse; - }else{ - powerNeeded += consumer.block().basePowerUse + consumer.entity.power.extraUse; + Consumers consumes = consumer.block().consumes; + if(consumes.hasSubclassOf(ConsumePower.class)){ + powerNeeded += consumes.getFirstSubclassOf(ConsumePower.class).requestedPower(consumer.block(), consumer.entity); } } return powerNeeded; @@ -54,7 +58,10 @@ public class PowerGraph{ public float getBatteryStored(){ float totalAccumulator = 0f; for(Tile battery : batteries){ - totalAccumulator += battery.entity.power.satisfaction * battery.block().basePowerUse; + Consumers consumes = battery.block().consumes; + if(consumes.hasSubclassOf(ConsumePowerBuffered.class)){ + totalAccumulator += battery.entity.power.satisfaction * consumes.getFirstSubclassOf(ConsumePowerBuffered.class).powerCapacity; + } } return totalAccumulator; } @@ -62,23 +69,30 @@ public class PowerGraph{ public float getBatteryCapacity(){ float totalCapacity = 0f; for(Tile battery : batteries){ - totalCapacity += (1f - battery.entity.power.satisfaction) * battery.block().basePowerUse; + Consumers consumes = battery.block().consumes; + if(consumes.hasSubclassOf(ConsumePower.class)){ + totalCapacity += consumes.getFirstSubclassOf(ConsumePower.class).requestedPower(battery.block(), battery.entity); + } } return totalCapacity; } public float useBatteries(float needed){ float stored = getBatteryStored(); + if(MathUtils.isEqual(stored, 0f)){ return 0f; } + float used = Math.min(stored, needed); - float thing = 1f - (used / stored); + float percentageRemaining = 1f - (used / stored); for(Tile battery : batteries){ - battery.entity.power.satisfaction *= thing; + battery.entity.power.satisfaction *= percentageRemaining; } return used; } public float chargeBatteries(float excess){ float capacity = getBatteryCapacity(); + if(MathUtils.isEqual(capacity, 0f)){ return 0f; } + float thing = Math.min(1, excess / capacity); for(Tile battery : batteries){ battery.entity.power.satisfaction += (1 - battery.entity.power.satisfaction) * thing; @@ -87,14 +101,14 @@ public class PowerGraph{ } public void distributePower(float needed, float produced){ - if(needed == 0f){ return; } + if(MathUtils.isEqual(needed,0f)){ return; } - float satisfaction = Math.min(1, produced / needed); + float coverage = Math.min(1, produced / needed); for(Tile consumer : consumers){ - if(consumer.block().bufferedPowerConsumer){ - consumer.entity.power.satisfaction += (1 - consumer.entity.power.satisfaction) * satisfaction; + if(consumer.block().consumes.hasSubclassOf(ConsumePowerBuffered.class)){ + consumer.entity.power.satisfaction += (1 - consumer.entity.power.satisfaction) * coverage; }else{ - consumer.entity.power.satisfaction = satisfaction; + consumer.entity.power.satisfaction = coverage; } } } @@ -109,11 +123,11 @@ public class PowerGraph{ float powerNeeded = getPowerNeeded(); float powerProduced = getPowerProduced(); - if(Math.abs(powerNeeded - powerProduced) > 0.0001f){ + if(!MathUtils.isEqual(powerNeeded, powerProduced)){ if(powerNeeded > powerProduced){ - powerProduced += useBatteries(powerNeeded-powerProduced); + powerProduced += useBatteries(powerNeeded - powerProduced); }else if(powerProduced > powerNeeded){ - powerProduced -= chargeBatteries(powerProduced-powerNeeded); + powerProduced -= chargeBatteries(powerProduced - powerNeeded); } } @@ -141,7 +155,7 @@ public class PowerGraph{ public void clear(){ for(Tile other : all){ - if(other.entity != null && other.entity.power != null) other.entity.power.graph = null; + if(other.entity != null && other.entity.power != null){ other.entity.power.graph = null; } } all.clear(); producers.clear(); @@ -171,7 +185,7 @@ public class PowerGraph{ closedSet.clear(); for(Tile other : tile.block().getPowerConnections(tile, outArray1)){ - if(other.entity.power == null || other.entity.power.graph != null) continue; + if(other.entity.power == null || other.entity.power.graph != null){ continue; } PowerGraph graph = new PowerGraph(); queue.clear(); queue.addLast(other); @@ -192,12 +206,12 @@ public class PowerGraph{ @Override public String toString(){ return "PowerGraph{" + - "producers=" + producers + - ", consumers=" + consumers + - ", batteries=" + batteries + - ", all=" + all + - ", lastFrameUpdated=" + lastFrameUpdated + - ", graphID=" + graphID + - '}'; + "producers=" + producers + + ", consumers=" + consumers + + ", batteries=" + batteries + + ", all=" + all + + ", lastFrameUpdated=" + lastFrameUpdated + + ", graphID=" + graphID + + '}'; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java index 46ce4c12a2..5fa8d18eff 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java @@ -26,7 +26,7 @@ public class Incinerator extends Block{ update = true; solid = true; - basePowerUse = 0.05f; + consumes.powerDirect(0.05f); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java index 581a16f745..a1fa070367 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java @@ -45,7 +45,6 @@ public class MechPad extends Block{ update = true; solidifes = true; hasPower = true; - bufferedPowerConsumer = true; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java index 5321273f29..415fdbacf4 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java @@ -44,8 +44,7 @@ public class Reconstructor extends Block{ solidifes = true; hasPower = true; configurable = true; - basePowerUse = 30f; // capacity - bufferedPowerConsumer = true; + consumes.powerBuffered(30f); } protected static boolean checkValidTap(Tile tile, ReconstructorEntity entity, Player player){ diff --git a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java index 1942dbb199..6d0192634b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java @@ -38,8 +38,7 @@ public class RepairPoint extends Block{ layer2 = Layer.laser; hasPower = true; // TODO Adapt to new power system - Make it use power while repairing - basePowerUse = 20f; // capacity - bufferedPowerConsumer = true; + consumes.powerBuffered(20f); } @Override diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java index 62eebdfb21..a835bd21c6 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java @@ -11,7 +11,7 @@ import io.anuke.mindustry.world.meta.StatUnit; /** Consumer class for blocks which directly consume power without buffering it. */ public class ConsumePowerBuffered extends ConsumePower{ /** The maximum power capacity in power units. */ - protected final float powerCapacity; + public final float powerCapacity; /** * Adds a power buffer to the owner which takes ticksToFill number of ticks to be filled. diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java index 0ce7d593a2..e746ec3cc3 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java @@ -13,14 +13,6 @@ public class ConsumePowerDirect extends ConsumePower{ /** The minimum power satisfaction (fraction of powerPerTick) which must be achieved before the module may work. */ protected final float minimumSatisfaction; - /** - * Makes the owner consume powerPerTick each tick and disables it unless 60% of that power is being supplied. - * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. - */ - public ConsumePowerDirect(float powerPerTick){ - this(powerPerTick, 0.75f); - } - /** * Makes the owner consume powerPerTick each tick and disables it unless minimumSatisfaction (1.0 = 100%) of that power is being supplied. * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index e38607ad33..f75f10ad6f 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -36,6 +36,47 @@ public class Consumers{ return c; } + /** + * Creates a consumer which directly uses power without buffering it. The module will work while at least 60% of power is supplied. + * @param powerPerTick The amount of power which is required each tick for 100% efficiency. + * @return the created consumer object. + */ + public ConsumePower powerDirect(float powerPerTick){ + return powerDirect(powerPerTick, 0.6f); + } + + /** + * Creates a consumer which directly uses power without buffering it. The module will work while the available power is greater than or equal to the minimumSatisfaction percentage (0..1). + * @param powerPerTick The amount of power which is required each tick for 100% efficiency. + * @return the created consumer object. + */ + public ConsumePower powerDirect(float powerPerTick, float minimumSatisfaction){ + ConsumePower c = new ConsumePowerDirect(powerPerTick, minimumSatisfaction); + add(c); + return c; + } + + /** + * Creates a consumer which stores power and uses it only in case of certain events (e.g. a turret firing). + * It will take 60 ticks (one second) to fill the buffer, given enough power supplied. + * @param powerCapacity The maximum capacity in power units. + */ + public ConsumePower powerBuffered(float powerCapacity){ + // TODO Balance: How long should it take to fill a buffer? The lower this value, the more power will be "stolen" from direct consumers. + return powerBuffered(powerCapacity, 60); + } + + /** + * Creates a consumer which stores power and uses it only in case of certain events (e.g. a turret firing). + * @param powerCapacity The maximum capacity in power units. + * @param ticksToFill The number of ticks it shall take to fill the buffer. + */ + public ConsumePower powerBuffered(float powerCapacity, float ticksToFill){ + ConsumePower c = new ConsumePowerBuffered(powerCapacity, ticksToFill); + add(c); + return c; + } + public ConsumeItem item(Item item){ return item(item, 1); } @@ -81,6 +122,15 @@ public class Consumers{ return map.containsKey(type); } + public boolean hasSubclassOf(Class type){ + for(Consume consume : all()){ + if(type.isAssignableFrom(consume.getClass())){ + return true; + } + } + return false; + } + public T get(Class type){ if(!map.containsKey(type)){ throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); @@ -88,6 +138,15 @@ public class Consumers{ return (T) map.get(type); } + public T getFirstSubclassOf(Class type){ + for(Consume consume : all()){ + if(type.isAssignableFrom(consume.getClass())){ + return (T)consume; + } + } + throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "' (subclasses included)!"); + } + public Iterable all(){ return map.values(); } From d8ddb9dc82cce2f1bfc7b44760d882fb68759c63 Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 22:55:53 +0100 Subject: [PATCH 5/7] Merged the three ConsumePower classes into a single one --- core/src/io/anuke/mindustry/world/Block.java | 8 +-- .../world/blocks/distribution/MassDriver.java | 6 +-- .../world/blocks/power/PowerGraph.java | 17 +++--- .../world/consumers/ConsumePower.java | 54 +++++++++++++++++-- .../world/consumers/ConsumePowerBuffered.java | 43 --------------- .../world/consumers/ConsumePowerDirect.java | 35 ------------ .../mindustry/world/consumers/Consumers.java | 22 +------- 7 files changed, 67 insertions(+), 118 deletions(-) delete mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java delete mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 36c80a493d..8eebd822cc 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -20,7 +20,7 @@ import io.anuke.mindustry.input.CursorType; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.world.consumers.ConsumePowerBuffered; +import io.anuke.mindustry.world.consumers.ConsumePower; import io.anuke.mindustry.world.meta.*; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -338,7 +338,7 @@ public class Block extends BaseBlock { //TODO make this easier to config. public void setBars(){ - if(consumes.has(ConsumePowerBuffered.class)){ + if(consumes.has(ConsumePower.class) && consumes.get(ConsumePower.class).isBuffered){ bars.add(new BlockBar(BarType.power, true, tile -> tile.entity.power.satisfaction)); } if(hasLiquids) @@ -406,8 +406,8 @@ public class Block extends BaseBlock { explosiveness += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); } - if(consumes.has(ConsumePowerBuffered.class)){ - power += tile.entity.power.satisfaction * consumes.get(ConsumePowerBuffered.class).powerCapacity; + if(consumes.has(ConsumePower.class) && consumes.get(ConsumePower.class).isBuffered){ + power += tile.entity.power.satisfaction * consumes.get(ConsumePower.class).powerCapacity; } tempColor.mul(1f / units); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index db665d79f6..ea15719524 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -19,7 +19,7 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.consumers.ConsumePowerBuffered; +import io.anuke.mindustry.world.consumers.ConsumePower; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Effects; @@ -131,10 +131,10 @@ public class MassDriver extends Block{ public void setStats(){ super.setStats(); - if(!consumes.hasSubclassOf(ConsumePowerBuffered.class)){ + if(!consumes.has(ConsumePower.class) || !consumes.get(ConsumePower.class).isBuffered){ throw new RuntimeException("Mass Driver did not have a buffered power consumer object attached."); } - stats.add(BlockStat.powerShot, consumes.getFirstSubclassOf(ConsumePowerBuffered.class).powerCapacity, StatUnit.powerUnits); + stats.add(BlockStat.powerShot, consumes.get(ConsumePower.class).powerCapacity, StatUnit.powerUnits); } @Override 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 d8276f16c3..0afbe9d2da 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -6,9 +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.ConsumePowerBuffered; import io.anuke.mindustry.world.consumers.Consumers; import static io.anuke.mindustry.Vars.threads; @@ -48,8 +46,8 @@ public class PowerGraph{ float powerNeeded = 0f; for(Tile consumer : consumers){ Consumers consumes = consumer.block().consumes; - if(consumes.hasSubclassOf(ConsumePower.class)){ - powerNeeded += consumes.getFirstSubclassOf(ConsumePower.class).requestedPower(consumer.block(), consumer.entity); + if(consumes.has(ConsumePower.class)){ + powerNeeded += consumes.get(ConsumePower.class).requestedPower(consumer.block(), consumer.entity); } } return powerNeeded; @@ -59,8 +57,8 @@ public class PowerGraph{ float totalAccumulator = 0f; for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.hasSubclassOf(ConsumePowerBuffered.class)){ - totalAccumulator += battery.entity.power.satisfaction * consumes.getFirstSubclassOf(ConsumePowerBuffered.class).powerCapacity; + if(consumes.has(ConsumePower.class)){ + totalAccumulator += battery.entity.power.satisfaction * consumes.get(ConsumePower.class).powerCapacity; } } return totalAccumulator; @@ -70,8 +68,8 @@ public class PowerGraph{ float totalCapacity = 0f; for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.hasSubclassOf(ConsumePower.class)){ - totalCapacity += consumes.getFirstSubclassOf(ConsumePower.class).requestedPower(battery.block(), battery.entity); + if(consumes.has(ConsumePower.class)){ + totalCapacity += consumes.get(ConsumePower.class).requestedPower(battery.block(), battery.entity); } } return totalCapacity; @@ -105,7 +103,8 @@ public class PowerGraph{ float coverage = Math.min(1, produced / needed); for(Tile consumer : consumers){ - if(consumer.block().consumes.hasSubclassOf(ConsumePowerBuffered.class)){ + Consumers consumes = consumer.block().consumes; + if(consumes.has(ConsumePower.class) && consumes.get(ConsumePower.class).isBuffered){ consumer.entity.power.satisfaction += (1 - consumer.entity.power.satisfaction) * coverage; }else{ consumer.entity.power.satisfaction = coverage; diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java index 8f4e829d1d..4129f3345c 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -9,12 +9,40 @@ import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.mindustry.world.meta.StatUnit; /** Consumer class for blocks which consume power while being connected to a power graph. */ -public abstract class ConsumePower extends Consume{ +public class ConsumePower extends Consume{ /** The maximum amount of power which can be processed per tick. This might influence efficiency or load a buffer. */ protected final float powerPerTick; + /** The minimum power satisfaction (fraction of powerPerTick) which must be achieved before the module may work. */ + protected final float minimumSatisfaction; + /** The maximum power capacity in power units. */ + public final float powerCapacity; + /** True if the module can store power. */ + public final boolean isBuffered; - public ConsumePower(float powerPerTick){ + protected ConsumePower(float powerPerTick, float minimumSatisfaction, float powerCapacity, boolean isBuffered){ this.powerPerTick = powerPerTick; + this.minimumSatisfaction = minimumSatisfaction; + this.powerCapacity = powerCapacity; + this.isBuffered = isBuffered; + } + + /** + * Makes the owner consume powerPerTick each tick and disables it unless minimumSatisfaction (1.0 = 100%) of that power is being supplied. + * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. + * @param minimumSatisfaction The percentage of powerPerTick which must be available for the module to work. + */ + public static ConsumePower consumePowerBuffered(float powerPerTick, float minimumSatisfaction){ + return new ConsumePower(powerPerTick, minimumSatisfaction, 0.0f, true); + } + + /** + * Adds a power buffer to the owner which takes ticksToFill number of ticks to be filled. + * Note that this object does not remove power from the buffer. + * @param powerCapacity The maximum capacity in power units. + * @param ticksToFill The number of ticks it shall take to fill the buffer. + */ + public static ConsumePower consumePowerDirect(float powerCapacity, float ticksToFill){ + return new ConsumePower(powerCapacity / ticksToFill, 0.0f, powerCapacity, false); } @Override @@ -32,8 +60,24 @@ public abstract class ConsumePower extends Consume{ // Nothing to do since PowerGraph directly updates entity.power.satisfaction } - // valid(...) is implemented in subclass - // display(...) is implemented in subclass + @Override + public boolean valid(Block block, TileEntity entity){ + if(isBuffered){ + // TODO - Verify: It might be necessary to know about the power required per shot/event here. + return true; + }else{ + return entity.power.satisfaction >= minimumSatisfaction; + } + } + + @Override + public void display(BlockStats stats){ + if(isBuffered){ + stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerSecond); + }else{ + stats.add(BlockStat.powerUse, powerPerTick * 60f, StatUnit.powerSecond); + } + } /** * Retrieves the amount of power which is requested for the given block and entity. @@ -45,4 +89,6 @@ public abstract class ConsumePower extends Consume{ // TODO Is it possible to make the block not consume power while items/liquids are missing? return powerPerTick; } + + } 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 a835bd21c6..0000000000 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerBuffered.java +++ /dev/null @@ -1,43 +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; - -/** Consumer class for blocks which directly consume power without buffering it. */ -public class ConsumePowerBuffered extends ConsumePower{ - /** The maximum power capacity in power units. */ - public final float powerCapacity; - - /** - * Adds a power buffer to the owner which takes ticksToFill number of ticks to be filled. - * Note that this object does not remove power from the buffer. - * @param powerCapacity The maximum capacity in power units. - * @param ticksToFill The number of ticks it shall take to fill the buffer. - */ - public ConsumePowerBuffered(float powerCapacity, float ticksToFill){ - super(powerCapacity / ticksToFill); - this.powerCapacity = powerCapacity; - } - - @Override - public boolean valid(Block block, TileEntity entity){ - // TODO - Verify: It might be necessary to know about the power required per shot/event here. - return true; - } - - @Override - public void display(BlockStats stats){ - stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerSecond); - } - - @Override - public float requestedPower(Block block, TileEntity entity){ - // Only request power until the capacity is full - return Math.max(powerPerTick, powerCapacity * (1 - entity.power.satisfaction)); - } -} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java deleted file mode 100644 index e746ec3cc3..0000000000 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePowerDirect.java +++ /dev/null @@ -1,35 +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; - -/** Consumer class for blocks which directly consume power without buffering it. */ -public class ConsumePowerDirect extends ConsumePower{ - /** The minimum power satisfaction (fraction of powerPerTick) which must be achieved before the module may work. */ - protected final float minimumSatisfaction; - - /** - * Makes the owner consume powerPerTick each tick and disables it unless minimumSatisfaction (1.0 = 100%) of that power is being supplied. - * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. - * @param minimumSatisfaction The percentage of powerPerTick which must be available for the module to work. - */ - public ConsumePowerDirect(float powerPerTick, float minimumSatisfaction){ - super(powerPerTick); - this.minimumSatisfaction = minimumSatisfaction; - } - - @Override - public boolean valid(Block block, TileEntity entity){ - return entity.power.satisfaction >= minimumSatisfaction; - } - - @Override - public void display(BlockStats stats){ - stats.add(BlockStat.powerUse, powerPerTick * 60f, StatUnit.powerSecond); - } -} diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index f75f10ad6f..75b91a98e4 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -51,7 +51,7 @@ public class Consumers{ * @return the created consumer object. */ public ConsumePower powerDirect(float powerPerTick, float minimumSatisfaction){ - ConsumePower c = new ConsumePowerDirect(powerPerTick, minimumSatisfaction); + ConsumePower c = ConsumePower.consumePowerDirect(powerPerTick, minimumSatisfaction); add(c); return c; } @@ -72,7 +72,7 @@ public class Consumers{ * @param ticksToFill The number of ticks it shall take to fill the buffer. */ public ConsumePower powerBuffered(float powerCapacity, float ticksToFill){ - ConsumePower c = new ConsumePowerBuffered(powerCapacity, ticksToFill); + ConsumePower c = ConsumePower.consumePowerBuffered(powerCapacity, ticksToFill); add(c); return c; } @@ -122,15 +122,6 @@ public class Consumers{ return map.containsKey(type); } - public boolean hasSubclassOf(Class type){ - for(Consume consume : all()){ - if(type.isAssignableFrom(consume.getClass())){ - return true; - } - } - return false; - } - public T get(Class type){ if(!map.containsKey(type)){ throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); @@ -138,15 +129,6 @@ public class Consumers{ return (T) map.get(type); } - public T getFirstSubclassOf(Class type){ - for(Consume consume : all()){ - if(type.isAssignableFrom(consume.getClass())){ - return (T)consume; - } - } - throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "' (subclasses included)!"); - } - public Iterable all(){ return map.values(); } From 761728ac438a05870b9dfcb3b1fc95c958be6db1 Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 23:04:18 +0100 Subject: [PATCH 6/7] Fixed the ConsumePower constructors which got mixed up at some point --- .../io/anuke/mindustry/world/consumers/ConsumePower.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java index 4129f3345c..9aec5498de 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -31,8 +31,8 @@ public class ConsumePower extends Consume{ * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. * @param minimumSatisfaction The percentage of powerPerTick which must be available for the module to work. */ - public static ConsumePower consumePowerBuffered(float powerPerTick, float minimumSatisfaction){ - return new ConsumePower(powerPerTick, minimumSatisfaction, 0.0f, true); + public static ConsumePower consumePowerDirect(float powerPerTick, float minimumSatisfaction){ + return new ConsumePower(powerPerTick, minimumSatisfaction, 0.0f, false); } /** @@ -41,8 +41,8 @@ public class ConsumePower extends Consume{ * @param powerCapacity The maximum capacity in power units. * @param ticksToFill The number of ticks it shall take to fill the buffer. */ - public static ConsumePower consumePowerDirect(float powerCapacity, float ticksToFill){ - return new ConsumePower(powerCapacity / ticksToFill, 0.0f, powerCapacity, false); + public static ConsumePower consumePowerBuffered(float powerCapacity, float ticksToFill){ + return new ConsumePower(powerCapacity / ticksToFill, 0.0f, powerCapacity, true); } @Override From 920491ddb25449c381b6c06ea6f7a09ce32c5bb2 Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Wed, 21 Nov 2018 23:38:28 +0100 Subject: [PATCH 7/7] MassDriver now properly displays the power per shot --- .../mindustry/world/blocks/distribution/MassDriver.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index ea15719524..f81c344278 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -61,6 +61,7 @@ public class MassDriver extends Block{ layer = Layer.turret; hasPower = true; consumes.powerBuffered(30f); + consumes.require(ConsumePower.class); } @Remote(targets = Loc.both, called = Loc.server, forward = true) @@ -131,10 +132,7 @@ public class MassDriver extends Block{ public void setStats(){ super.setStats(); - if(!consumes.has(ConsumePower.class) || !consumes.get(ConsumePower.class).isBuffered){ - throw new RuntimeException("Mass Driver did not have a buffered power consumer object attached."); - } - stats.add(BlockStat.powerShot, consumes.get(ConsumePower.class).powerCapacity, StatUnit.powerUnits); + stats.add(BlockStat.powerShot, consumes.get(ConsumePower.class).powerCapacity * powerPercentageUsed, StatUnit.powerUnits); } @Override