From 63a0fde1211c27e31b925d8af220d19d5b11474c Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 8 Jul 2018 16:38:29 -0400 Subject: [PATCH] Offload optimizations / Compile errors fixed / Massive refactor --- .../content/blocks/CraftingBlocks.java | 103 +++++++++--------- .../content/blocks/LiquidBlocks.java | 4 +- .../mindustry/content/blocks/PowerBlocks.java | 3 +- .../content/blocks/ProductionBlocks.java | 24 ++-- .../mindustry/content/blocks/UnitBlocks.java | 11 +- .../anuke/mindustry/entities/TileEntity.java | 53 ++++++++- .../io/anuke/mindustry/world/BaseBlock.java | 97 +++++++++-------- core/src/io/anuke/mindustry/world/Block.java | 4 +- core/src/io/anuke/mindustry/world/Edges.java | 8 ++ core/src/io/anuke/mindustry/world/Tile.java | 14 ++- .../blocks/defense/turrets/CooledTurret.java | 10 +- .../world/blocks/distribution/ItemBridge.java | 5 +- .../blocks/distribution/LiquidBridge.java | 6 +- .../distribution/LiquidExtendingBridge.java | 5 +- .../blocks/distribution/LiquidJunction.java | 3 +- .../world/blocks/distribution/WarpGate.java | 26 ++--- .../world/blocks/power/FusionReactor.java | 28 ++--- .../world/blocks/power/ItemGenerator.java | 22 ++-- .../blocks/power/ItemLiquidGenerator.java | 33 ++---- .../world/blocks/power/LiquidGenerator.java | 24 ++-- .../world/blocks/power/NuclearReactor.java | 43 ++++---- .../world/blocks/power/TurbineGenerator.java | 51 +-------- .../world/blocks/production/Compressor.java | 43 +++----- .../world/blocks/production/Cultivator.java | 16 ++- .../world/blocks/production/Drill.java | 4 +- .../world/blocks/production/Fracker.java | 48 ++------ .../blocks/production/GenericCrafter.java | 47 ++------ .../world/blocks/production/Incinerator.java | 17 +-- .../world/blocks/production/LiquidMixer.java | 3 +- .../world/blocks/production/PowerCrafter.java | 24 +--- .../world/blocks/production/PowerSmelter.java | 27 +---- .../world/blocks/production/Smelter.java | 34 +++--- .../world/blocks/units/Projector.java | 6 +- .../world/blocks/units/UnitFactory.java | 19 ++-- .../mindustry/world/consumers/Consume.java | 21 ++-- .../world/consumers/ConsumeItem.java | 13 ++- .../world/consumers/ConsumeItemFilter.java | 38 +++++++ .../world/consumers/ConsumeItems.java | 37 +++++++ .../world/consumers/ConsumeLiquid.java | 3 +- .../world/consumers/ConsumeLiquidFilter.java | 41 +++++++ .../mindustry/world/consumers/Consumers.java | 88 ++++++++++----- .../anuke/mindustry/world/consumers/Uses.java | 7 -- .../anuke/mindustry/world/meta/BlockStat.java | 1 - .../mindustry/world/meta/BlockStats.java | 12 +- .../world/modules/ConsumeModule.java | 18 +-- .../mindustry/world/modules/LiquidModule.java | 4 + 46 files changed, 583 insertions(+), 565 deletions(-) create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java create mode 100644 core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java delete mode 100644 core/src/io/anuke/mindustry/world/consumers/Uses.java diff --git a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java index e0f8e9e4bd..2c76f2638b 100644 --- a/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/CraftingBlocks.java @@ -13,52 +13,51 @@ import io.anuke.mindustry.world.blocks.production.*; public class CraftingBlocks extends BlockList implements ContentList { public static Block smelter, arcsmelter, siliconsmelter, plastaniumCompressor, phaseWeaver, alloysmelter, alloyfuser, pyratiteMixer, blastMixer, - cryofluidmixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, oilRefinery, solidifier, incinerator; + cryofluidmixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, solidifier, incinerator; @Override public void load() { smelter = new Smelter("smelter") {{ health = 70; - inputs = new ItemStack[]{new ItemStack(Items.tungsten, 3)}; - fuel = Items.coal; result = Items.carbide; craftTime = 45f; burnDuration = 35f; useFlux = true; + + consumes.items(new ItemStack[]{new ItemStack(Items.tungsten, 3)}); + consumes.item(Items.coal); }}; arcsmelter = new PowerSmelter("arc-smelter") {{ health = 90; craftEffect = BlockFx.smeltsmoke; - inputs = new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.tungsten, 2)}; result = Items.carbide; - powerUse = 0.1f; craftTime = 30f; size = 2; useFlux = true; fluxNeeded = 2; + + consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.tungsten, 2)}); + consumes.power(0.1f); }}; siliconsmelter = new PowerSmelter("silicon-smelter") {{ health = 90; craftEffect = BlockFx.smeltsmoke; - inputs = new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)}; result = Items.silicon; - powerUse = 0.05f; craftTime = 40f; size = 2; hasLiquids = false; flameColor = Color.valueOf("ffef99"); + + consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)}); + consumes.power(0.05f); }}; plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor") {{ - inputLiquid = Liquids.oil; - inputItem = new ItemStack(Items.titanium, 2); hasItems = true; - liquidUse = 0.3f; liquidCapacity = 60f; - powerUse = 0.5f; craftTime = 80f; output = Items.plastanium; itemCapacity = 30; @@ -67,66 +66,73 @@ public class CraftingBlocks extends BlockList implements ContentList { hasPower = hasLiquids = true; craftEffect = BlockFx.formsmoke; updateEffect = BlockFx.plasticburn; + + consumes.liquid(Liquids.oil, 0.3f); + consumes.power(0.4f); + consumes.item(Items.titanium, 2); }}; phaseWeaver = new PhaseWeaver("phase-weaver") {{ health = 90; craftEffect = BlockFx.smeltsmoke; - inputs = new ItemStack[]{new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10)}; result = Items.phasematter; - powerUse = 0.4f; craftTime = 120f; size = 2; + + consumes.items(new ItemStack[]{new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10)}); + consumes.power(0.5f); }}; alloysmelter = new PowerSmelter("alloy-smelter") {{ health = 90; craftEffect = BlockFx.smeltsmoke; - inputs = new ItemStack[]{new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.plastanium, 2)}; result = Items.surgealloy; - powerUse = 0.3f; craftTime = 50f; size = 2; useFlux = true; fluxNeeded = 4; + + consumes.power(0.3f); + consumes.items(new ItemStack[]{new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.plastanium, 2)}); }}; alloyfuser = new PowerSmelter("alloy-fuser") {{ health = 90; craftEffect = BlockFx.smeltsmoke; - inputs = new ItemStack[]{new ItemStack(Items.titanium, 3), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.plastanium, 2)}; result = Items.surgealloy; - powerUse = 0.4f; craftTime = 30f; size = 3; useFlux = true; fluxNeeded = 4; + + consumes.items(new ItemStack[]{new ItemStack(Items.titanium, 3), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.plastanium, 2)}); + consumes.power(0.4f); }}; cryofluidmixer = new LiquidMixer("cryofluidmixer") {{ health = 200; - inputLiquid = Liquids.water; outputLiquid = Liquids.cryofluid; - inputItem = Items.titanium; liquidPerItem = 50f; itemCapacity = 50; - powerUse = 0.1f; size = 2; + + consumes.power(0.1f); + consumes.item(Items.titanium); + consumes.liquid(Liquids.water, 0.2f); }}; blastMixer = new GenericCrafter("blast-mixer") {{ itemCapacity = 20; hasItems = true; hasPower = true; - inputLiquid = Liquids.oil; - liquidUse = 0.05f; - inputItem = new ItemStack(Items.pyratite, 1); output = Items.blastCompound; - powerUse = 0.04f; - size = 2; + + consumes.liquid(Liquids.oil, 0.05f); + consumes.item(Items.pyratite, 1); + consumes.power(0.04f); }}; pyratiteMixer = new PowerSmelter("pyratite-mixer") {{ @@ -134,27 +140,27 @@ public class CraftingBlocks extends BlockList implements ContentList { itemCapacity = 20; hasItems = true; hasPower = true; - inputs = new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)}; result = Items.pyratite; - powerUse = 0.02f; size = 2; + + consumes.power(0.02f); + consumes.items(new ItemStack[]{new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)}); }}; melter = new PowerCrafter("melter") {{ health = 200; outputLiquid = Liquids.lava; outputLiquidAmount = 0.05f; - input = new ItemStack(Items.stone, 1); itemCapacity = 50; craftTime = 10f; - powerUse = 0.1f; hasLiquids = hasPower = true; + + consumes.power(0.1f); + consumes.item(Items.stone, 2); }}; separator = new Separator("separator") {{ - liquid = Liquids.water; - item = Items.stone; results = new Item[]{ null, null, null, null, null, null, null, null, null, null, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, @@ -164,15 +170,15 @@ public class CraftingBlocks extends BlockList implements ContentList { Items.coal, Items.coal, Items.titanium }; - liquidUse = 0.2f; filterTime = 40f; itemCapacity = 40; health = 50; + + consumes.item(Items.stone); + consumes.liquid(Liquids.water, 0.2f); }}; centrifuge = new Separator("centrifuge") {{ - liquid = Liquids.water; - item = Items.stone; results = new Item[]{ null, null, null, null, null, null, null, null, null, null, null, null, null, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, Items.sand, @@ -184,9 +190,7 @@ public class CraftingBlocks extends BlockList implements ContentList { Items.thorium, }; - liquidUse = 0.3f; hasPower = true; - powerUse = 0.2f; filterTime = 15f; itemCapacity = 60; health = 50 * 4; @@ -195,53 +199,48 @@ public class CraftingBlocks extends BlockList implements ContentList { spinnerThickness = 1.5f; spinnerSpeed = 3f; size = 2; + + consumes.item(Items.stone); + consumes.power(0.2f); + consumes.liquid(Liquids.water, 0.35f); }}; biomatterCompressor = new Compressor("biomattercompressor") {{ - input = new ItemStack(Items.biomatter, 1); liquidCapacity = 60f; itemCapacity = 50; - powerUse = 0.06f; craftTime = 25f; outputLiquid = Liquids.oil; outputLiquidAmount = 0.1f; size = 2; health = 320; hasLiquids = true; + + consumes.item(Items.biomatter, 1); + consumes.power(0.06f); }}; pulverizer = new Pulverizer("pulverizer") {{ - inputItem = new ItemStack(Items.stone, 2); itemCapacity = 40; - powerUse = 0.2f; output = Items.sand; health = 80; craftEffect = BlockFx.pulverize; craftTime = 60f; updateEffect = BlockFx.pulverizeSmall; hasItems = hasPower = true; - }}; - oilRefinery = new GenericCrafter("oilrefinery") {{ - inputLiquid = Liquids.oil; - powerUse = 0.05f; - liquidUse = 0.1f; - liquidCapacity = 56f; - output = Items.coal; - health = 80; - craftEffect = BlockFx.purifyoil; - hasItems = hasLiquids = hasPower = true; + consumes.item(Items.stone, 2); + consumes.power(0.2f); }}; solidifier = new GenericCrafter("solidifer") {{ - inputLiquid = Liquids.lava; - liquidUse = 1f; liquidCapacity = 21f; craftTime = 14; output = Items.stone; health = 80; craftEffect = BlockFx.purifystone; hasLiquids = hasItems = true; + + consumes.liquid(Liquids.lava, 1f); }}; incinerator = new Incinerator("incinerator") {{ diff --git a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java index 6b47cb80d4..c6330d2e09 100644 --- a/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/LiquidBlocks.java @@ -20,7 +20,7 @@ public class LiquidBlocks extends BlockList implements ContentList{ rotaryPump = new Pump("rotary-pump") {{ shadow = "shadow-rounded-2"; pumpAmount = 0.25f; - powerUse = 0.015f; + consumes.power(0.015f); liquidCapacity = 30f; size = 2; tier = 1; @@ -28,7 +28,7 @@ public class LiquidBlocks extends BlockList implements ContentList{ thermalPump = new Pump("thermal-pump") {{ pumpAmount = 0.3f; - powerUse = 0.02f; + consumes.power(0.05f); liquidCapacity = 40f; size = 2; tier = 2; diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index e8533325f7..223a88efdb 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.content.blocks; +import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.world.Block; @@ -32,7 +33,7 @@ public class PowerBlocks extends BlockList implements ContentList { powerCapacity = 40f; itemDuration = 30f; powerPerLiquid = 0.7f; - auxLiquidUse = 0.05f; + consumes.liquid(Liquids.water, 0.05f); size = 2; }}; diff --git a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java index 6a7c9f8a18..8bbdba1f1e 100644 --- a/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/ProductionBlocks.java @@ -29,17 +29,17 @@ public class ProductionBlocks extends BlockList implements ContentList { laserdrill = new Drill("laser-drill") {{ drillTime = 180; size = 2; - powerUse = 0.2f; hasPower = true; tier = 4; updateEffect = BlockFx.pulverizeMedium; drillEffect = BlockFx.mineBig; + + consumes.power(0.2f); }}; blastdrill = new Drill("blast-drill") {{ drillTime = 120; size = 3; - powerUse = 0.5f; drawRim = true; hasPower = true; tier = 5; @@ -48,13 +48,14 @@ public class ProductionBlocks extends BlockList implements ContentList { drillEffect = BlockFx.mineHuge; rotateSpeed = 6f; warmupSpeed = 0.01f; + + consumes.power(0.5f); }}; plasmadrill = new Drill("plasma-drill") {{ heatColor = Color.valueOf("ff461b"); drillTime = 90; size = 4; - powerUse = 0.7f; hasLiquids = true; hasPower = true; tier = 5; @@ -64,38 +65,43 @@ public class ProductionBlocks extends BlockList implements ContentList { updateEffectChance = 0.04f; drillEffect = BlockFx.mineHuge; warmupSpeed = 0.005f; + + consumes.power(0.7f); }}; waterextractor = new SolidPump("water-extractor") {{ result = Liquids.water; - powerUse = 0.2f; pumpAmount = 0.1f; size = 2; liquidCapacity = 30f; rotateSpeed = 1.4f; + + consumes.power(0.2f); }}; oilextractor = new Fracker("oil-extractor") {{ result = Liquids.oil; - inputLiquid = Liquids.water; updateEffect = BlockFx.pulverize; liquidCapacity = 50f; updateEffectChance = 0.05f; - inputLiquidUse = 0.3f; - powerUse = 0.6f; pumpAmount = 0.06f; size = 3; liquidCapacity = 30f; + + consumes.item(Items.sand); + consumes.power(0.6f); + consumes.liquid(Liquids.water, 0.3f); }}; cultivator = new Cultivator("cultivator") {{ result = Items.biomatter; - inputLiquid = Liquids.water; - liquidUse = 0.2f; drillTime = 260; size = 2; hasLiquids = true; hasPower = true; + + consumes.power(0.08f); + consumes.liquid(Liquids.water, 0.2f); }}; } diff --git a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java index 397e70cba3..5abf5ceb51 100644 --- a/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/UnitBlocks.java @@ -16,19 +16,16 @@ public class UnitBlocks extends BlockList implements ContentList { type = UnitTypes.drone; produceTime = 800; size = 2; - requirements = new ItemStack[]{ - new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30) - }; + consumes.power(0.08f); + consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)}); }}; fabricatorFactory = new UnitFactory("fabricator-factory") {{ type = UnitTypes.fabricator; produceTime = 1600; size = 2; - powerUse = 0.2f; - requirements = new ItemStack[]{ - new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80) - }; + consumes.power(0.2f); + consumes.items(new ItemStack[]{new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)}); }}; resupplyPoint = new ResupplyPoint("resupply-point") {{ diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 46b66c389e..f7df09b001 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -1,6 +1,9 @@ package io.anuke.mindustry.entities; +import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ObjectSet; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.mindustry.content.fx.Fx; @@ -10,9 +13,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.Edges; 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.consumers.Consume; import io.anuke.mindustry.world.modules.ConsumeModule; import io.anuke.mindustry.world.modules.InventoryModule; import io.anuke.mindustry.world.modules.LiquidModule; @@ -36,6 +40,8 @@ public class TileEntity extends BaseEntity implements TargetTrait { /**This value is only used for debugging.*/ public static int sleepingEntities = 0; + private static final ObjectSet tmpTiles = new ObjectSet<>(); + public Tile tile; public Timer timer; public float health; @@ -45,6 +51,9 @@ public class TileEntity extends BaseEntity implements TargetTrait { public LiquidModule liquids; public ConsumeModule cons; + //list of (cached) tiles with entities in proximity, used for outputting to + //TODO implement + private Array proximity = new Array<>(8); private boolean dead = false; private boolean sleeping; private float sleepTime; @@ -133,8 +142,46 @@ public class TileEntity extends BaseEntity implements TargetTrait { return tile; } - public boolean consumed(Uses uses){ - return tile.block().consumes.get(uses).valid(tile.block(), this); + public boolean consumed(Class type){ + return tile.block().consumes.get(type).valid(tile.block(), this); + } + + public void removeFromProximity(){ + GridPoint2[] nearby = Edges.getEdges(tile.block().size); + for (GridPoint2 point : nearby) { + Tile other = world.tile(tile.x + point.x, tile.y + point.y); + //remove this tile from all nearby tile's proximities + if(other != null && other.entity != null){ + other.entity.proximity.removeValue(tile, true); + } + } + } + + public void updateProximity(){ + tmpTiles.clear(); + proximity.clear(); + + GridPoint2[] nearby = Edges.getEdges(tile.block().size); + for (GridPoint2 point : nearby) { + Tile other = world.tile(tile.x + point.x, tile.y + point.y); + if(other != null && other.entity != null){ + tmpTiles.add(other); + + //add this tile to proximity of nearby tiles + if(!other.entity.proximity.contains(tile, true)){ + other.entity.proximity.add(tile); + } + } + } + + //using a set to prevent duplicates + for(Tile tile : tmpTiles){ + proximity.add(tile); + } + } + + public Array proximity(){ + return proximity; } @Override diff --git a/core/src/io/anuke/mindustry/world/BaseBlock.java b/core/src/io/anuke/mindustry/world/BaseBlock.java index fec0728ac0..70634e45c6 100644 --- a/core/src/io/anuke/mindustry/world/BaseBlock.java +++ b/core/src/io/anuke/mindustry/world/BaseBlock.java @@ -1,13 +1,14 @@ package io.anuke.mindustry.world; -import com.badlogic.gdx.math.GridPoint2; +import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.fx.EnvironmentFx; +import io.anuke.mindustry.entities.TileEntity; 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.ConsumeLiquid; 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; @@ -71,9 +72,9 @@ public abstract class BaseBlock { } public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && + return hasLiquids && tile.entity.liquids.get(liquid) + amount < liquidCapacity && (!singleLiquid || (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f)) - && (!consumes.has(Uses.liquid) || consumes.liquid() == liquid); + && (!consumes.has(ConsumeLiquid.class) || consumes.liquid() == liquid); } public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){ @@ -94,25 +95,20 @@ public abstract class BaseBlock { } public void tryDumpLiquid(Tile tile, Liquid liquid){ - int size = tile.block().size; + Array proximity = tile.entity.proximity(); + int dump = tile.getDump(); - GridPoint2[] nearby = Edges.getEdges(size); - byte i = tile.getDump(); + for (int i = 0; i < proximity.size; i ++) { + incrementDump(tile, proximity.size); + Tile other = proximity.get((i + dump) % proximity.size); + Tile in = Edges.getFacingEdge(tile, other); - for (int j = 0; j < nearby.length; j ++) { - Tile other = tile.getNearby(nearby[i]); - Tile in = tile.getNearby(Edges.getInsideEdges(size)[i]); - - if(other != null) other = other.target(); - - if (other != null && other.block().hasLiquids) { + if (other.block().hasLiquids) { float ofract = other.entity.liquids.get(liquid) / other.block().liquidCapacity; float fract = tile.entity.liquids.get(liquid) / liquidCapacity; - if(ofract < fract) tryMoveLiquid(tile, in, other, (fract - ofract) * liquidCapacity / 2f, liquid); + if (ofract < fract) tryMoveLiquid(tile, in, other, (fract - ofract) * liquidCapacity / 2f, liquid); } - - i = (byte) ((i + 1) % nearby.length); } } @@ -173,16 +169,14 @@ public abstract class BaseBlock { * Tries to put this item into a nearby container, if there are no available * containers, it gets added to the block's inventory.*/ public void offloadNear(Tile tile, Item item){ - int size = tile.block().size; + Array proximity = tile.entity.proximity(); + int dump = tile.getDump(); - GridPoint2[] nearby = Edges.getEdges(size); - byte i = (byte)(tile.getDump() % nearby.length); - - for(int j = 0; j < nearby.length; j ++){ - tile.setDump((byte)((i + 1) % nearby.length)); - Tile other = tile.getNearby(nearby[i]); - Tile in = tile.getNearby(Edges.getInsideEdges(size)[i]); - if(other != null && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){ + for(int i = 0; i < proximity.size; i ++){ + incrementDump(tile, proximity.size); + Tile other = proximity.get((i + dump) % proximity.size); + Tile in = Edges.getFacingEdge(tile, other); + if(other.block().acceptItem(item, other, in) && canDump(tile, other, item)){ other.block().handleItem(item, other, in); return; } @@ -196,42 +190,53 @@ public abstract class BaseBlock { return tryDump(tile, null); } - /**Try dumping a specific item near the tile.*/ + /**Try dumping a specific item near the tile. + * @param todump Item to dump. Can be null to dump anything.*/ public boolean tryDump(Tile tile, Item todump){ - if(tile.entity == null || !hasItems || tile.entity.items.total() == 0) return false; + TileEntity entity = tile.entity; + if(entity == null || !hasItems || tile.entity.items.total() == 0 || (todump != null && !entity.items.has(todump))) return false; - int size = tile.block().size; + Array proximity = entity.proximity(); + int dump = tile.getDump(); - GridPoint2[] nearby = Edges.getEdges(size); - byte i = (byte)(tile.getDump() % nearby.length); + if(proximity.size == 0) return false; - for(int j = 0; j < nearby.length; j ++){ - Tile other; - Tile in; + for(int i = 0; i < proximity.size; i ++){ + Tile other = proximity.get((i + dump) % proximity.size); + Tile in = Edges.getFacingEdge(tile, other); - for(int ii = 0; ii < Item.all().size; ii ++){ - Item item = Item.getByID(ii); - other = tile.getNearby(nearby[i]); - in = tile.getNearby(Edges.getInsideEdges(size)[i]); + if(todump == null) { - if(todump != null && item != todump) continue; + for (int ii = 0; ii < Item.all().size; ii++) { + Item item = Item.getByID(ii); - if(tile.entity.items.has(item) && other != null && other.block().acceptItem(item, other, in) && canDump(tile, other, item)){ - other.block().handleItem(item, other, in); - tile.entity.items.remove(item, 1); - i = (byte)((i + 1) % nearby.length); - tile.setDump(i); + if (other.block().acceptItem(item, other, in) && canDump(tile, other, item)) { + other.block().handleItem(item, other, in); + tile.entity.items.remove(item, 1); + incrementDump(tile, proximity.size); + return true; + } + } + }else{ + + if (other.block().acceptItem(todump, other, in) && canDump(tile, other, todump)) { + other.block().handleItem(todump, other, in); + tile.entity.items.remove(todump, 1); + incrementDump(tile, proximity.size); return true; } } - i = (byte)((i + 1) % nearby.length); - tile.setDump(i); + incrementDump(tile, proximity.size); } return false; } + private void incrementDump(Tile tile, int prox){ + tile.setDump((byte)((tile.getDump() + 1) % prox)); + } + /**Used for dumping items.*/ public boolean canDump(Tile tile, Tile to, Item item){ return true; diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 93ecd50975..5e2b2631a5 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -101,7 +101,7 @@ public class Block extends BaseBlock implements Content{ /**list of displayed block status bars. Defaults to health bar.*/ public BlockBars bars = new BlockBars(); /**List of block stats.*/ - public BlockStats stats = new BlockStats(); + public BlockStats stats = new BlockStats(this); /**List of block flags. Used for AI indexing.*/ public EnumSet flags; /**Whether to automatically set the entity to 'sleeping' when created.*/ @@ -162,6 +162,8 @@ public class Block extends BaseBlock implements Content{ setStats(); setBars(); + + consumes.checkRequired(this); } @Override diff --git a/core/src/io/anuke/mindustry/world/Edges.java b/core/src/io/anuke/mindustry/world/Edges.java index 61575ba381..f8f0fe045b 100644 --- a/core/src/io/anuke/mindustry/world/Edges.java +++ b/core/src/io/anuke/mindustry/world/Edges.java @@ -7,6 +7,8 @@ import io.anuke.ucore.util.Mathf; import java.util.Arrays; +import static io.anuke.mindustry.Vars.world; + public class Edges { private static final int maxSize = 11; private static final int maxRadius = 12; @@ -49,6 +51,12 @@ public class Edges { } } + public static Tile getFacingEdge(Tile tile, Tile other){ + int size = tile.block().size; + return world.tile(tile.x + Mathf.clamp(other.x - tile.x, -(size-1) / 2, (size / 2)), + tile.y + Mathf.clamp(other.y - tile.y, -(size-1) / 2, (size / 2))); + } + public static Vector2[] getPixelPolygon(float radius){ if(radius < 1 || radius > maxRadius) throw new RuntimeException("Polygon size must be between 1 and " + maxRadius); return polygons[(int)(radius*2) - 1]; diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 0f0c27a8d9..99cd9d987b 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -161,6 +161,7 @@ public class Tile implements PosTrait, TargetTrait { public void setBlock(Block type, int rotation){ synchronized (tileSetLock) { + preChanged(); if(rotation < 0) rotation = (-rotation + 2); this.wall = type; this.link = 0; @@ -171,6 +172,7 @@ public class Tile implements PosTrait, TargetTrait { public void setBlock(Block type){ synchronized (tileSetLock) { + preChanged(); this.wall = type; this.link = 0; changed(); @@ -366,8 +368,16 @@ public class Tile implements PosTrait, TargetTrait { cost += 1; } } + + private void preChanged(){ + synchronized (tileSetLock) { + if (entity != null) { + entity.removeFromProximity(); + } + } + } - public void changed(){ + private void changed(){ synchronized (tileSetLock) { if (entity != null) { @@ -381,12 +391,12 @@ 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(); } + entity.updateProximity(); updateOcclusion(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java index 7ca7f09a9e..d7f0e8dd89 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java @@ -4,8 +4,7 @@ import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.entities.effect.Fire; 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.values.LiquidFilterValue; +import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -24,13 +23,8 @@ public class CooledTurret extends Turret { super(name); hasLiquids = true; liquidCapacity = 20f; - } - @Override - public void setStats() { - super.setStats(); - - stats.add(BlockStat.inputLiquidAux, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.2f)); + consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f, 0.01f)).update(false).optional(true); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index cfad7d944e..6f5b4b2e30 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -35,7 +35,6 @@ public class ItemBridge extends Block { protected int timerTransport = timers++; protected int range; - protected float powerUse = 0.05f; protected float transportTime = 2f; protected IntArray removals = new IntArray(); @@ -155,11 +154,9 @@ public class ItemBridge extends Block { tryDump(tile); entity.uptime = 0f; }else{ - float use = Math.min(powerCapacity, powerUse * Timers.delta()); - if(!hasPower || entity.power.amount >= use){ + if(entity.cons.valid()){ entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f); - if(hasPower) entity.power.amount -= use; }else{ entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java index 738ece51d8..a16c0b6b7f 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidBridge.java @@ -26,15 +26,13 @@ public class LiquidBridge extends ItemBridge { if(!linkValid(tile, other)){ tryDumpLiquid(tile, entity.liquids.current()); }else{ - float use = Math.min(powerCapacity, powerUse * Timers.delta()); - - if(entity.power.amount >= use){ + if(entity.cons.valid()){ entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f); - entity.power.amount -= use; }else{ entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f); } + if(entity.uptime >= 0.5f){ if(tryMoveLiquid(tile, other, false, entity.liquids.current()) > 0.1f){ diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java index cf0ce206d1..d8fc185adc 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidExtendingBridge.java @@ -26,11 +26,8 @@ public class LiquidExtendingBridge extends ExtendingItemBridge { if(!linkValid(tile, other)){ tryDumpLiquid(tile, entity.liquids.current()); }else{ - float use = Math.min(powerCapacity, powerUse * Timers.delta()); - - if(!hasPower || entity.power.amount >= use){ + if(entity.cons.valid()){ entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f); - if(hasPower) entity.power.amount -= use; }else{ entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java index 3d1a47f8c3..3f99bce32b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/LiquidJunction.java @@ -6,11 +6,12 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.LiquidBlock; import io.anuke.ucore.graphics.Draw; +//TODO fix public class LiquidJunction extends LiquidBlock{ public LiquidJunction(String name) { super(name); - hasLiquids = false; + hasLiquids = true; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java index 5d7b1488b6..4a1b8e849e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/WarpGate.java @@ -34,6 +34,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; +//TODO implement public class WarpGate extends PowerBlock{ public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.LIME, Color.PURPLE, Color.GOLD, Color.PINK, Color.LIGHT_GRAY}; @@ -52,8 +53,6 @@ public class WarpGate extends PowerBlock{ //time between teleports protected float teleportMax = 400f; protected float teleportLiquidUse = 0.3f; - protected float liquidUse = 0.1f; - protected float powerUse = 0.3f; protected Liquid inputLiquid = Liquids.cryofluid; protected Effect activateEffect = BlockFx.teleportActivate; protected Effect teleportEffect = BlockFx.teleport; @@ -162,10 +161,9 @@ public class WarpGate extends PowerBlock{ entity.power.amount = 0f; Effects.effect(activateEffect, resultColor, tile.drawx(), tile.drawy()); } - }else { + }else{ entity.activeScl = Mathf.lerpDelta(entity.activeScl, 1f, 0.015f); - - float powerUsed = Math.min(powerCapacity, powerUse * Timers.delta()); + /* if (entity.power.amount >= powerUsed) { entity.power.amount -= powerUsed; @@ -179,15 +177,13 @@ public class WarpGate extends PowerBlock{ catastrophicFailure(tile); } - float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta()); - if (entity.liquids.amount >= liquidUsed) { entity.liquids.amount -= liquidUsed; entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 0f, 0.1f); }else{ entity.liquids.amount = 0f; entity.liquidLackScl = Mathf.lerpDelta(entity.liquidLackScl, 1f, 0.1f); - } + }*/ if(entity.liquidLackScl >= 0.999f){ catastrophicFailure(tile); @@ -197,19 +193,19 @@ public class WarpGate extends PowerBlock{ if (entity.teleporting) { entity.speedScl = Mathf.lerpDelta(entity.speedScl, 2f, 0.01f); - liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta()); + //liquidUsed = Math.min(liquidCapacity, teleportLiquidUse * Timers.delta()); - if (entity.liquids.amount >= liquidUsed) { - entity.liquids.amount -= liquidUsed; - } else { + //if (entity.liquids.amount >= liquidUsed) { + // entity.liquids.amount -= liquidUsed; + //} else { catastrophicFailure(tile); - } + //} } else { entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.04f); } entity.time += Timers.delta() * entity.speedScl; - +/* if (!entity.teleporting && entity.items.total() >= itemCapacity && entity.power.amount >= powerCapacity - 0.01f - powerUse && entity.timer.get(timerTeleport, teleportMax)) { Array testLinks = findLinks(tile); @@ -238,7 +234,7 @@ public class WarpGate extends PowerBlock{ entity.power.amount = 0f; entity.teleporting = false; }); - } + }*/ } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java index a5da34207e..b4c36a3f5c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java @@ -2,11 +2,11 @@ package io.anuke.mindustry.world.blocks.power; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.type.Liquid; 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.ucore.core.Graphics; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -14,10 +14,7 @@ import io.anuke.ucore.util.Mathf; public class FusionReactor extends PowerGenerator { protected int plasmas = 4; - protected float powerUsage = 0.5f; - protected float maxPowerProduced = 1.5f; - protected float liquidUsage = 1f; - protected Liquid inputLiquid = Liquids.water; + protected float maxPowerProduced = 2f; protected float warmupSpeed = 0.001f; protected Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b"); @@ -32,16 +29,18 @@ public class FusionReactor extends PowerGenerator { hasItems = true; } + @Override + public void setStats() { + super.setStats(); + + stats.add(BlockStat.maxPowerGeneration, maxPowerProduced * 60f, StatUnit.powerSecond); + } + @Override public void update(Tile tile){ FusionReactorEntity entity = tile.entity(); - float powerUse = Math.min(powerCapacity, powerUsage * Timers.delta()); - float liquidUse = Math.min(liquidCapacity, liquidUsage * Timers.delta()); - - if(entity.power.amount >= powerUse && entity.liquids.amount >= liquidUse){ - entity.power.amount -= powerUse; - entity.liquids.amount -= liquidUse; + if(entity.cons.valid()){ entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, warmupSpeed); }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.01f); @@ -113,11 +112,6 @@ public class FusionReactor extends PowerGenerator { return new FusionReactorEntity(); } - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid; - } - @Override public void onDestroyed(Tile tile) { super.onDestroyed(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java index 265ae49baf..e1973d64d2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemGenerator.java @@ -7,10 +7,10 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumeItemFilter; import io.anuke.mindustry.world.meta.BlockBar; 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.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -36,6 +36,8 @@ public abstract class ItemGenerator extends PowerGenerator { super(name); itemCapacity = 20; hasItems = true; + + consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false); } @Override @@ -48,7 +50,6 @@ public abstract class ItemGenerator extends PowerGenerator { public void setStats() { super.setStats(); - stats.add(BlockStat.inputItems, new ItemFilterValue(item -> getItemEfficiency(item) >= minItemEfficiency)); stats.add(BlockStat.maxPowerGeneration, powerOutput * 60f, StatUnit.powerSecond); } @@ -96,17 +97,12 @@ public abstract class ItemGenerator extends PowerGenerator { Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize/2f), tile.worldy() + Mathf.range(size * tilesize/2f)); } } - - if(entity.generateTime <= 0f && entity.items.total() > 0){ - Effects.effect(generateEffect, tile.worldx() + Mathf.range(size * tilesize/2f), tile.worldy() + Mathf.range(size * tilesize/2f)); - for(int i = 0; i < entity.items.items.length; i ++){ - if(entity.items.items[i] > 0){ - entity.items.items[i] --; - entity.efficiency = getItemEfficiency(Item.getByID(i)); - entity.explosiveness = Item.getByID(i).explosiveness; - break; - } - } + + if (entity.generateTime <= 0f && entity.items.total() > 0) { + Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); + Item item = entity.items.take(); + entity.efficiency = getItemEfficiency(item); + entity.explosiveness = item.explosiveness; entity.generateTime = 1f; } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index 6adc8bf50f..5b9d3f32d1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -4,8 +4,7 @@ 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.meta.BlockStat; -import io.anuke.mindustry.world.meta.values.LiquidFilterValue; +import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -23,13 +22,8 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { super(name); hasLiquids = true; liquidCapacity = 10f; - } - @Override - public void setStats() { - super.setStats(); - - stats.add(BlockStat.inputLiquid, new LiquidFilterValue(item -> getLiquidEfficiency(item) >= minLiquidEfficiency)); + consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, 0.001f)).update(false); } @Override @@ -37,12 +31,12 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { ItemGeneratorEntity entity = tile.entity(); //liquid takes priority over solids - if(entity.liquids.amount >= 0.001f){ - float powerPerLiquid = getLiquidEfficiency(entity.liquids.liquid)*this.powerPerLiquid; - float used = Math.min(entity.liquids.amount, maxLiquidGenerate * Timers.delta()); + if(entity.liquids.currentAmount() >= 0.001f){ + float powerPerLiquid = getLiquidEfficiency(entity.liquids.current())*this.powerPerLiquid; + float used = Math.min(entity.liquids.currentAmount(), maxLiquidGenerate * Timers.delta()); used = Math.min(used, (powerCapacity - entity.power.amount)/powerPerLiquid); - entity.liquids.amount -= used; + entity.liquids.remove(entity.liquids.current(), used); entity.power.amount += used * powerPerLiquid; if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){ @@ -66,14 +60,9 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { if (entity.generateTime <= 0f && entity.items.total() > 0) { Effects.effect(generateEffect, tile.worldx() + Mathf.range(3f), tile.worldy() + Mathf.range(3f)); - for (int i = 0; i < entity.items.items.length; i++) { - if (entity.items.items[i] > 0) { - entity.items.items[i]--; - entity.efficiency = getItemEfficiency(Item.getByID(i)); - entity.explosiveness = Item.getByID(i).explosiveness; - break; - } - } + Item item = entity.items.take(); + entity.efficiency = getItemEfficiency(item); + entity.explosiveness = item.explosiveness; entity.generateTime = 1f; } } @@ -87,8 +76,8 @@ public abstract class ItemLiquidGenerator extends ItemGenerator { TileEntity entity = tile.entity(); - Draw.color(entity.liquids.liquid.color); - Draw.alpha(entity.liquids.amount / liquidCapacity); + Draw.color(entity.liquids.current().color); + Draw.alpha(entity.liquids.currentAmount() / liquidCapacity); drawLiquidCenter(tile); Draw.color(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java index ff276b057e..ddb092e181 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/LiquidGenerator.java @@ -5,8 +5,7 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.power.ItemGenerator.ItemGeneratorEntity; -import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.values.LiquidFilterValue; +import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -24,13 +23,8 @@ public abstract class LiquidGenerator extends PowerGenerator { super(name); liquidCapacity = 30f; hasLiquids = true; - } - @Override - public void setStats() { - super.setStats(); - - stats.add(BlockStat.inputLiquid, new LiquidFilterValue(item -> getEfficiency(item) >= minEfficiency)); + consumes.add(new ConsumeLiquidFilter(liquid -> getEfficiency(liquid) >= minEfficiency, 0.001f)).update(false); } @Override @@ -39,8 +33,8 @@ public abstract class LiquidGenerator extends PowerGenerator { TileEntity entity = tile.entity(); - Draw.color(entity.liquids.liquid.color); - Draw.alpha(entity.liquids.amount / liquidCapacity); + Draw.color(entity.liquids.current().color); + Draw.alpha(entity.liquids.total() / liquidCapacity); drawLiquidCenter(tile); Draw.color(); } @@ -53,12 +47,12 @@ public abstract class LiquidGenerator extends PowerGenerator { public void update(Tile tile){ TileEntity entity = tile.entity(); - if(entity.liquids.amount > 0){ - float powerPerLiquid = getEfficiency(entity.liquids.liquid)*this.powerPerLiquid; - float used = Math.min(entity.liquids.amount, maxLiquidGenerate * Timers.delta()); + if(entity.liquids.get(entity.liquids.current()) >= 0.001f){ + float powerPerLiquid = getEfficiency(entity.liquids.current())*this.powerPerLiquid; + float used = Math.min(entity.liquids.currentAmount(), maxLiquidGenerate * Timers.delta()); used = Math.min(used, (powerCapacity - entity.power.amount)/powerPerLiquid); - - entity.liquids.amount -= used; + + entity.liquids.remove(entity.liquids.current(), used); entity.power.amount += used * powerPerLiquid; if(used > 0.001f && Mathf.chance(0.05 * Timers.delta())){ diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index 1184da288b..c5acb2c935 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -6,7 +6,6 @@ import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.content.fx.ExplosionFx; import io.anuke.mindustry.entities.Damage; import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Tile; @@ -26,12 +25,12 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.tilesize; +//TODO refactor to use consumers public class NuclearReactor extends PowerGenerator { protected final int timerFuel = timers++; protected final Translator tr = new Translator(); - protected Item generateItem; protected Color coolColor = new Color(1, 1, 1, 0f); protected Color hotColor = Color.valueOf("ff9575a3"); protected int fuelUseTime = 120; //time to consume 1 fuel @@ -39,32 +38,32 @@ public class NuclearReactor extends PowerGenerator { protected float heating = 0.009f; //heating per frame protected float coolantPower = 0.015f; //how much heat decreases per coolant unit protected float smokeThreshold = 0.3f; //threshold at which block starts smoking - protected float maxLiquidUse = 1f; //max liquid use per frame + protected float maxLiquidUse = 4f; //max liquid use per frame protected int explosionRadius = 19; protected int explosionDamage = 135; protected float flashThreshold = 0.46f; //heat threshold at which the lights start flashing public NuclearReactor(String name) { super(name); - generateItem = Items.thorium; itemCapacity = 30; liquidCapacity = 50; powerCapacity = 80f; hasItems = true; hasLiquids = true; + + consumes.item(Items.thorium); } @Override public void setBars(){ super.setBars(); - bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.get(generateItem) / itemCapacity)); + bars.replace(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.get(consumes.item()) / itemCapacity)); bars.add(new BlockBar(BarType.heat, true, tile -> tile.entity().heat)); } @Override public void setStats(){ super.setStats(); - stats.add(BlockStat.inputItem, generateItem); stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f)); stats.add(BlockStat.maxPowerGeneration, powerMultiplier*60f, StatUnit.powerSecond); } @@ -73,7 +72,7 @@ public class NuclearReactor extends PowerGenerator { public void update(Tile tile){ NuclearReactorEntity entity = tile.entity(); - int fuel = entity.items.get(generateItem); + int fuel = entity.items.get(consumes.item()); float fullness = (float)fuel / itemCapacity; if(fuel > 0){ @@ -81,22 +80,23 @@ public class NuclearReactor extends PowerGenerator { entity.power.amount += powerMultiplier * fullness * Timers.delta(); entity.power.amount = Mathf.clamp(entity.power.amount, 0f, powerCapacity); if(entity.timer.get(timerFuel, fuelUseTime)){ - entity.items.remove(generateItem, 1); + entity.items.remove(consumes.item(), 1); } } - if(entity.liquids.amount > 0){ + if(entity.liquids.total() > 0){ + Liquid liquid = entity.liquids.current(); - if(entity.liquids.liquid.temperature <= 0.5f){ //is coolant - float pow = coolantPower * entity.liquids.liquid.heatCapacity; //heat depleted per unit of liquid - float maxUsed = Math.min(Math.min(entity.liquids.amount, entity.heat / pow), maxLiquidUse * Timers.delta()); //max that can be cooled in terms of liquid + if(liquid.temperature <= 0.5f){ //is coolant + float pow = coolantPower * liquid.heatCapacity; //heat depleted per unit of liquid + float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), entity.heat / pow), maxLiquidUse * Timers.delta()); //max that can be cooled in terms of liquid entity.heat -= maxUsed * pow; - entity.liquids.amount -= maxUsed; + entity.liquids.remove(liquid, maxUsed); }else{ //is heater - float heat = coolantPower * entity.liquids.liquid.heatCapacity / 4f; //heat created per unit of liquid - float maxUsed = Math.min(Math.min(entity.liquids.amount, (1f - entity.heat) / heat), maxLiquidUse * Timers.delta()); //max liquid used + float heat = coolantPower * liquid.heatCapacity / 4f; //heat created per unit of liquid + float maxUsed = Math.min(Math.min(entity.liquids.get(liquid), (1f - entity.heat) / heat), maxLiquidUse * Timers.delta()); //max liquid used entity.heat += maxUsed * heat; - entity.liquids.amount -= maxUsed; + entity.liquids.remove(liquid, maxUsed); } } @@ -123,7 +123,7 @@ public class NuclearReactor extends PowerGenerator { NuclearReactorEntity entity = tile.entity(); - int fuel = entity.items.get(generateItem); + int fuel = entity.items.get(consumes.item()); if(fuel < 5 && entity.heat < 0.5f) return; @@ -153,15 +153,10 @@ public class NuclearReactor extends PowerGenerator { } } - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - return item == generateItem && tile.entity.items.get(generateItem) < itemCapacity; - } - @Override public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return tile.entity.liquids.amount + amount < liquidCapacity - && (tile.entity.liquids.liquid == liquid || tile.entity.liquids.amount <= 0.001f); + return tile.entity.liquids.get(liquid) + amount < liquidCapacity && liquid.temperature <= 0.5f && + (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java index d29d5bb67e..8efd90fbc9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/TurbineGenerator.java @@ -1,57 +1,10 @@ package io.anuke.mindustry.world.blocks.power; -import io.anuke.mindustry.content.Liquids; -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.ucore.core.Timers; - +//TODO public class TurbineGenerator extends BurnerGenerator { - protected float auxLiquidUse = 0.1f; - protected Liquid auxLiquid = Liquids.water; - protected float auxLiquidCapacity = 10; public TurbineGenerator(String name) { super(name); - } - - @Override - public void setStats() { - super.setStats(); - - stats.add(BlockStat.inputLiquidAux, auxLiquid); - } - - @Override - public void update(Tile tile) { - TurbineEntity entity = tile.entity(); - float used = Math.min(auxLiquidUse * Timers.delta(), auxLiquidCapacity); - - if(entity.aux >= used){ - super.update(tile); - entity.aux -= used; - } - } - - @Override - public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - TurbineEntity entity = tile.entity(); - if(liquid == auxLiquid){ - float accepted = Math.min(auxLiquidCapacity - entity.aux, amount); - entity.aux += accepted; - return accepted; - }else { - return 0; - } - } - - @Override - public TileEntity getEntity() { - return new TurbineEntity(); - } - - public class TurbineEntity extends ItemGeneratorEntity{ - public float aux; + singleLiquid = false; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java index ffe9544a59..4fde97444e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Compressor.java @@ -4,11 +4,12 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureRegion; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterEntity; -import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; public class Compressor extends PowerCrafter { + protected TextureRegion liquidRegion, topRegion; + protected TextureRegion[] frameRegions; public Compressor(String name) { super(name); @@ -16,32 +17,16 @@ public class Compressor extends PowerCrafter { } @Override - public void update(Tile tile) { - GenericCrafterEntity entity = tile.entity(); + public void load() { + super.load(); - float powerUsed = Math.min(Timers.delta() * powerUse, tile.entity.power.amount); - float liquidAdded = Math.min(outputLiquidAmount * Timers.delta(), liquidCapacity - entity.liquids.amount); - int itemsUsed = Mathf.ceil(1 + input.amount * entity.progress); - - if(entity.power.amount > powerUsed && entity.items.has(input.item, itemsUsed) && liquidAdded > 0.001f){ - entity.progress += 1f/craftTime; - entity.totalProgress += Timers.delta(); - handleLiquid(tile, tile, outputLiquid, liquidAdded); - } - - if(entity.progress >= 1f){ - entity.items.remove(input); - if(outputItem != null) offloadNear(tile, outputItem); - entity.progress = 0f; - } - - if(outputItem != null && entity.timer.get(timerDump, 5)){ - tryDump(tile, outputItem); - } - - if(outputLiquid != null){ - tryDumpLiquid(tile); + frameRegions = new TextureRegion[3]; + for (int i = 0; i < 3; i++) { + frameRegions[i] = Draw.region(name + "-frame" + i); } + + liquidRegion = Draw.region(name + "-liquid"); + topRegion = Draw.region(name + "-top"); } @Override @@ -49,11 +34,11 @@ public class Compressor extends PowerCrafter { GenericCrafterEntity entity = tile.entity(); Draw.rect(region, tile.drawx(), tile.drawy()); - Draw.rect(name + "-frame" + (int) Mathf.absin(entity.totalProgress, 5f, 2.999f), tile.drawx(), tile.drawy()); - Draw.color(Color.CLEAR, tile.entity.liquids.liquid.color, tile.entity.liquids.amount / liquidCapacity); - Draw.rect(name + "-liquid", tile.drawx(), tile.drawy()); + Draw.rect(frameRegions[(int) Mathf.absin(entity.totalProgress, 5f, 2.999f)], tile.drawx(), tile.drawy()); + Draw.color(Color.CLEAR, tile.entity.liquids.current().color, tile.entity.liquids.total() / liquidCapacity); + Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(); - Draw.rect(name + "-top", tile.drawx(), tile.drawy()); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java index 2af65d16a4..c0f473e4cd 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -23,6 +23,7 @@ public class Cultivator extends Drill { protected Color plantColor = Color.valueOf("648b55"); protected Color plantColorLight = Color.valueOf("73a75f"); protected Color bottomColor = Color.valueOf("474747"); + protected TextureRegion middleRegion, topRegion; protected Item result; @@ -44,13 +45,20 @@ public class Cultivator extends Drill { }); } + @Override + public void load() { + super.load(); + + middleRegion = Draw.region(name + "-middle"); + topRegion = Draw.region(name + "-top"); + } + @Override public void update(Tile tile) { super.update(tile); CultivatorEntity entity = tile.entity(); - entity.warmup = Mathf.lerpDelta(entity.warmup, - tile.entity.liquids.amount > liquidUse ? 1f : 0f, 0.015f); + entity.warmup = Mathf.lerpDelta(entity.warmup, entity.cons.valid() ? 1f : 0f, 0.015f); } @Override @@ -61,7 +69,7 @@ public class Cultivator extends Drill { Draw.color(plantColor); Draw.alpha(entity.warmup); - Draw.rect(name + "-middle", tile.drawx(), tile.drawy()); + Draw.rect(middleRegion, tile.drawx(), tile.drawy()); Draw.color(bottomColor, plantColorLight, entity.warmup); @@ -78,7 +86,7 @@ public class Cultivator extends Drill { } Draw.color(); - Draw.rect(name + "-top", tile.drawx(), tile.drawy()); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); } @Override 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 0c315c51bd..28aaffbefb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -10,7 +10,7 @@ import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.consumers.Uses; +import io.anuke.mindustry.world.consumers.ConsumeLiquid; import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; @@ -167,7 +167,7 @@ public class Drill extends Block{ float speed = 1f; - if(entity.consumed(Uses.liquid) && !liquidRequired){ + if(entity.consumed(ConsumeLiquid.class) && !liquidRequired){ speed = liquidBoostIntensity; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java index 7b7c68c50e..5a2700bcb1 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java @@ -1,21 +1,14 @@ package io.anuke.mindustry.world.blocks.production; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import io.anuke.mindustry.content.Items; 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.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; +import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; public class Fracker extends SolidPump { - protected Liquid inputLiquid; - protected float inputLiquidUse; - protected float inputCapacity = 20f; - protected Item inputItem = Items.sand; protected float itemUseTime = 100f; protected TextureRegion liquidRegion; @@ -26,6 +19,9 @@ public class Fracker extends SolidPump { super(name); hasItems = true; itemCapacity = 20; + singleLiquid = false; + + consumes.require(ConsumeItem.class); } @Override @@ -40,10 +36,6 @@ public class Fracker extends SolidPump { @Override public void setStats() { super.setStats(); - - stats.add(BlockStat.inputItem, inputItem); - stats.add(BlockStat.inputLiquid, inputLiquid); - stats.add(BlockStat.liquidUse, 60f *inputLiquidUse, StatUnit.liquidSecond); } @Override @@ -52,8 +44,8 @@ public class Fracker extends SolidPump { Draw.rect(region, tile.drawx(), tile.drawy()); - Draw.color(tile.entity.liquids.liquid.color); - Draw.alpha(tile.entity.liquids.amount/liquidCapacity); + Draw.color(result.color); + Draw.alpha(tile.entity.liquids.get(result)/liquidCapacity); Draw.rect(liquidRegion, tile.drawx(), tile.drawy()); Draw.color(); @@ -69,35 +61,18 @@ public class Fracker extends SolidPump { @Override public void update(Tile tile) { FrackerEntity entity = tile.entity(); + Item item = consumes.item(); - while(entity.accumulator > itemUseTime && entity.items.has(inputItem, 1)){ - entity.items.remove(inputItem, 1); + while(entity.accumulator > itemUseTime && entity.items.has(item, 1)){ + entity.items.remove(item, 1); entity.accumulator -= itemUseTime; } - if(entity.input >= Math.min(inputLiquidUse * Timers.delta(), inputCapacity) && entity.accumulator < itemUseTime){ + if(entity.cons.valid() && entity.accumulator < itemUseTime){ super.update(tile); - entity.input -= inputLiquidUse * Timers.delta(); entity.accumulator += Timers.delta(); }else{ - tryDumpLiquid(tile); - } - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { - return item == inputItem && tile.entity.items.total() < itemCapacity; - } - - @Override - public float handleAuxLiquid(Tile tile, Tile source, Liquid liquid, float amount) { - if(liquid != inputLiquid){ - return 0f; - }else{ - FrackerEntity entity = tile.entity(); - float accepted = Math.min(inputCapacity - entity.input, amount); - entity.input += accepted; - return accepted; + tryDumpLiquid(tile, result); } } @@ -107,7 +82,6 @@ public class Fracker extends SolidPump { } public static class FrackerEntity extends SolidPumpEntity{ - public float input; public float accumulator; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java index 7abfd25839..8f7f773915 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java @@ -5,11 +5,10 @@ import io.anuke.mindustry.content.fx.BlockFx; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; @@ -27,14 +26,14 @@ public class GenericCrafter extends Block{ protected final int timerDump = timers++; /**Can be null. If you use this, make sure to set hasItems to true!*/ - protected ItemStack inputItem; + //protected ItemStack inputItem; /**Can be null. If you use this, make sure to set hasLiquids to true!*/ - protected Liquid inputLiquid; + //protected Liquid inputLiquid; /**Required.*/ protected Item output; protected float craftTime = 80; - protected float powerUse; - protected float liquidUse; + //protected float powerUse; + //protected float liquidUse; protected Effect craftEffect = BlockFx.purify; protected Effect updateEffect = Fx.none; protected float updateEffectChance = 0.04f; @@ -50,8 +49,8 @@ public class GenericCrafter extends Block{ public void setBars(){ super.setBars(); - if(inputItem != null) bars.replace(new BlockBar(BarType.inventory, true, - tile -> (float)tile.entity.items.get(inputItem.item) / itemCapacity)); + if(consumes.has(ConsumeItem.class)) bars.replace(new BlockBar(BarType.inventory, true, + tile -> (float)tile.entity.items.get(consumes.item()) / itemCapacity)); } @Override @@ -59,11 +58,6 @@ public class GenericCrafter extends Block{ super.setStats(); stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); stats.add(BlockStat.outputItem, output); - - if(inputLiquid != null) stats.add(BlockStat.inputLiquid, inputLiquid); - if(inputLiquid != null) stats.add(BlockStat.liquidUse, (liquidUse * craftTime), StatUnit.liquidSecond); - if(inputItem != null) stats.add(BlockStat.inputItem, inputItem); - if(hasPower) stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); } @Override @@ -72,8 +66,8 @@ public class GenericCrafter extends Block{ if(!hasLiquids) return; - 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("blank", tile.drawx(), tile.drawy(), 2, 2); Draw.color(); } @@ -87,19 +81,11 @@ public class GenericCrafter extends Block{ public void update(Tile tile){ GenericCrafterEntity entity = tile.entity(); - float powerUsed = Math.min(powerCapacity, powerUse * Timers.delta()); - float liquidUsed = Math.min(liquidCapacity, liquidUse * Timers.delta()); - int itemsUsed = (inputItem == null ? 0 : (int)(1 + inputItem.amount * entity.progress)); - - if((!hasLiquids || entity.liquids.amount >= liquidUsed) && - (!hasPower || entity.power.amount >= powerUsed) && - (inputItem == null || entity.items.has(inputItem.item, itemsUsed))){ + if(entity.cons.valid()){ entity.progress += 1f / craftTime * Timers.delta(); entity.totalProgress += Timers.delta(); entity.warmup = Mathf.lerp(entity.warmup, 1f, 0.02f); - if(hasPower) entity.power.amount -= powerUsed; - if(hasLiquids) entity.liquids.amount -= liquidUsed; if(Mathf.chance(Timers.delta() * updateEffectChance)) Effects.effect(updateEffect, entity.x + Mathf.range(size*4f), entity.y + Mathf.range(size*4)); @@ -109,7 +95,7 @@ public class GenericCrafter extends Block{ if(entity.progress >= 1f){ - if(inputItem != null) tile.entity.items.remove(inputItem); + if(consumes.has(ConsumeItem.class)) tile.entity.items.remove(consumes.item(), consumes.itemAmount()); offloadNear(tile, output); Effects.effect(craftEffect, tile.drawx(), tile.drawy()); entity.progress = 0f; @@ -119,17 +105,6 @@ public class GenericCrafter extends Block{ tryDump(tile, output); } } - - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return super.acceptLiquid(tile, source, liquid, amount) && liquid == inputLiquid; - } - - @Override - public boolean acceptItem(Item item, Tile tile, Tile source){ - TileEntity entity = tile.entity(); - return inputItem != null && item == inputItem.item && entity.items.get(inputItem.item) < itemCapacity; - } @Override public TileEntity getEntity() { 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 285288b9c5..00b8997d07 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java @@ -8,8 +8,6 @@ import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Block; 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; @@ -18,7 +16,6 @@ import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Mathf; public class Incinerator extends Block { - protected float powerUse = 0.07f; protected Effect effect = BlockFx.fuelburn; protected Color flameColor = Color.valueOf("ffad9d"); @@ -28,6 +25,8 @@ public class Incinerator extends Block { hasLiquids = true; update = true; solid = true; + + consumes.power(0.05f); } @Override @@ -36,21 +35,11 @@ public class Incinerator extends Block { bars.remove(BarType.liquid); } - @Override - public void setStats() { - super.setStats(); - - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); - } - @Override public void update(Tile tile) { IncineratorEntity entity = tile.entity(); - float used = Math.min(powerCapacity, powerUse * Timers.delta()); - - if(entity.power.amount >= used){ - entity.power.amount -= used; + if(entity.cons.valid()){ entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.04f); }else{ entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.02f); 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 0611b7c727..befc9cc980 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java @@ -5,7 +5,6 @@ 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.ucore.core.Timers; @@ -37,7 +36,7 @@ public class LiquidMixer extends LiquidBlock{ LiquidMixerEntity entity = tile.entity(); if(tile.entity.cons.valid()){ - float use = Math.min(consumes.get(Uses.liquid).used() * Timers.delta(), liquidCapacity - entity.liquids.get(outputLiquid)); + float use = Math.min(consumes.get(ConsumeLiquid.class).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++) { 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 f2cbe29263..bda67dc758 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java @@ -2,27 +2,21 @@ package io.anuke.mindustry.world.blocks.production; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; 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.ucore.core.Timers; -import io.anuke.ucore.util.Mathf; public class PowerCrafter extends Block{ protected final int timerDump = timers++; - /**Required.*/ - protected ItemStack input; /**Optional.*/ protected Item outputItem; /**Optional. Set hasLiquids to true when using.*/ protected Liquid outputLiquid; protected float outputLiquidAmount; - protected float powerUse; protected float craftTime; public PowerCrafter(String name) { @@ -37,8 +31,6 @@ public class PowerCrafter extends Block{ public void setStats() { super.setStats(); - stats.add(BlockStat.inputItem, input); - if(outputItem != null){ stats.add(BlockStat.outputItem, outputItem); } @@ -46,26 +38,19 @@ public class PowerCrafter extends Block{ if(outputLiquid != null){ stats.add(BlockStat.liquidOutput, outputLiquid); } - - if(hasPower){ - stats.add(BlockStat.powerUse, 60f * powerUse, StatUnit.powerSecond); - } } @Override public void update(Tile tile) { GenericCrafterEntity entity = tile.entity(); - float powerUsed = Math.min(Timers.delta() * powerUse, tile.entity.power.amount); - int itemsUsed = Mathf.ceil(1 + input.amount * entity.progress); - - if(entity.power.amount > powerUsed && entity.items.has(input.item, itemsUsed)){ + if(entity.cons.valid()){ entity.progress += 1f/craftTime; entity.totalProgress += Timers.delta(); } if(entity.progress >= 1f){ - entity.items.remove(input); + entity.items.remove(consumes.item(), consumes.itemAmount()); if(outputItem != null) offloadNear(tile, outputItem); if(outputLiquid != null) handleLiquid(tile, tile, outputLiquid, outputLiquidAmount); entity.progress = 0f; @@ -80,11 +65,6 @@ public class PowerCrafter extends Block{ } } - @Override - public boolean acceptItem(Item item, Tile tile, Tile source) { - return item == input.item && tile.entity.items.get(input.item) < itemCapacity; - } - @Override public TileEntity getEntity() { return new GenericCrafterEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java index dcc147c953..a2949393c2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java @@ -12,7 +12,6 @@ import io.anuke.mindustry.world.blocks.PowerBlock; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.values.ItemListValue; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -28,12 +27,7 @@ public class PowerSmelter extends PowerBlock { protected final int timerDump = timers++; protected final int timerCraft = timers++; - /**Recipe format: - * First item in each array: result - * Everything else in each array: requirements. Can have duplicates.*/ - protected ItemStack[] inputs; protected Item result; - protected float powerUse; protected float minFlux = 0.2f; protected int fluxNeeded = 1; @@ -70,7 +64,7 @@ public class PowerSmelter extends PowerBlock { super.setBars(); bars.remove(BarType.inventory); - for(ItemStack item : inputs){ + for(ItemStack item : consumes.items()){ bars.add(new BlockBar(BarType.inventory, true, tile -> (float) tile.entity.items.get(item.item) / itemCapacity)); } } @@ -78,10 +72,7 @@ public class PowerSmelter extends PowerBlock { @Override public void setStats(){ super.setStats(); - //TODO input/outputs - stats.add(BlockStat.inputItems, new ItemListValue(inputs)); - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); stats.add(BlockStat.outputItem, result); stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); @@ -97,11 +88,8 @@ public class PowerSmelter extends PowerBlock { tryDump(tile, result); } - float used = powerUse * Timers.delta(); - //heat it up if there's enough power - if(entity.power.amount > used){ - entity.power.amount -= used; + if(entity.cons.valid()){ entity.heat += 1f / heatUpTime; if(Mathf.chance(Timers.delta() * burnEffectChance)) Effects.effect(burnEffect, entity.x + Mathf.range(size*4f), entity.y + Mathf.range(size*4)); @@ -112,11 +100,8 @@ public class PowerSmelter extends PowerBlock { entity.heat = Mathf.clamp(entity.heat); entity.time += entity.heat * Timers.delta(); - //make sure it has all the items - for(ItemStack item : inputs){ - if(!entity.items.has(item.item, item.amount)){ - return; - } + if(!entity.cons.valid()){ + return; } if(entity.items.get(result) >= itemCapacity //output full @@ -141,7 +126,7 @@ public class PowerSmelter extends PowerBlock { } if(consumeInputs) { - for (ItemStack item : inputs) { + for (ItemStack item : consumes.items()) { entity.items.remove(item.item, item.amount); } } @@ -153,7 +138,7 @@ public class PowerSmelter extends PowerBlock { @Override public boolean acceptItem(Item item, Tile tile, Tile source){ - for(ItemStack stack : inputs){ + for(ItemStack stack : consumes.items()){ if(stack.item == item){ return tile.entity.items.get(item) < itemCapacity; } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java index 5deb96b27b..b28847fb7e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java @@ -8,10 +8,11 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumeItem; +import io.anuke.mindustry.world.consumers.ConsumeItems; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.values.ItemListValue; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Timers; @@ -22,9 +23,7 @@ import io.anuke.ucore.util.Mathf; public class Smelter extends Block{ protected final int timerDump = timers++; protected final int timerCraft = timers++; - - protected ItemStack[] inputs; - protected Item fuel; + protected Item result; protected float minFlux = 0.2f; @@ -42,11 +41,14 @@ public class Smelter extends Block{ hasItems = true; solid = true; itemCapacity = 20; + + consumes.require(ConsumeItems.class); + consumes.require(ConsumeItem.class); } @Override public void setBars(){ - for(ItemStack item : inputs){ + for(ItemStack item : consumes.items()){ bars.add(new BlockBar(BarType.inventory, true, tile -> (float)tile.entity.items.get(item.item)/itemCapacity)); } } @@ -55,9 +57,9 @@ public class Smelter extends Block{ public void setStats(){ super.setStats(); - stats.add(BlockStat.inputFuel, fuel); + //TODO + //stats.add(BlockStat.inputFuel, fuel); stats.add(BlockStat.fuelBurnTime, burnDuration/60f, StatUnit.seconds); - stats.add(BlockStat.inputItems, new ItemListValue(inputs)); stats.add(BlockStat.outputItem, result); stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond); stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); @@ -68,7 +70,7 @@ public class Smelter extends Block{ public void init() { super.init(); - for(ItemStack item : inputs){ + for(ItemStack item : consumes.items()){ if(item.item.fluxiness >= minFlux && useFlux){ throw new IllegalArgumentException("'" + name + "' has input item '" + item.item.name + "', which is a flux, when useFlux is enabled. To prevent ambiguous item use, either remove this flux item from the inputs, or set useFlux to false."); } @@ -84,8 +86,8 @@ public class Smelter extends Block{ } //add fuel - if(entity.items.get(fuel) > 0 && entity.burnTime <= 0f){ - entity.items.remove(fuel, 1); + if(entity.consumed(ConsumeItem.class) && entity.burnTime <= 0f){ + entity.items.remove(consumes.item(), 1); entity.burnTime += burnDuration; Effects.effect(burnEffect, entity.x + Mathf.range(2f), entity.y + Mathf.range(2f)); } @@ -99,10 +101,8 @@ public class Smelter extends Block{ } //make sure it has all the items - for(ItemStack item : inputs){ - if(!entity.items.has(item.item, item.amount)){ - return; - } + if(!entity.cons.valid()){ + return; } if(entity.items.get(result) >= itemCapacity //output full @@ -127,7 +127,7 @@ public class Smelter extends Block{ } if(consumeInputs) { - for (ItemStack item : inputs) { + for (ItemStack item : consumes.items()) { entity.items.remove(item.item, item.amount); } } @@ -145,14 +145,14 @@ public class Smelter extends Block{ public boolean acceptItem(Item item, Tile tile, Tile source){ boolean isInput = false; - for(ItemStack req : inputs){ + for(ItemStack req : consumes.items()){ if(req.item == item){ isInput = true; break; } } - return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == fuel && tile.entity.items.get(fuel) < itemCapacity) || + return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == consumes.item() && tile.entity.items.get(consumes.item()) < itemCapacity) || (useFlux && item.fluxiness >= minFlux && tile.entity.items.get(item) < itemCapacity); } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Projector.java b/core/src/io/anuke/mindustry/world/blocks/units/Projector.java index 5dd6c7c3e5..55ddcd1e78 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/Projector.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/Projector.java @@ -15,7 +15,6 @@ public abstract class Projector extends Block { protected final int timerApply = timers++; protected final float applyTime = 4f; - protected float powerUse = 0.01f; protected float range = 80f; protected StatusEffect status; @@ -39,11 +38,8 @@ public abstract class Projector extends Block { public void update(Tile tile) { ProjectorEntity entity = tile.entity(); - float used = Math.min(powerCapacity, powerUse * Timers.delta()); - - if(entity.power.amount >= used){ + if(entity.cons.valid()){ entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.01f); - entity.power.amount -= used; }else{ entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.01f); } diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index 3015c88970..a68d7562b5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -19,10 +19,10 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumeItems; import io.anuke.mindustry.world.meta.BlockBar; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.values.ItemListValue; import io.anuke.mindustry.world.modules.InventoryModule; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Graphics; @@ -37,9 +37,7 @@ import java.io.IOException; public class UnitFactory extends Block { protected UnitType type; - protected ItemStack[] requirements; protected float produceTime = 1000f; - protected float powerUse = 0.1f; protected float openDuration = 50f; protected float launchVelocity = 0f; protected String unitRegion; @@ -50,14 +48,14 @@ public class UnitFactory extends Block { hasPower = true; hasItems = true; solidifes = true; + + consumes.require(ConsumeItems.class); } @Override public void setStats() { super.setStats(); - stats.add(BlockStat.inputItems, new ItemListValue(requirements)); - stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond); stats.add(BlockStat.craftSpeed, produceTime/60f, StatUnit.seconds); } @@ -119,8 +117,6 @@ public class UnitFactory extends Block { public void update(Tile tile) { UnitFactoryEntity entity = tile.entity(); - float used = Math.min(powerUse * Timers.delta(), powerCapacity); - entity.time += Timers.delta() * entity.speedScl; if(entity.openCountdown > 0){ @@ -148,10 +144,9 @@ public class UnitFactory extends Block { }*/ if(!entity.hasSpawned && hasRequirements(entity.items, entity.buildTime/produceTime) && - entity.power.amount >= used && !entity.open){ + entity.cons.valid() && !entity.open){ entity.buildTime += Timers.delta(); - entity.power.amount -= used; entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.05f); }else{ if(!entity.open) entity.speedScl = Mathf.lerpDelta(entity.speedScl, 0f, 0.05f); @@ -164,7 +159,7 @@ public class UnitFactory extends Block { entity.openCountdown = openDuration; - for(ItemStack stack : requirements){ + for(ItemStack stack : consumes.items()){ entity.items.remove(stack.item, stack.amount); } } @@ -172,7 +167,7 @@ public class UnitFactory extends Block { @Override public boolean acceptItem(Item item, Tile tile, Tile source) { - for(ItemStack stack : requirements){ + for(ItemStack stack : consumes.items()){ if(item == stack.item && tile.entity.items.get(item) <= stack.amount*2){ return true; } @@ -186,7 +181,7 @@ public class UnitFactory extends Block { } protected boolean hasRequirements(InventoryModule inv, float fraction){ - for(ItemStack stack : requirements){ + for(ItemStack stack : consumes.items()){ if(!inv.has(stack.item, (int)(fraction * stack.amount))){ return false; } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index f920ebf888..8a43c31e55 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -4,26 +4,29 @@ import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStats; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - public abstract class Consume { private boolean optional; + private boolean update; - public void optional(boolean optional) { + public Consume optional(boolean optional) { this.optional = optional; + return this; + } + + public Consume update(boolean update){ + this.update = update; + return this; } public boolean isOptional() { return optional; } + public boolean isUpdate() { + return update; + } + 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 index e1d3db4e64..b618c7b7ab 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java @@ -8,9 +8,20 @@ import io.anuke.mindustry.world.meta.BlockStats; public class ConsumeItem extends Consume { private final Item item; + private final int amount; public ConsumeItem(Item item) { this.item = item; + this.amount = 1; + } + + public ConsumeItem(Item item, int amount) { + this.item = item; + this.amount = amount; + } + + public int getAmount() { + return amount; } public Item get() { @@ -24,7 +35,7 @@ public class ConsumeItem extends Consume { @Override public boolean valid(Block block, TileEntity entity) { - return entity.items.has(item); + return entity.items.has(item, amount); } @Override diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java new file mode 100644 index 0000000000..44e9cc2b08 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java @@ -0,0 +1,38 @@ +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; +import io.anuke.mindustry.world.meta.values.ItemFilterValue; +import io.anuke.ucore.function.Predicate; + +public class ConsumeItemFilter extends Consume{ + private final Predicate item; + + public ConsumeItemFilter(Predicate item) { + this.item = item; + } + + @Override + public void update(Block block, TileEntity entity) { + + } + + @Override + public boolean valid(Block block, TileEntity entity) { + for(int i = 0; i < Item.all().size; i ++){ + Item item = Item.getByID(i); + if(entity.items.has(item) && this.item.test(item)){ + return true; + } + } + return false; + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.inputItems, new ItemFilterValue(item)); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java new file mode 100644 index 0000000000..f662fcfebb --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java @@ -0,0 +1,37 @@ +package io.anuke.mindustry.world.consumers; + +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.type.ItemStack; +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.values.ItemListValue; + +public class ConsumeItems extends Consume { + private ItemStack[] items; + + public ConsumeItems(ItemStack[] items) { + this.items = items; + } + + public ItemStack[] getItems() { + return items; + } + + @Override + public void update(Block block, TileEntity entity) { + for(ItemStack stack : items){ + entity.items.remove(stack); + } + } + + @Override + public boolean valid(Block block, TileEntity entity) { + return entity.items.has(items); + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.inputItems, new ItemListValue(items)); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java index 2fa7e36404..1f82439c5d 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -6,6 +6,7 @@ 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 ConsumeLiquid extends Consume { private final float use; @@ -41,6 +42,6 @@ public class ConsumeLiquid extends Consume { } float use(Block block) { - return Math.min(use, block.liquidCapacity); + return Math.min(use * Timers.delta(), block.liquidCapacity); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java new file mode 100644 index 0000000000..5f3fd5dfc4 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -0,0 +1,41 @@ +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; +import io.anuke.mindustry.world.meta.values.LiquidFilterValue; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.function.Predicate; + +public class ConsumeLiquidFilter extends Consume{ + private final Predicate liquid; + private final float use; + + public ConsumeLiquidFilter(Predicate liquid, float amount) { + this.liquid = liquid; + this.use = amount; + } + + @Override + public void update(Block block, TileEntity entity) { + entity.liquids.remove(entity.liquids.current(), use(block)); + } + + @Override + public boolean valid(Block block, TileEntity entity) { + return liquid.test(entity.liquids.current()) && entity.liquids.currentAmount() >= use(block); + } + + @Override + public void display(BlockStats stats) { + stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid)); + stats.add(BlockStat.liquidUse, 60f * use, StatUnit.liquidSecond); + } + + float use(Block block) { + return Math.min(use * Timers.delta(), block.liquidCapacity); + } +} diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index 02590d85c4..552b41bce3 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -1,71 +1,101 @@ package io.anuke.mindustry.world.consumers; -import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.ObjectSet; +import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.world.Block; import io.anuke.ucore.function.Consumer; public class Consumers { - private Consume[] consumeMap = new Consume[Uses.values().length]; + private ObjectMap, Consume> map = new ObjectMap<>(); + private ObjectSet> required = new ObjectSet<>(); + + public void require(Class type){ + required.add(type); + } + + public void checkRequired(Block block){ + for (Class c : required){ + if(!map.containsKey(c)){ + throw new RuntimeException("Missing required consumer of type \"" + ClassReflection.getSimpleName(c) + "\" in block \"" + block.name + "\"!"); + } + } + } public ConsumePower power(float amount){ ConsumePower p = new ConsumePower(amount); - add(Uses.power, p); + add(p); return p; } public ConsumeLiquid liquid(Liquid liquid, float amount){ ConsumeLiquid c = new ConsumeLiquid(liquid, amount); - add(Uses.liquid, c); + add(c); return c; } public ConsumeItem item(Item item){ - ConsumeItem i = new ConsumeItem(item); - add(Uses.items, i); + return item(item, 1); + } + + public ConsumeItem item(Item item, int amount){ + ConsumeItem i = new ConsumeItem(item, amount); + add(i); + return i; + } + + public ConsumeItems items(ItemStack[] items){ + ConsumeItems i = new ConsumeItems(items); + add(i); return i; } public Item item(){ - return this.get(Uses.items).get(); + return get(ConsumeItem.class).get(); + } + + public ItemStack[] items(){ + return get(ConsumeItems.class).getItems(); + } + + public int itemAmount(){ + return get(ConsumeItem.class).getAmount(); } public Liquid liquid(){ - return this.get(Uses.liquid).get(); + return get(ConsumeLiquid.class).get(); } - public void add(Uses type, Consume consume){ - consumeMap[type.ordinal()] = consume; + public Consume add(Consume consume){ + map.put(consume.getClass(), consume); + return consume; } - public void remove(Uses type){ - consumeMap[type.ordinal()] = null; + public void remove(Class type){ + map.remove(type); } - public boolean has(Uses type){ - return consumeMap[type.ordinal()] != null; + public boolean has(Class type){ + return map.containsKey(type); } - public T get(Uses type){ - if(consumeMap[type.ordinal()] == null){ + public T get(Class type){ + if(!map.containsKey(type)){ throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!"); } - return (T)consumeMap[type.ordinal()]; + return (T)map.get(type); + } + + public Iterable all() { + return map.values(); } 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()); - } + for(Consume c : all()){ + cons.accept(c); } } } diff --git a/core/src/io/anuke/mindustry/world/consumers/Uses.java b/core/src/io/anuke/mindustry/world/consumers/Uses.java deleted file mode 100644 index c1bb49632a..0000000000 --- a/core/src/io/anuke/mindustry/world/consumers/Uses.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.world.consumers; - -public enum Uses { - power, - liquid, - items, -} diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStat.java b/core/src/io/anuke/mindustry/world/meta/BlockStat.java index 4279f272c9..1e18967fbf 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStat.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStat.java @@ -22,7 +22,6 @@ public enum BlockStat { maxPowerGeneration(StatCategory.power), inputLiquid(StatCategory.crafting), - inputLiquidAux(StatCategory.crafting), liquidUse(StatCategory.crafting), inputItem(StatCategory.crafting), inputItems(StatCategory.crafting), diff --git a/core/src/io/anuke/mindustry/world/meta/BlockStats.java b/core/src/io/anuke/mindustry/world/meta/BlockStats.java index 112f431211..e697c0255f 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockStats.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockStats.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.OrderedMap; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.values.*; import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Log; @@ -13,9 +14,14 @@ import io.anuke.ucore.util.Log; public class BlockStats { private static final boolean errorWhenMissing = true; - private OrderedMap> map = new OrderedMap<>(); + private final OrderedMap> map = new OrderedMap<>(); + private final Block block; private boolean dirty; + public BlockStats(Block block) { + this.block = block; + } + /**Adds a single float value with this stat, formatted to 2 decimal places.*/ public void add(BlockStat stat, float value, StatUnit unit){ add(stat, new NumberValue(value, unit)); @@ -66,7 +72,7 @@ public class BlockStats { } if(map.containsKey(stat.category) && map.get(stat.category).containsKey(stat)){ - throw new RuntimeException("Duplicate stat entry: \"" +stat + "\""); + throw new RuntimeException("Duplicate stat entry: \"" +stat + "\" in block '" + block.name + "'"); } if(!map.containsKey(stat.category)){ @@ -80,7 +86,7 @@ public class BlockStats { public void remove(BlockStat stat){ if(!map.containsKey(stat.category) || !map.get(stat.category).containsKey(stat)){ - throw new RuntimeException("No stat entry found: \"" + stat + "\"!"); + throw new RuntimeException("No stat entry found: \"" + stat + "\" in block '" + block.name + "'!"); } map.get(stat.category).remove(stat); diff --git a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java index 39bf00dc5c..c33e556ee8 100644 --- a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java +++ b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java @@ -1,6 +1,5 @@ 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; @@ -9,15 +8,14 @@ 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)){ + for(Consume cons : entity.tile.block().consumes.all()){ + if(cons.isUpdate() && prevValid && entity.tile.block().shouldConsume(entity.tile) && cons.valid(entity.getTile().block(), entity)){ cons.update(entity.getTile().block(), entity); } @@ -31,21 +29,13 @@ public class ConsumeModule extends BlockModule{ return valid; } - public Array all() { - return consumers; - } - @Override public void write(DataOutput stream) throws IOException { - for(Consume cons : consumers){ - cons.write(stream); - } + stream.writeBoolean(valid); } @Override public void read(DataInput stream) throws IOException { - for(Consume cons : consumers){ - cons.read(stream); - } + valid = stream.readBoolean(); } } diff --git a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java index 564bed0512..42358a1ca5 100644 --- a/core/src/io/anuke/mindustry/world/modules/LiquidModule.java +++ b/core/src/io/anuke/mindustry/world/modules/LiquidModule.java @@ -21,6 +21,10 @@ public class LiquidModule extends BlockModule { return current; } + public float currentAmount(){ + return liquids[current.id]; + } + public float get(Liquid liquid){ return liquids[liquid.id]; }