From 0a76647175e819aa55608cf02dc8d1b8fed8dc5b Mon Sep 17 00:00:00 2001 From: Timmeey86 Date: Fri, 7 Dec 2018 19:38:14 +0100 Subject: [PATCH] ForceProjector should now work properly --- core/src/io/anuke/mindustry/world/Block.java | 6 +-- .../world/blocks/defense/ForceProjector.java | 38 ++++++++++++++----- .../world/blocks/distribution/MassDriver.java | 2 +- .../world/blocks/power/PowerGraph.java | 29 +++++++------- tests/src/test/java/power/PowerTests.java | 4 +- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 839d0af6bd..534ee13a52 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -345,7 +345,7 @@ public class Block extends BaseBlock { } public void setBars(){ - if(consumes.has(ConsumePower.class) && consumes.get(ConsumePower.class).isBuffered){ + if(consumes.hasSubtypeOf(ConsumePower.class) && consumes.getSubtypeOf(ConsumePower.class).isBuffered){ 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)); @@ -412,8 +412,8 @@ public class Block extends BaseBlock { explosiveness += tile.entity.liquids.sum((liquid, amount) -> liquid.flammability * amount / 2f); } - if(consumes.has(ConsumePower.class) && consumes.get(ConsumePower.class).isBuffered){ - power += tile.entity.power.satisfaction * consumes.get(ConsumePower.class).powerCapacity; + if(consumes.hasSubtypeOf(ConsumePower.class) && consumes.getSubtypeOf(ConsumePower.class).isBuffered){ + power += tile.entity.power.satisfaction * consumes.getSubtypeOf(ConsumePower.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 d80eb9546a..79732764a0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java @@ -44,7 +44,7 @@ public class ForceProjector extends Block { protected float cooldownBrokenBase = 0.35f; protected float basePowerDraw = 0.2f; protected float powerDamage = 0.1f; - protected final ConsumePower consumePower; + protected final ConsumeForceProjectorPower consumePower; protected TextureRegion topRegion; @@ -58,7 +58,8 @@ public class ForceProjector extends Block { hasItems = true; itemCapacity = 10; consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).optional(true).update(false); - consumePower = consumes.powerBuffered(60f); + consumePower = new ConsumeForceProjectorPower(60f, 60f); + consumes.add(consumePower); } @Override @@ -104,18 +105,27 @@ public class ForceProjector extends Block { Effects.effect(BlockFx.reactorsmoke, tile.drawx() + Mathf.range(tilesize/2f), tile.drawy() + Mathf.range(tilesize/2f)); } - // Draw base power from buffer manually (ConsumePower doesn't support both filling a buffer and drawing power additionally so we have to do it here) - entity.power.satisfaction -= Math.min(entity.power.satisfaction, basePowerDraw / consumePower.powerCapacity); + // Use Cases: + // - There is enough power in the buffer, and there are no shots fired => Draw base power and keep shield up + // - There is enough power in the buffer, but not enough power to cope for shots being fired => Draw all power and break shield + // - There is enough power in the buffer and enough power to cope for shots being fired => Draw base power + additional power based on shots absorbed + // - There is not enough base power in the buffer => Draw all power and break shield + // - The generator is in the AI base and uses cheat mode => Only draw power from shots being absorbed - if(entity.power.satisfaction == 0.0f && !cheat){ + float relativePowerDraw = 0.0f; + if(!cheat){ + relativePowerDraw = basePowerDraw / consumePower.powerCapacity; + } + + if(entity.power.satisfaction < relativePowerDraw){ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.15f); + entity.power.satisfaction = .0f; if(entity.warmup <= 0.09f){ entity.broken = true; } }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.1f); - float relativePowerDraw = powerDamage * entity.delta() * (1f + entity.buildup / breakage) / consumePower.powerCapacity; - entity.power.satisfaction -= Math.min(relativePowerDraw, entity.power.satisfaction); + entity.power.satisfaction -= Math.min(entity.power.satisfaction, relativePowerDraw); } if(entity.buildup > 0){ @@ -150,10 +160,10 @@ public class ForceProjector extends Block { if(trait.canBeAbsorbed() && trait.getTeam() != tile.getTeam() && isInsideHexagon(trait.getX(), trait.getY(), realRadius * 2f, tile.drawx(), tile.drawy())){ trait.absorb(); Effects.effect(BulletFx.absorb, trait); - float relativePowerDraw = trait.getShieldDamage() * powerDamage / consumePower.powerCapacity; + float relativeDamagePowerDraw = trait.getShieldDamage() * powerDamage / consumePower.powerCapacity; entity.hit = 1f; - entity.power.satisfaction -= Math.min(relativePowerDraw, entity.power.satisfaction); + entity.power.satisfaction -= Math.min(relativeDamagePowerDraw, entity.power.satisfaction); if(entity.power.satisfaction <= 0.0001f){ entity.buildup += trait.getShieldDamage() * entity.warmup * 2f; } @@ -264,4 +274,14 @@ public class ForceProjector extends Block { return shieldGroup; } } + + public class ConsumeForceProjectorPower extends ConsumePower{ + public ConsumeForceProjectorPower(float powerCapacity, float ticksToFill){ + super(powerCapacity / ticksToFill, 0.0f, powerCapacity, true); + } + @Override + public boolean valid(Block block, TileEntity entity){ + return entity.power.satisfaction >= basePowerDraw / powerCapacity && super.valid(block, entity); + } + } } 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 390f13f46b..80eea77ef8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -131,7 +131,7 @@ public class MassDriver extends Block{ public void setStats(){ super.setStats(); - stats.add(BlockStat.powerShot, consumes.get(ConsumePower.class).powerCapacity * powerPercentageUsed, StatUnit.powerUnits); + stats.add(BlockStat.powerShot, consumes.getSubtypeOf(ConsumePower.class).powerCapacity * powerPercentageUsed, 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 a83f210c7b..45311afcd5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -48,8 +48,8 @@ public class PowerGraph{ float powerNeeded = 0f; for(Tile consumer : consumers){ Consumers consumes = consumer.block().consumes; - if(consumes.has(ConsumePower.class)){ - ConsumePower consumePower = consumes.get(ConsumePower.class); + if(consumes.hasSubtypeOf(ConsumePower.class)){ + ConsumePower consumePower = consumes.getSubtypeOf(ConsumePower.class); if(otherConsumersAreValid(consumer, consumePower)){ powerNeeded += consumePower.requestedPower(consumer.block(), consumer.entity) * consumer.entity.delta(); } @@ -62,8 +62,8 @@ public class PowerGraph{ float totalAccumulator = 0f; for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.has(ConsumePower.class)){ - totalAccumulator += battery.entity.power.satisfaction * consumes.get(ConsumePower.class).powerCapacity; + if(consumes.hasSubtypeOf(ConsumePower.class)){ + totalAccumulator += battery.entity.power.satisfaction * consumes.getSubtypeOf(ConsumePower.class).powerCapacity; } } return totalAccumulator; @@ -73,8 +73,8 @@ public class PowerGraph{ float totalCapacity = 0f; for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.has(ConsumePower.class)){ - totalCapacity += consumes.get(ConsumePower.class).requestedPower(battery.block(), battery.entity) * battery.entity.delta(); + if(consumes.hasSubtypeOf(ConsumePower.class)){ + totalCapacity += consumes.getSubtypeOf(ConsumePower.class).requestedPower(battery.block(), battery.entity) * battery.entity.delta(); } } return totalCapacity; @@ -88,8 +88,8 @@ public class PowerGraph{ float consumedPowerPercentage = Math.min(1.0f, needed / stored); for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.has(ConsumePower.class)){ - ConsumePower consumePower = consumes.get(ConsumePower.class); + if(consumes.hasSubtypeOf(ConsumePower.class)){ + ConsumePower consumePower = consumes.getSubtypeOf(ConsumePower.class); if(consumePower.powerCapacity > 0f){ battery.entity.power.satisfaction = Math.max(0.0f, battery.entity.power.satisfaction - consumedPowerPercentage); } @@ -104,8 +104,8 @@ public class PowerGraph{ for(Tile battery : batteries){ Consumers consumes = battery.block().consumes; - if(consumes.has(ConsumePower.class)){ - ConsumePower consumePower = consumes.get(ConsumePower.class); + if(consumes.hasSubtypeOf(ConsumePower.class)){ + ConsumePower consumePower = consumes.getSubtypeOf(ConsumePower.class); if(consumePower.powerCapacity > 0f){ float additionalPowerPercentage = Math.min(1.0f, excess / consumePower.powerCapacity); battery.entity.power.satisfaction = Math.min(1.0f, battery.entity.power.satisfaction + additionalPowerPercentage); @@ -121,8 +121,8 @@ public class PowerGraph{ float coverage = Math.min(1, produced / needed); for(Tile consumer : consumers){ Consumers consumes = consumer.block().consumes; - if(consumes.has(ConsumePower.class)){ - ConsumePower consumePower = consumes.get(ConsumePower.class); + if(consumes.hasSubtypeOf(ConsumePower.class)){ + ConsumePower consumePower = consumes.getSubtypeOf(ConsumePower.class); if(!otherConsumersAreValid(consumer, consumePower)){ consumer.entity.power.satisfaction = 0.0f; // Only supply power if the consumer would get valid that way }else{ @@ -180,7 +180,10 @@ 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.satisfaction = 0.0f; + other.entity.power.graph = null; + } } all.clear(); producers.clear(); diff --git a/tests/src/test/java/power/PowerTests.java b/tests/src/test/java/power/PowerTests.java index a79089ab91..64bfa2e451 100644 --- a/tests/src/test/java/power/PowerTests.java +++ b/tests/src/test/java/power/PowerTests.java @@ -174,8 +174,8 @@ public class PowerTests extends PowerTestFixture{ powerGraph.update(); assertEquals(0.0f, consumerTile.entity.power.satisfaction, MathUtils.FLOAT_ROUNDING_ERROR); - if(consumerTile.block().consumes.has(ConsumePower.class)){ - ConsumePower consumePower = consumerTile.block().consumes.get(ConsumePower.class); + if(consumerTile.block().consumes.hasSubtypeOf(ConsumePower.class)){ + ConsumePower consumePower = consumerTile.block().consumes.getSubtypeOf(ConsumePower.class); assertFalse(consumePower.valid(consumerTile.block(), consumerTile.entity())); } }