From c06152de0738cedfd1e60590f0e3c9ef9544c856 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 8 Jul 2018 00:04:41 -0400 Subject: [PATCH] Consumption system more or less complete --- .../io/anuke/mindustry/content/Liquids.java | 2 +- core/src/io/anuke/mindustry/core/UI.java | 2 +- .../anuke/mindustry/entities/TileEntity.java | 16 ++--- .../anuke/mindustry/io/versions/Save16.java | 2 + .../src/io/anuke/mindustry/net/NetworkIO.java | 2 + .../io/anuke/mindustry/world/BaseBlock.java | 13 +++- core/src/io/anuke/mindustry/world/Block.java | 7 +- core/src/io/anuke/mindustry/world/Tile.java | 14 +--- .../world/blocks/production/Drill.java | 36 ++-------- .../world/blocks/production/LiquidMixer.java | 58 +++++---------- .../world/blocks/production/PowerCrafter.java | 2 +- .../world/blocks/production/Pump.java | 34 ++++----- .../world/blocks/production/Separator.java | 45 +++--------- .../world/blocks/production/SolidPump.java | 29 ++++---- .../world/blocks/units/MechFactory.java | 1 + .../mindustry/world/consumers/Consume.java | 27 ++++++- .../world/consumers/ConsumeItem.java | 34 +++++++++ .../world/consumers/ConsumeLiquid.java | 46 ++++++++++++ .../world/consumers/ConsumePower.java | 35 +++++++++ .../mindustry/world/consumers/Consumers.java | 71 +++++++++++++++++++ .../anuke/mindustry/world/consumers/Uses.java | 7 ++ .../{blocks => modules}/BlockModule.java | 2 +- .../world/modules/ConsumeModule.java | 51 +++++++++++++ .../world/modules/InventoryModule.java | 1 - .../mindustry/world/modules/LiquidModule.java | 1 - .../mindustry/world/modules/PowerModule.java | 2 - 26 files changed, 359 insertions(+), 181 deletions(-) create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumePower.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/Consumers.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/Uses.java rename core/src/io/anuke/mindustry/world/{blocks => modules}/BlockModule.java (86%) create mode 100644 core/src/io/anuke/mindustry/world/modules/ConsumeModule.java diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index 097d708a30..86adf3cf85 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -7,7 +7,7 @@ import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.Liquid; public class Liquids implements ContentList { - public static Liquid none, water, lava, oil, cryofluid; + public static Liquid water, lava, oil, cryofluid; @Override public void load() { diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index be54f94247..53e5497a1b 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -147,7 +147,7 @@ public class UI extends SceneModule{ } Graphics.end(); - + Draw.color(); } @Override diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 3347ed4ccf..46b66c389e 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Array; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.mindustry.content.fx.Fx; @@ -11,9 +10,10 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.CallBlocks; import io.anuke.mindustry.net.In; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.consumers.Consume; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Wall; +import io.anuke.mindustry.world.consumers.Uses; +import io.anuke.mindustry.world.modules.ConsumeModule; import io.anuke.mindustry.world.modules.InventoryModule; import io.anuke.mindustry.world.modules.LiquidModule; import io.anuke.mindustry.world.modules.PowerModule; @@ -43,8 +43,7 @@ public class TileEntity extends BaseEntity implements TargetTrait { public PowerModule power; public InventoryModule items; public LiquidModule liquids; - - public Array consumers = new Array<>(); + public ConsumeModule cons; private boolean dead = false; private boolean sleeping; @@ -59,7 +58,6 @@ public class TileEntity extends BaseEntity implements TargetTrait { health = tile.block().health; timer = new Timer(tile.block().timers); - tile.block().setConsumers(consumers); if(added){ add(); @@ -135,6 +133,10 @@ public class TileEntity extends BaseEntity implements TargetTrait { return tile; } + public boolean consumed(Uses uses){ + return tile.block().consumes.get(uses).valid(tile.block(), this); + } + @Override public Team getTeam() { return tile.getTeam(); @@ -160,9 +162,7 @@ public class TileEntity extends BaseEntity implements TargetTrait { } tile.block().update(tile); - for(Consume cons : consumers){ - cons.update(this); - } + cons.update(this); } } diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 263ff28e06..b116b627cc 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -121,6 +121,7 @@ public class Save16 extends SaveFileVersion { if (tile.entity.items != null) tile.entity.items.read(stream); if (tile.entity.power != null) tile.entity.power.read(stream); if (tile.entity.liquids != null) tile.entity.liquids.read(stream); + if (tile.entity.cons != null) tile.entity.cons.read(stream); tile.entity.read(stream); @@ -220,6 +221,7 @@ public class Save16 extends SaveFileVersion { if(tile.entity.items != null) tile.entity.items.write(stream); if(tile.entity.power != null) tile.entity.power.write(stream); if(tile.entity.liquids != null) tile.entity.liquids.write(stream); + if(tile.entity.cons != null) tile.entity.cons.write(stream); tile.entity.write(stream); }else if(tile.getWallID() == 0){ diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 035decf9e3..1625079e2e 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -75,6 +75,7 @@ public class NetworkIO { if(tile.entity.items != null) tile.entity.items.write(stream); if(tile.entity.power != null) tile.entity.power.write(stream); if(tile.entity.liquids != null) tile.entity.liquids.write(stream); + if(tile.entity.cons != null) tile.entity.cons.write(stream); tile.entity.write(stream); }else if(tile.getWallID() == 0){ @@ -193,6 +194,7 @@ public class NetworkIO { if (tile.entity.items != null) tile.entity.items.read(stream); if (tile.entity.power != null) tile.entity.power.read(stream); if (tile.entity.liquids != null) tile.entity.liquids.read(stream); + if (tile.entity.cons != null) tile.entity.cons.read(stream); tile.entity.read(stream); }else if(wallid == 0){ diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index b0c91e6287..fec0728ac0 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -6,6 +6,8 @@ import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.world.consumers.Consumers; +import io.anuke.mindustry.world.consumers.Uses; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.util.Mathf; @@ -23,6 +25,12 @@ public abstract class BaseBlock { public float liquidFlowFactor = 4.9f; public float powerCapacity = 10f; + public Consumers consumes = new Consumers(); + + public boolean shouldConsume(Tile tile){ + return true; + } + /**Returns the amount of items this block can accept.*/ public int acceptStack(Item item, int amount, Tile tile, Unit source){ if(acceptItem(item, tile, tile) && hasItems && source.getTeam() == tile.getTeam()){ @@ -59,12 +67,13 @@ public abstract class BaseBlock { } public boolean acceptItem(Item item, Tile tile, Tile source){ - return false; + return tile.entity != null && consumes.item() == item && tile.entity.items.total() < itemCapacity; } public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ return tile.entity.liquids.get(liquid) + amount < liquidCapacity && - (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f)); + (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f)) + && (!consumes.has(Uses.liquid) || consumes.liquid() == liquid); } public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 51f5bce094..93ecd50975 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -19,7 +19,6 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.input.CursorType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.world.consumers.Consume; import io.anuke.mindustry.world.meta.*; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -133,10 +132,6 @@ public class Block extends BaseBlock implements Content{ blocks.add(this); } - public void setConsumers(Array consumers){ - - } - public boolean isLayer(Tile tile){return true;} public boolean isLayer2(Tile tile){return true;} public void drawLayer(Tile tile){} @@ -221,6 +216,8 @@ public class Block extends BaseBlock implements Content{ stats.add(BlockStat.size, "{0}x{0}", size); stats.add(BlockStat.health, health, StatUnit.none); + consumes.forEach(cons -> cons.display(stats)); + if(hasPower) stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerUnits); if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits); if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items); diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 3393a2de39..0f0c27a8d9 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -352,28 +352,15 @@ public class Tile implements PosTrait, TargetTrait { GridPoint2 pc = Geometry.d4[i]; GridPoint2 pcprev = Geometry.d4[Mathf.mod(i - 1, 4)]; GridPoint2 pcnext = Geometry.d4[(i + 1) % 4]; - GridPoint2 pe = Geometry.d8edge[i]; Tile tc = world.tile(x + pc.x, y + pc.y); Tile tprev = world.tile(x + pcprev.x, y + pcprev.y); Tile tnext = world.tile(x + pcnext.x, y + pcnext.y); - Tile te = world.tile(x + pe.x, y + pe.y); - Tile tex = world.tile(x, y + pe.y); - Tile tey = world.tile(x + pe.x, y); //check for cardinal direction elevation changes and bitmask that if(tc != null && tprev != null && tnext != null && ((tc.elevation < elevation && tc.elevation != -1))){ cliffs |= (1 << (i*2)); } - - //00S - //0X0 - //010 - - //check for corner bitmasking: doesn't even get checked so it doesn't matter - /*if(te != null && tex != null && tey != null && te.elevation == -1 && elevation > 0){ - cliffs |= (1 << (((i+1)%4)*2)); - }*/ } if(occluded){ cost += 1; @@ -394,6 +381,7 @@ public class Tile implements PosTrait, TargetTrait { if (block.hasEntity()) { entity = block.getEntity().init(this, block.update); + block.consumes.addAll(entity.cons.all()); if(block.hasItems) entity.items = new InventoryModule(); if(block.hasLiquids) entity.liquids = new LiquidModule(); if(block.hasPower) entity.power = new PowerModule(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index 0de56aea3b..0c315c51bd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -8,9 +8,9 @@ import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.Uses; import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; @@ -35,12 +35,6 @@ public class Drill extends Block{ protected int tier; /**Base time to drill one ore, in frames.*/ protected float drillTime = 300; - /**power use per frame.*/ - public float powerUse = 0.08f; - /**liquid use per frame.*/ - protected float liquidUse = 0.05f; - /**Input liquid. Set hasLiquids to true so this is used.*/ - protected Liquid inputLiquid = Liquids.water; /**Whether the liquid is required to drill. If false, then it will be used as a speed booster.*/ protected boolean liquidRequired = false; /**How many times faster the drill will progress when boosted by liquid.*/ @@ -74,6 +68,8 @@ public class Drill extends Block{ hasLiquids = true; liquidCapacity = 5f; hasItems = true; + + consumes.liquid(Liquids.water, 0.01f).optional(true); } @Override @@ -141,14 +137,6 @@ public class Drill extends Block{ }); stats.add(BlockStat.drillSpeed, 60f/drillTime, StatUnit.itemsSecond); - - if(inputLiquid != null){ - stats.add(BlockStat.inputLiquid, inputLiquid); - } - - if(hasPower){ - stats.add(BlockStat.powerUse, powerUse*60f, StatUnit.powerSecond); - } } @Override @@ -175,20 +163,11 @@ public class Drill extends Block{ entity.drillTime += entity.warmup * Timers.delta(); - float powerUsed = Math.min(powerCapacity, powerUse * Timers.delta()); - float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta()); - - if(entity.items.total() < itemCapacity && toAdd.size > 0 && - (!hasPower || entity.power.amount >= powerUsed) && - (!liquidRequired || entity.liquids.amount >= liquidUsed)){ - - if(hasPower) entity.power.amount -= powerUsed; - if(liquidRequired) entity.liquids.amount -= liquidUsed; + if(entity.items.total() < itemCapacity && toAdd.size > 0 && entity.cons.valid()){ float speed = 1f; - if(entity.liquids.amount >= liquidUsed && !liquidRequired){ - entity.liquids.amount -= liquidUsed; + if(entity.consumed(Uses.liquid) && !liquidRequired){ speed = liquidBoostIntensity; } @@ -235,11 +214,6 @@ public class Drill extends Block{ } } - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid; - } - @Override public TileEntity getEntity() { return new DrillEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java index 02b889fc34..0611b7c727 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java @@ -1,28 +1,22 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.LiquidBlock; +import io.anuke.mindustry.world.consumers.ConsumeLiquid; +import io.anuke.mindustry.world.consumers.Uses; import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Timers; public class LiquidMixer extends LiquidBlock{ - protected Liquid inputLiquid = Liquids.none; - protected Liquid outputLiquid = Liquids.none; - protected Item inputItem = null; + protected Liquid outputLiquid; protected float liquidPerItem = 50f; - protected float powerUse = 0f; public LiquidMixer(String name) { super(name); hasItems = true; - hasPower = true; rotate = false; - liquidRegion = name() + "-liquid"; solid = true; } @@ -31,43 +25,29 @@ public class LiquidMixer extends LiquidBlock{ super.setStats(); stats.add(BlockStat.liquidOutput, outputLiquid); - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); - stats.add(BlockStat.inputItem, inputItem); + } + + @Override + public boolean shouldConsume(Tile tile){ + return tile.entity.liquids.get(outputLiquid) < liquidCapacity; } @Override public void update(Tile tile){ - float used = Math.min(Timers.delta() * powerUse, tile.entity.power.amount); - - tryDumpLiquid(tile); - - if(tile.entity.power.amount > used) tile.entity.power.amount -= used; - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { - return item == inputItem && tile.entity.items.get(item) < itemCapacity; - } - - @Override - public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) { LiquidMixerEntity entity = tile.entity(); - if(liquid == inputLiquid && tile.entity.items.has(inputItem, (int)((entity.accumulator + amount)/amount)) && - tile.entity.power.amount >= powerUse){ - - amount = Math.min(liquidCapacity - tile.entity.liquids.amount, amount); - - entity.accumulator += amount; - int items = (int)(entity.accumulator / liquidPerItem); - entity.items.remove(inputItem, items); - entity.accumulator %= liquidPerItem; - entity.liquids.liquid = outputLiquid; - entity.liquids.amount += amount; - return amount; - }else{ - return 0; + if(tile.entity.cons.valid()){ + float use = Math.min(consumes.get(Uses.liquid).used() * Timers.delta(), liquidCapacity - entity.liquids.get(outputLiquid)); + entity.accumulator += use; + entity.liquids.add(outputLiquid, use); + for (int i = 0; i < (int)(entity.accumulator / liquidPerItem); i++) { + if(!entity.items.has(consumes.item())) break; + entity.items.remove(consumes.item(), 1); + entity.accumulator --; + } } + + tryDumpLiquid(tile, outputLiquid); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java index efe340ce3a..f2cbe29263 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java @@ -76,7 +76,7 @@ public class PowerCrafter extends Block{ } if(outputLiquid != null){ - tryDumpLiquid(tile); + tryDumpLiquid(tile, entity.liquids.current()); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java index 7e98c47e3d..cbfff62e71 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Pump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Pump.java @@ -11,7 +11,6 @@ import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.util.Mathf; public class Pump extends LiquidBlock{ protected final Array drawTiles = new Array<>(); @@ -19,8 +18,6 @@ public class Pump extends LiquidBlock{ /**Pump amount per tile this block is on.*/ protected float pumpAmount = 1f; - /**Power used per frame per tile this block is on.*/ - protected float powerUse = 0f; /**Maximum liquid tier this pump can use.*/ protected int tier = 0; @@ -29,10 +26,16 @@ public class Pump extends LiquidBlock{ layer = Layer.overlay; liquidFlowFactor = 3f; group = BlockGroup.liquids; - liquidRegion = "pump-liquid"; floating = true; } + @Override + public void load() { + super.load(); + + liquidRegion = Draw.region("pump-liquid"); + } + @Override public void setStats(){ super.setStats(); @@ -48,8 +51,8 @@ public class Pump extends LiquidBlock{ public void draw(Tile tile){ Draw.rect(name(), tile.drawx(), tile.drawy()); - Draw.color(tile.entity.liquids.liquid.color); - Draw.alpha(tile.entity.liquids.amount / liquidCapacity); + Draw.color(tile.entity.liquids.current().color); + Draw.alpha(tile.entity.liquids.total() / liquidCapacity); Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(); } @@ -96,23 +99,12 @@ public class Pump extends LiquidBlock{ liquidDrop = tile.floor().liquidDrop; } - if(hasPower){ - float used = Math.min(powerCapacity, tiles * powerUse * Timers.delta()); - - //multiply liquid obtained by the fraction of power this pump has to pump it - //e.g. only has 50% power required = only pumps 50% of liquid that it can - tiles *= Mathf.clamp(tile.entity.power.amount / used); - - tile.entity.power.amount -= Math.min(tile.entity.power.amount, used); + if(tile.entity.cons.valid() && liquidDrop != null){ + float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), tiles * pumpAmount * Timers.delta()); + tile.entity.liquids.add(liquidDrop, maxPump); } - if(liquidDrop != null){ - float maxPump = Math.min(liquidCapacity - tile.entity.liquids.amount, tiles * pumpAmount * Timers.delta()); - tile.entity.liquids.liquid = liquidDrop; - tile.entity.liquids.amount += maxPump; - } - - tryDumpLiquid(tile); + tryDumpLiquid(tile, tile.entity.liquids.current()); } protected boolean isValid(Tile tile){ diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java index 2ee107fb5f..3fbaab0ef2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java @@ -2,14 +2,14 @@ package io.anuke.mindustry.world.blocks.production; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterEntity; import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.mindustry.world.meta.values.ItemFilterValue; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -20,11 +20,7 @@ import io.anuke.ucore.util.Mathf; public class Separator extends Block { protected final int timerDump = timers ++; - protected Liquid liquid; - protected Item item; protected Item[] results; - protected float liquidUse; - protected float powerUse; protected float filterTime; protected float spinnerRadius = 2.5f; protected float spinnerLength = 1f; @@ -42,6 +38,9 @@ public class Separator extends Block { solid = true; hasItems = true; hasLiquids = true; + + consumes.item(Items.stone); + consumes.liquid(Liquids.water, 0.1f); } @Override @@ -55,13 +54,6 @@ public class Separator extends Block { public void setStats() { super.setStats(); - if(hasPower){ - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); - } - - stats.add(BlockStat.liquidUse, liquidUse * 60f, StatUnit.liquidSecond); - stats.add(BlockStat.inputLiquid, liquid); - stats.add(BlockStat.inputItem, item); stats.add(BlockStat.outputItem, new ItemFilterValue(item -> { for(Item i : results){ if(item == i) return true; @@ -76,8 +68,8 @@ public class Separator extends Block { GenericCrafterEntity entity = tile.entity(); - Draw.color(tile.entity.liquids.liquid.color); - Draw.alpha(tile.entity.liquids.amount / liquidCapacity); + Draw.color(tile.entity.liquids.current().color); + Draw.alpha(tile.entity.liquids.total() / liquidCapacity); Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(color); @@ -90,17 +82,10 @@ public class Separator extends Block { public void update(Tile tile) { GenericCrafterEntity entity = tile.entity(); - float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta()); - float powerUsed = Math.min(powerCapacity, powerUse * Timers.delta()); - entity.totalProgress += entity.warmup*Timers.delta(); - if(entity.liquids.amount >= liquidUsed && entity.items.has(item) && - (!hasPower || entity.power.amount >= powerUsed)){ + if(entity.cons.valid()){ entity.progress += 1f/filterTime; - entity.liquids.amount -= liquidUsed; - if(hasPower) entity.power.amount -= powerUsed; - entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f); }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.02f); @@ -109,7 +94,7 @@ public class Separator extends Block { if(entity.progress >= 1f){ entity.progress = 0f; Item item = Mathf.select(results); - entity.items.remove(this.item, 1); + entity.items.remove(consumes.item(), 1); if(item != null){ offloading = true; offloadNear(tile, item); @@ -124,17 +109,7 @@ public class Separator extends Block { @Override public boolean canDump(Tile tile, Tile to, Item item) { - return offloading || item != this.item; - } - - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - return super.acceptLiquid(tile, source, liquid, amount) && this.liquid == liquid; - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { - return this.item == item && tile.entity.items.get(item) < itemCapacity; + return offloading || item != consumes.item(); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index 6a4cfd6ccc..ac852972e0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -7,7 +7,6 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Liquid; 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.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -17,8 +16,6 @@ import io.anuke.ucore.util.Mathf; /**Pump that makes liquid from solids and takes in power. Only works on solid floor blocks.*/ public class SolidPump extends Pump { protected Liquid result = Liquids.water; - /**Power use per liquid unit.*/ - protected float powerUse = 0.1f; protected Effect updateEffect = Fx.none; protected float updateEffectChance = 0.02f; protected float rotateSpeed = 1f; @@ -26,7 +23,13 @@ public class SolidPump extends Pump { public SolidPump(String name){ super(name); hasPower = true; - liquidRegion = name + "-liquid"; + } + + @Override + public void load() { + super.load(); + + liquidRegion = Draw.region(name + "-liquid"); } @Override @@ -34,8 +37,6 @@ public class SolidPump extends Pump { super.setStats(); stats.remove(BlockStat.liquidOutput); - - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); stats.add(BlockStat.liquidOutput, result); } @@ -44,8 +45,8 @@ public class SolidPump extends Pump { SolidPumpEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); - Draw.color(tile.entity.liquids.liquid.color); - Draw.alpha(tile.entity.liquids.amount / liquidCapacity); + Draw.color(tile.entity.liquids.current().color); + Draw.alpha(tile.entity.liquids.total() / liquidCapacity); Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(); Draw.rect(name + "-rotator", tile.drawx(), tile.drawy(), entity.pumpTime * rotateSpeed); @@ -61,8 +62,6 @@ public class SolidPump extends Pump { public void update(Tile tile){ SolidPumpEntity entity = tile.entity(); - float used = Math.min(powerUse * Timers.delta(), powerCapacity); - float fraction = 0f; if(isMultiblock()){ @@ -75,11 +74,9 @@ public class SolidPump extends Pump { if(isValid(tile)) fraction = 1f; } - if(tile.entity.power.amount >= used && tile.entity.liquids.amount < liquidCapacity - 0.001f){ - float maxPump = Math.min(liquidCapacity - tile.entity.liquids.amount, pumpAmount * Timers.delta() * fraction); - tile.entity.liquids.liquid = result; - tile.entity.liquids.amount += maxPump; - tile.entity.power.amount -= used; + if(tile.entity.cons.valid() && tile.entity.liquids.total() < liquidCapacity - 0.001f){ + float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), pumpAmount * Timers.delta() * fraction); + tile.entity.liquids.add(result, maxPump); entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f); if(Mathf.chance(Timers.delta() * updateEffectChance)) Effects.effect(updateEffect, entity.x + Mathf.range(size*2f), entity.y + Mathf.range(size*2f)); @@ -89,7 +86,7 @@ public class SolidPump extends Pump { entity.pumpTime += entity.warmup * Timers.delta(); - tryDumpLiquid(tile); + tryDumpLiquid(tile, entity.liquids.current()); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java index 99c54704cf..deff90de86 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechFactory.java @@ -52,6 +52,7 @@ public class MechFactory extends Block{ @Override public void tapped(Tile tile, Player player) { + if(mobile && !mech.flying) return; if(checkValidTap(tile, player)){ CallBlocks.onMechFactoryTap(player, tile); diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index 977435abae..f920ebf888 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -1,8 +1,29 @@ package io.anuke.mindustry.world.consumers; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.meta.BlockStats; -public interface Consume { - void update(TileEntity entity); - boolean valid(); +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public abstract class Consume { + private boolean optional; + + public void optional(boolean optional) { + this.optional = optional; + } + + public boolean isOptional() { + return optional; + } + + public abstract void update(Block block, TileEntity entity); + public abstract boolean valid(Block block, TileEntity entity); + public abstract void display(BlockStats stats); + + public Consume copy(){ return this; } + public void write(DataOutput stream) throws IOException{} + public void read(DataInput stream) throws IOException{} } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java new file mode 100644 index 0000000000..e1d3db4e64 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java @@ -0,0 +1,34 @@ +package io.anuke.mindustry.world.consumers; + +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.meta.BlockStat; +import io.anuke.mindustry.world.meta.BlockStats; + +public class ConsumeItem extends Consume { + private final Item item; + + public ConsumeItem(Item item) { + this.item = item; + } + + public Item get() { + return item; + } + + @Override + public void update(Block block, TileEntity entity) { + //doesn't update because consuming items is very specific + } + + @Override + public boolean valid(Block block, TileEntity entity) { + return entity.items.has(item); + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.inputItem, item); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java new file mode 100644 index 0000000000..2fa7e36404 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -0,0 +1,46 @@ +package io.anuke.mindustry.world.consumers; + +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.type.Liquid; +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 ConsumeLiquid extends Consume { + private final float use; + private final Liquid liquid; + + public ConsumeLiquid(Liquid liquid, float use) { + this.liquid = liquid; + this.use = use; + } + + public float used() { + return use; + } + + public Liquid get() { + return liquid; + } + + @Override + public void update(Block block, TileEntity entity) { + entity.liquids.remove(liquid, Math.min(use(block), entity.liquids.get(liquid))); + } + + @Override + public boolean valid(Block block, TileEntity entity) { + return entity.liquids.get(liquid) >= use(block); + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.liquidUse, use * 60f, StatUnit.liquidSecond); + stats.add(BlockStat.inputLiquid, liquid); + } + + float use(Block block) { + return Math.min(use, block.liquidCapacity); + } +} 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..84f8636b90 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.world.consumers; + +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; +import io.anuke.ucore.core.Timers; + +public class ConsumePower extends Consume { + private final float use; + + public ConsumePower(float use) { + this.use = use; + } + + @Override + public void update(Block block, TileEntity entity) { + entity.power.amount -= Math.min(use(block), entity.power.amount); + } + + @Override + public boolean valid(Block block, TileEntity entity) { + return entity.power.amount >= use(block); + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.powerUse, use * 60f, StatUnit.powerSecond); + } + + float use(Block block){ + return Math.min(use * Timers.delta(), block.powerCapacity); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java new file mode 100644 index 0000000000..02590d85c4 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -0,0 +1,71 @@ +package io.anuke.mindustry.world.consumers; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.Liquid; +import io.anuke.ucore.function.Consumer; + +public class Consumers { + private Consume[] consumeMap = new Consume[Uses.values().length]; + + public ConsumePower power(float amount){ + ConsumePower p = new ConsumePower(amount); + add(Uses.power, p); + return p; + } + + public ConsumeLiquid liquid(Liquid liquid, float amount){ + ConsumeLiquid c = new ConsumeLiquid(liquid, amount); + add(Uses.liquid, c); + return c; + } + + public ConsumeItem item(Item item){ + ConsumeItem i = new ConsumeItem(item); + add(Uses.items, i); + return i; + } + + public Item item(){ + return this.get(Uses.items).get(); + } + + public Liquid liquid(){ + return this.get(Uses.liquid).get(); + } + + public void add(Uses type, Consume consume){ + consumeMap[type.ordinal()] = consume; + } + + public void remove(Uses type){ + consumeMap[type.ordinal()] = null; + } + + public boolean has(Uses type){ + return consumeMap[type.ordinal()] != null; + } + + public T get(Uses type){ + if(consumeMap[type.ordinal()] == null){ + throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); + } + return (T)consumeMap[type.ordinal()]; + } + + public void forEach(Consumer cons){ + for (Consume c : consumeMap) { + if (c != null) { + cons.accept(c); + } + } + } + + public void addAll(Array result){ + for (Consume c : consumeMap) { + if (c != null) { + result.add(c.copy()); + } + } + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/Uses.java b/core/src/io/anuke/mindustry/world/consumers/Uses.java new file mode 100644 index 0000000000..c1bb49632a --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/Uses.java @@ -0,0 +1,7 @@ +package io.anuke.mindustry.world.consumers; + +public enum Uses { + power, + liquid, + items, +} diff --git a/core/src/io/anuke/mindustry/world/blocks/BlockModule.java b/core/src/io/anuke/mindustry/world/modules/BlockModule.java similarity index 86% rename from core/src/io/anuke/mindustry/world/blocks/BlockModule.java rename to core/src/io/anuke/mindustry/world/modules/BlockModule.java index c30e571dd8..0b74bfb5e5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BlockModule.java +++ b/core/src/io/anuke/mindustry/world/modules/BlockModule.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.world.blocks; +package io.anuke.mindustry.world.modules; import java.io.DataInput; import java.io.DataOutput; diff --git a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java new file mode 100644 index 0000000000..39bf00dc5c --- /dev/null +++ b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java @@ -0,0 +1,51 @@ +package io.anuke.mindustry.world.modules; + +import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.world.consumers.Consume; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class ConsumeModule extends BlockModule{ + private Array consumers = new Array<>(); + private boolean valid; + + public void update(TileEntity entity){ + boolean prevValid = valid; + valid = true; + + for(Consume cons : consumers){ + if(prevValid && entity.tile.block().shouldConsume(entity.tile)){ + cons.update(entity.getTile().block(), entity); + } + + if(!cons.isOptional()){ + valid &= cons.valid(entity.getTile().block(), entity); + } + } + } + + public boolean valid(){ + return valid; + } + + public Array all() { + return consumers; + } + + @Override + public void write(DataOutput stream) throws IOException { + for(Consume cons : consumers){ + cons.write(stream); + } + } + + @Override + public void read(DataInput stream) throws IOException { + for(Consume cons : consumers){ + cons.read(stream); + } + } +} diff --git a/core/src/io/anuke/mindustry/world/modules/InventoryModule.java b/core/src/io/anuke/mindustry/world/modules/InventoryModule.java index cc937769cd..9fb13a9a3c 100644 --- a/core/src/io/anuke/mindustry/world/modules/InventoryModule.java +++ b/core/src/io/anuke/mindustry/world/modules/InventoryModule.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.world.modules; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.world.blocks.BlockModule; import java.io.DataInput; import java.io.DataOutput; diff --git a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java index 57808eee6d..564bed0512 100644 --- a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java +++ b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.world.modules; import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.blocks.BlockModule; import java.io.DataInput; import java.io.DataOutput; diff --git a/core/src/io/anuke/mindustry/world/modules/PowerModule.java b/core/src/io/anuke/mindustry/world/modules/PowerModule.java index f46f9ca817..fe35aa0d90 100644 --- a/core/src/io/anuke/mindustry/world/modules/PowerModule.java +++ b/core/src/io/anuke/mindustry/world/modules/PowerModule.java @@ -1,7 +1,5 @@ package io.anuke.mindustry.world.modules; -import io.anuke.mindustry.world.blocks.BlockModule; - import java.io.DataInput; import java.io.DataOutput; import java.io.IOException;