Offload optimizations / Compile errors fixed / Massive refactor

This commit is contained in:
Anuken
2018-07-08 16:38:29 -04:00
parent c06152de07
commit 63a0fde121
46 changed files with 583 additions and 565 deletions

View File

@@ -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") {{

View File

@@ -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;

View File

@@ -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;
}};

View File

@@ -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);
}};
}

View File

@@ -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") {{

View File

@@ -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<Tile> 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<Tile> 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<? extends Consume> 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<Tile> proximity(){
return proximity;
}
@Override

View File

@@ -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<Tile> 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<Tile> 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<Tile> 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;

View File

@@ -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<BlockFlag> 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

View File

@@ -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];

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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){

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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<Tile> testLinks = findLinks(tile);
@@ -238,7 +234,7 @@ public class WarpGate extends PowerBlock{
entity.power.amount = 0f;
entity.teleporting = false;
});
}
}*/
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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())){

View File

@@ -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.<NuclearReactorEntity>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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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.<ConsumeLiquid>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++) {

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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{}
}

View File

@@ -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

View File

@@ -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> item;
public ConsumeItemFilter(Predicate<Item> 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));
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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> liquid;
private final float use;
public ConsumeLiquidFilter(Predicate<Liquid> 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);
}
}

View File

@@ -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<Class<? extends Consume>, Consume> map = new ObjectMap<>();
private ObjectSet<Class<? extends Consume>> required = new ObjectSet<>();
public void require(Class<? extends Consume> type){
required.add(type);
}
public void checkRequired(Block block){
for (Class<? extends Consume> 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.<ConsumeItem>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.<ConsumeLiquid>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<? extends Consume> type){
map.remove(type);
}
public boolean has(Uses type){
return consumeMap[type.ordinal()] != null;
public boolean has(Class<? extends Consume> type){
return map.containsKey(type);
}
public <T extends Consume> T get(Uses type){
if(consumeMap[type.ordinal()] == null){
public <T extends Consume> T get(Class<T> 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<Consume> all() {
return map.values();
}
public void forEach(Consumer<Consume> cons){
for (Consume c : consumeMap) {
if (c != null) {
cons.accept(c);
}
}
}
public void addAll(Array<Consume> result){
for (Consume c : consumeMap) {
if (c != null) {
result.add(c.copy());
}
for(Consume c : all()){
cons.accept(c);
}
}
}

View File

@@ -1,7 +0,0 @@
package io.anuke.mindustry.world.consumers;
public enum Uses {
power,
liquid,
items,
}

View File

@@ -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),

View File

@@ -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<StatCategory, OrderedMap<BlockStat, StatValue>> map = new OrderedMap<>();
private final OrderedMap<StatCategory, OrderedMap<BlockStat, StatValue>> 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);

View File

@@ -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<Consume> 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<Consume> 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();
}
}

View File

@@ -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];
}