New block stat system, names for all current block recipes

This commit is contained in:
Anuken
2018-06-27 21:29:57 -04:00
parent 2344fb910b
commit 18b137a1a6
44 changed files with 777 additions and 224 deletions

View File

@@ -56,7 +56,7 @@ public class Items implements ContentList{
plasteel = new Item("plasteel", Color.valueOf("e9ead3")) {{
type = ItemType.material;
flammability = 0.2f;
flammability = 0.1f;
explosiveness = 0.1f;
}};

View File

@@ -63,12 +63,12 @@ public class Recipes implements ContentList{
//TODO implement alloy smelter
// new Recipe(crafting, CraftingBlocks.alloySmelter, new ItemStack(Items.silicon, 160), new ItemStack(Items.lead, 160), new ItemStack(Items.thorium, 140));
new Recipe(crafting, CraftingBlocks.plasteelcompressor, new ItemStack(Items.silicon, 60), new ItemStack(Items.lead, 170), new ItemStack(Items.titanium, 170));
// new Recipe(crafting, CraftingBlocks.plasteelcompressor, new ItemStack(Items.silicon, 60), new ItemStack(Items.lead, 170), new ItemStack(Items.titanium, 170));
//misc
new Recipe(crafting, CraftingBlocks.pulverizer, new ItemStack(Items.tungsten, 60), new ItemStack(Items.lead, 50));
new Recipe(crafting, CraftingBlocks.thermiteMixer, new ItemStack(Items.tungsten, 100), new ItemStack(Items.lead, 50));
new Recipe(crafting, CraftingBlocks.blastMixer, new ItemStack(Items.tungsten, 60), new ItemStack(Items.lead, 60), new ItemStack(Items.carbide, 40));
//new Recipe(crafting, CraftingBlocks.thermiteMixer, new ItemStack(Items.tungsten, 100), new ItemStack(Items.lead, 50));
//new Recipe(crafting, CraftingBlocks.blastMixer, new ItemStack(Items.tungsten, 60), new ItemStack(Items.lead, 60), new ItemStack(Items.carbide, 40));
new Recipe(crafting, CraftingBlocks.cryofluidmixer, new ItemStack(Items.lead, 130), new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 90));
new Recipe(crafting, CraftingBlocks.melter, new ItemStack(Items.tungsten, 60), new ItemStack(Items.lead, 70), new ItemStack(Items.carbide, 90));
@@ -102,7 +102,7 @@ public class Recipes implements ContentList{
new Recipe(production, ProductionBlocks.waterextractor, new ItemStack(Items.tungsten, 50), new ItemStack(Items.carbide, 50), new ItemStack(Items.lead, 40));
new Recipe(production, ProductionBlocks.cultivator, new ItemStack(Items.tungsten, 20), new ItemStack(Items.lead, 50), new ItemStack(Items.silicon, 20));
new Recipe(production, ProductionBlocks.oilextractor, new ItemStack(Items.tungsten, 90), new ItemStack(Items.carbide, 150), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 100));
//new Recipe(production, ProductionBlocks.oilextractor, new ItemStack(Items.tungsten, 90), new ItemStack(Items.carbide, 150), new ItemStack(Items.lead, 100), new ItemStack(Items.silicon, 100));
//UNITS

View File

@@ -14,10 +14,10 @@ public class UnitBlocks extends BlockList implements ContentList {
public void load() {
droneFactory = new UnitFactory("dronefactory") {{
type = UnitTypes.drone;
produceTime = 300;
produceTime = 800;
size = 2;
requirements = new ItemStack[]{
new ItemStack(Items.silicon, 20), new ItemStack(Items.lead, 20)
new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)
};
}};

View File

@@ -9,6 +9,8 @@ import io.anuke.mindustry.world.Block;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.debug;
import static io.anuke.mindustry.Vars.headless;
@@ -31,6 +33,8 @@ public class Recipe implements UnlockableContent{
this.requirements = requirements;
this.category = category;
Arrays.sort(requirements, (a, b) -> Integer.compare(a.item.id, b.item.id));
float timeToPlace = 0f;
for(ItemStack stack : requirements){
timeToPlace += stack.amount * stack.item.cost;
@@ -56,9 +60,9 @@ public class Recipe implements UnlockableContent{
public void init() {
if(!Bundles.has("block." + result.name + ".name")) {
Log.err("WARNING: Recipe block '{0}' does not have a formal name defined.", result.name);
}else if(result.fullDescription == null){
}/*else if(result.fullDescription == null){
Log.err("WARNING: Recipe block '{0}' does not have a description defined.", result.name);
}
}*/
}
@Override

View File

@@ -2,34 +2,37 @@ package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.scene.style.TextureRegionDrawable;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
public class ItemImage extends Stack {
private Image image;
public ItemImage(TextureRegion region, Supplier<CharSequence> text, Color color) {
public ItemImage(TextureRegion region, Supplier<CharSequence> text) {
Table t = new Table().left().bottom();
t.label(text).color(Color.DARK_GRAY).padBottom(-60).get().setFontScale(0.5f);
t.row();
t.label(text).get().setFontScale(0.5f);
image = new Image(region);
image.setColor(color);
Image image = new Image(region);
add(image);
add(t);
}
public ItemImage updateColor(Supplier<Color> c){
image.update(() -> image.setColor(c.get()));
return this;
}
public ItemImage(ItemStack stack) {
Table t = new Table().left().bottom();
public ItemImage updateRegion(Supplier<TextureRegion> c){
image.update(() -> image.setDrawable(new TextureRegionDrawable(c.get())));
return this;
t.add(stack.amount + "").color(Color.DARK_GRAY).padBottom(-22).get().setFontScale(0.5f);
t.row();
t.add(stack.amount + "").get().setFontScale(0.5f);
Image image = new Image(stack.item.region);
add(image);
add(t);
}
}

View File

@@ -1,6 +1,5 @@
package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.IntSet;
@@ -106,7 +105,7 @@ public class BlockInventoryFragment implements Fragment {
HandCursorListener l = new HandCursorListener();
l.setEnabled(canPick);
ItemImage image = new ItemImage(item.region, () -> round(items[f]), Color.WHITE);
ItemImage image = new ItemImage(item.region, () -> round(items[f]));
image.addListener(l);
image.tapped(() -> {
if(!canPick.get() || items[f] == 0) return;

View File

@@ -4,15 +4,24 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.OrderedMap;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.type.Category;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
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.StatCategory;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.actions.Actions;
@@ -317,6 +326,8 @@ public class BlocksFragment implements Fragment{
nameLabel.setWrap(true);
header.add(nameLabel).padLeft(2).width(120f);
header.addButton("?", () -> showBlockInfo(recipe.result)).expandX().padLeft(3).top().right().size(40f, 44f).padTop(-2);
descTable.add().pad(2);
Table requirements = new Table();
@@ -345,6 +356,56 @@ public class BlocksFragment implements Fragment{
descTable.row();
}
private void showBlockInfo(Block block){
FloatingDialog dialog = new FloatingDialog("$text.blocks.blockinfo");
dialog.addCloseButton();
Table table = new Table();
ScrollPane pane = new ScrollPane(table, "clear");
table.table(title -> {
title.addImage(Draw.region("block-icon-" + block.name)).size(8 * 6);
title.add("[accent]" + block.formalName).padLeft(5);
});
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
if(block.fullDescription != null){
table.add(block.fullDescription);
table.row();
table.addImage("white").height(3).color(Color.LIGHT_GRAY).pad(15).padLeft(0).padRight(0).fillX();
table.row();
}
BlockStats stats = block.stats;
for(StatCategory cat : stats.toMap().keys()){
OrderedMap<BlockStat, StatValue> map = stats.toMap().get(cat);
if(map.size == 0) continue;
table.add("$text.category." + cat.name()).color(Palette.accent).fillX();
table.row();
for (BlockStat stat : map.keys()){
table.table(inset -> {
inset.left();
inset.add("[LIGHT_GRAY]" + stat.localized() + ":[] ");
map.get(stat).display(inset);
}).fillX().padLeft(10);
table.row();
}
}
dialog.content().add(pane).grow();
dialog.show();
}
String format(int number){
if(number >= 1000000) {
return Strings.toFixed(number/1000000f, 1) + "[gray]mil[]";

View File

@@ -126,7 +126,7 @@ public class Block extends BaseBlock implements UnlockableContent{
public Block(String name) {
this.name = name;
this.formalName = Bundles.get("block." + name + ".name", name);
this.fullDescription = Bundles.getOrNull("block." + name + ".fulldescription");
this.fullDescription = Bundles.getOrNull("block." + name + ".description");
this.solid = false;
this.id = lastid++;
@@ -221,11 +221,11 @@ public class Block extends BaseBlock implements UnlockableContent{
public void setStats(){
stats.add(BlockStat.size, "{0}x{0}", size);
stats.add(BlockStat.health, health);
stats.add(BlockStat.health, health, StatUnit.none);
if(hasPower) stats.add(BlockStat.powerCapacity, powerCapacity);
if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity);
if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity);
if(hasPower) stats.add(BlockStat.powerCapacity, powerCapacity, StatUnit.powerUnits);
if(hasLiquids) stats.add(BlockStat.liquidCapacity, liquidCapacity, StatUnit.liquidUnits);
if(hasItems) stats.add(BlockStat.itemCapacity, itemCapacity, StatUnit.items);
}
//TODO make this easier to config.

View File

@@ -8,6 +8,8 @@ import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.values.ItemFilterValue;
public class ItemTurret extends CooledTurret {
protected int maxAmmo = 50;
@@ -19,6 +21,15 @@ public class ItemTurret extends CooledTurret {
hasItems = true;
}
@Override
public void setStats() {
super.setStats();
stats.remove(BlockStat.itemCapacity);
stats.add(BlockStat.inputItems, new ItemFilterValue(item -> ammoMap.containsKey(item)));
}
@Override
public int acceptStack(Item item, int amount, Tile tile, Unit source) {
TurretEntity entity = tile.entity();

View File

@@ -5,8 +5,10 @@ import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.meta.BlockBar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.values.LiquidFilterValue;
import io.anuke.ucore.core.Effects;
public abstract class LiquidTurret extends Turret {
@@ -18,6 +20,13 @@ public abstract class LiquidTurret extends Turret {
hasLiquids = true;
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.inputItems, new LiquidFilterValue(item -> liquidAmmoMap.containsKey(item)));
}
@Override
public void setBars() {
super.setBars();

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.world.blocks.defense.turrets;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
public abstract class PowerTurret extends CooledTurret {
protected float powerUsed = 0.5f;
@@ -17,7 +18,7 @@ public abstract class PowerTurret extends CooledTurret {
public void setStats(){
super.setStats();
stats.add(BlockStat.powerShot, powerUsed);
stats.add(BlockStat.powerShot, powerUsed, StatUnit.powerUnits);
}
@Override

View File

@@ -18,6 +18,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup;
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.Graphics;
@@ -88,10 +89,11 @@ public abstract class Turret extends Block{
if(ammo != null) stats.add("ammo", ammo);
if(ammo != null) stats.add("ammocapacity", maxAmmo);
if(ammo != null) stats.add("ammoitem", ammoMultiplier);*/
stats.add(BlockStat.shootRange, (int)range);
stats.add(BlockStat.inaccuracy, (int)inaccuracy);
stats.add(BlockStat.reload, Strings.toFixed(60f/reload, 1));
stats.add(BlockStat.shots, shots);
stats.add(BlockStat.shootRange, range, StatUnit.blocks);
stats.add(BlockStat.inaccuracy, (int)inaccuracy, StatUnit.degrees);
stats.add(BlockStat.reload, 60f/reload, StatUnit.seconds);
stats.add(BlockStat.shots, shots, StatUnit.none);
}
@Override

View File

@@ -12,6 +12,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.*;
@@ -57,7 +58,7 @@ public class Conveyor extends Block{
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.itemSpeed, speed * 60);
stats.add(BlockStat.itemSpeed, speed * 60, StatUnit.pixelsSecond);
}
@Override

View File

@@ -7,6 +7,8 @@ import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
import io.anuke.mindustry.world.meta.BlockStat;
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;
@@ -30,6 +32,13 @@ public abstract class ItemGenerator extends PowerGenerator {
hasItems = true;
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.inputItems, new ItemFilterValue(item -> getItemEfficiency(item) >= minItemEfficiency));
}
@Override
public void setBars(){
super.setBars();
@@ -86,7 +95,7 @@ public abstract class ItemGenerator extends PowerGenerator {
}
protected abstract float getItemEfficiency(Item item);
protected abstract float getItemEfficiency(Item item);
@Override
public TileEntity getEntity() {

View File

@@ -4,6 +4,8 @@ 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.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
@@ -21,6 +23,13 @@ public abstract class ItemLiquidGenerator extends ItemGenerator {
liquidCapacity = 10f;
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.inputLiquid, new LiquidFilterValue(item -> getLiquidEfficiency(item) >= minLiquidEfficiency));
}
@Override
public void update(Tile tile){
ItemGeneratorEntity entity = tile.entity();

View File

@@ -5,6 +5,8 @@ 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.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
@@ -23,7 +25,14 @@ public abstract class LiquidGenerator extends PowerGenerator {
liquidCapacity = 30f;
hasLiquids = true;
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.inputLiquid, new LiquidFilterValue(item -> getEfficiency(item) >= minEfficiency));
}
@Override
public void draw(Tile tile){
super.draw(tile);

View File

@@ -12,6 +12,7 @@ import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
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.Timers;
import io.anuke.ucore.graphics.Draw;
@@ -60,8 +61,8 @@ public class NuclearReactor extends PowerGenerator {
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.inputItem, generateItem.toString());
stats.add(BlockStat.maxPowerGeneration, powerMultiplier*60f);
stats.add(BlockStat.inputItem, generateItem);
stats.add(BlockStat.maxPowerGeneration, powerMultiplier*60f, StatUnit.powerSecond);
}
@Override

View File

@@ -14,6 +14,7 @@ import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.PowerBlock;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
@@ -68,8 +69,8 @@ public class PowerDistributor extends PowerBlock{
public void setStats(){
super.setStats();
stats.add(BlockStat.powerRange, laserRange);
stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60);
stats.add(BlockStat.powerRange, laserRange, StatUnit.blocks);
stats.add(BlockStat.powerTransferSpeed, powerSpeed * 60, StatUnit.powerSecond);
}
@Override

View File

@@ -1,6 +1,8 @@
package io.anuke.mindustry.world.blocks.power;
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.Timers;
public class SolarGenerator extends PowerGenerator {
@@ -11,6 +13,13 @@ public class SolarGenerator extends PowerGenerator {
super(name);
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.maxPowerGeneration, generation * 60f, StatUnit.powerSecond);
}
@Override
public void update(Tile tile){
addPower(tile, generation * Timers.delta());

View File

@@ -12,6 +12,8 @@ import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup;
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.Graphics;
@@ -117,6 +119,9 @@ public class Drill extends Block{
public void setStats(){
super.setStats();
//TODO add drill speed stats
stats.add(BlockStat.drillTier, tier, StatUnit.none);
stats.add(BlockStat.drillSpeed, 60f/drillTime, StatUnit.itemsSecond);
}
@Override

View File

@@ -12,6 +12,7 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockBar;
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;
@@ -56,11 +57,13 @@ public class GenericCrafter extends Block{
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.craftSpeed, 60f/craftTime);
stats.add(BlockStat.outputItem, output.toString());
stats.add(BlockStat.craftSpeed, 60f/craftTime, StatUnit.itemsSecond);
stats.add(BlockStat.outputItem, output);
if(inputLiquid != null) stats.add(BlockStat.inputLiquid, "{0} x {1}", inputLiquid, (int)(liquidUse * craftTime));
if(inputItem != null) stats.add(BlockStat.inputItem, "{0} x {1}", inputItem, inputItem.amount);
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

View File

@@ -8,6 +8,8 @@ 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;
@@ -34,6 +36,13 @@ 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();

View File

@@ -7,6 +7,8 @@ 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;
@@ -31,6 +33,25 @@ public class PowerCrafter extends Block{
hasItems = true;
}
@Override
public void setStats() {
super.setStats();
stats.add(BlockStat.inputItem, input);
if(outputItem != null){
stats.add(BlockStat.outputItem, outputItem);
}
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();

View File

@@ -10,6 +10,8 @@ import io.anuke.mindustry.world.Tile;
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;
@@ -20,7 +22,6 @@ import io.anuke.ucore.util.Mathf;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class PowerSmelter extends PowerBlock {
protected final int timerDump = timers++;
@@ -70,12 +71,12 @@ public class PowerSmelter extends PowerBlock {
super.setStats();
//TODO input/outputs
stats.add(BlockStat.inputItems, Arrays.toString(inputs));
stats.add(BlockStat.powerUse, powerUse * 60f);
stats.add(BlockStat.outputItem, result.toString());
stats.add(BlockStat.craftSpeed, 60f/craftTime);
stats.add(BlockStat.inputItemCapacity, itemCapacity);
stats.add(BlockStat.outputItemCapacity, itemCapacity);
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);
stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items);
}
@Override

View File

@@ -8,6 +8,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.LiquidBlock;
import io.anuke.mindustry.world.meta.BlockGroup;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
@@ -35,7 +36,7 @@ public class Pump extends LiquidBlock{
@Override
public void setStats(){
super.setStats();
stats.add(BlockStat.liquidOutput, 60f*pumpAmount);
stats.add(BlockStat.liquidOutput, 60f*pumpAmount, StatUnit.liquidSecond);
}
@Override

View File

@@ -7,6 +7,9 @@ import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterEntity;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.mindustry.world.meta.values.ItemFilterValue;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
@@ -37,6 +40,24 @@ public class Separator extends Block {
hasLiquids = true;
}
@Override
public void setStats() {
super.setStats();
if(hasPower){
stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond);
}
stats.add(BlockStat.liquidUse, liquidUse * 60f, StatUnit.liquidSecond);
stats.add(BlockStat.inputLiquid, liquid);
stats.add(BlockStat.outputItem, new ItemFilterValue(item -> {
for(Item i : results){
if(item == i) return true;
}
return false;
}));
}
@Override
public void draw(Tile tile) {
super.draw(tile);

View File

@@ -10,6 +10,8 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
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;
@@ -17,8 +19,6 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Mathf;
import java.util.Arrays;
public class Smelter extends Block{
protected final int timerDump = timers++;
protected final int timerCraft = timers++;
@@ -55,13 +55,13 @@ public class Smelter extends Block{
public void setStats(){
super.setStats();
stats.add(BlockStat.inputFuel, fuel.toString());
stats.add(BlockStat.fuelBurnTime, burnDuration/60f);
stats.add(BlockStat.inputItems, Arrays.toString(inputs));
stats.add(BlockStat.outputItem, result.toString());
stats.add(BlockStat.craftSpeed, 60f/craftTime);
stats.add(BlockStat.inputItemCapacity, itemCapacity);
stats.add(BlockStat.outputItemCapacity, itemCapacity);
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);
stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items);
}
@Override

View File

@@ -6,6 +6,8 @@ import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
@@ -27,6 +29,16 @@ public class SolidPump extends Pump {
liquidRegion = name + "-liquid";
}
@Override
public void setStats() {
super.setStats();
stats.remove(BlockStat.liquidOutput);
stats.add(BlockStat.powerUse, powerUse * 60f, StatUnit.powerSecond);
stats.add(BlockStat.liquidOutput, result);
}
@Override
public void draw(Tile tile) {
SolidPumpEntity entity = tile.entity();

View File

@@ -21,6 +21,9 @@ import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.modules.InventoryModule;
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.Graphics;
import io.anuke.ucore.core.Timers;
@@ -49,6 +52,15 @@ public class UnitFactory extends Block {
solidifes = true;
}
@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);
}
@Override
public boolean isSolidFor(Tile tile) {
UnitFactoryEntity entity = tile.entity();

View File

@@ -1,5 +1,7 @@
package io.anuke.mindustry.world.meta;
import io.anuke.ucore.util.Bundles;
/**Describes one type of stat for a block.*/
public enum BlockStat {
health(StatCategory.general),
@@ -20,12 +22,15 @@ public enum BlockStat {
maxPowerGeneration(StatCategory.power),
inputLiquid(StatCategory.crafting),
liquidUse(StatCategory.crafting),
inputItem(StatCategory.crafting),
inputItems(StatCategory.crafting),
inputFuel(StatCategory.crafting),
fuelBurnTime(StatCategory.crafting),
craftSpeed(StatCategory.crafting),
outputItem(StatCategory.crafting),
drillTier(StatCategory.crafting),
drillSpeed(StatCategory.crafting),
shootRange(StatCategory.shooting),
inaccuracy(StatCategory.shooting),
@@ -41,4 +46,8 @@ public enum BlockStat {
BlockStat(StatCategory category) {
this.category = category;
}
public String localized(){
return Bundles.get("text.blocks." + name().toLowerCase());
}
}

View File

@@ -2,30 +2,51 @@ package io.anuke.mindustry.world.meta;
import com.badlogic.gdx.utils.ObjectMap.Entry;
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.meta.values.ItemValue;
import io.anuke.mindustry.world.meta.values.LiquidValue;
import io.anuke.mindustry.world.meta.values.NumberValue;
import io.anuke.mindustry.world.meta.values.StringValue;
import io.anuke.ucore.util.Bundles;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings;
/**Hold and organizes a list of block stats.*/
public class BlockStats {
//TODO change back to true
private static final boolean errorWhenMissing = false;
private static final boolean errorWhenMissing = true;
private OrderedMap<StatCategory, OrderedMap<BlockStat, String>> map = new OrderedMap<>();
private OrderedMap<StatCategory, OrderedMap<BlockStat, StatValue>> map = new OrderedMap<>();
private boolean dirty;
/**Adds a single integer value with this stat.*/
public void add(BlockStat stat, int value){
add(stat, "" + value);
}
/**Adds a single float value with this stat, formatted to 2 decimal places.*/
public void add(BlockStat stat, float value){
add(stat, Strings.toFixed(value, 2));
public void add(BlockStat stat, float value, StatUnit unit){
add(stat, new NumberValue(value, unit));
}
/**Adds a formatted string with this stat.*/
public void add(BlockStat stat, String format, Object... arguments){
/**Adds an item value.*/
public void add(BlockStat stat, Item item){
add(stat, new ItemValue(new ItemStack(item, 1)));
}
/**Adds a liquid value.*/
public void add(BlockStat stat, Liquid liquid){
add(stat, new LiquidValue(liquid));
}
/**Adds an item value.*/
public void add(BlockStat stat, ItemStack item){
add(stat, new ItemValue(item));
}
/**Adds a single string value with this stat.*/
public void add(BlockStat stat, String format, Object... args){
add(stat, new StringValue(format, args));
}
/**Adds a stat value.*/
public void add(BlockStat stat, StatValue value){
if(!Bundles.has("text.blocks." + stat.name().toLowerCase())){
if(!errorWhenMissing){
Log.err("Warning: No bundle entry for stat type \"" + stat + "\"!");
@@ -34,6 +55,14 @@ public class BlockStats {
}
}
if(!Bundles.has("text.category." + stat.category.name().toLowerCase())){
if(!errorWhenMissing){
Log.err("Warning: No bundle entry for stat cateogry \"" + stat.category + "\"!");
}else{
throw new RuntimeException("No bundle entry for stat category \"" + stat.category + "\"!");
}
}
if(map.containsKey(stat.category) && map.get(stat.category).containsKey(stat)){
throw new RuntimeException("Duplicate stat entry: \"" +stat + "\"");
}
@@ -42,7 +71,7 @@ public class BlockStats {
map.put(stat.category, new OrderedMap<>());
}
map.get(stat.category).put(stat, Strings.formatArgs(format, arguments));
map.get(stat.category).put(stat, value);
dirty = true;
}
@@ -57,11 +86,11 @@ public class BlockStats {
dirty = true;
}
public OrderedMap<StatCategory, OrderedMap<BlockStat, String>> toMap() {
public OrderedMap<StatCategory, OrderedMap<BlockStat, StatValue>> toMap() {
//sort stats by index if they've been modified
if(dirty) {
map.orderedKeys().sort();
for (Entry<StatCategory, OrderedMap<BlockStat, String>> entry : map.entries()) {
for (Entry<StatCategory, OrderedMap<BlockStat, StatValue>> entry : map.entries()) {
entry.value.orderedKeys().sort();
}

View File

@@ -0,0 +1,22 @@
package io.anuke.mindustry.world.meta;
import io.anuke.ucore.util.Bundles;
/**Defines a unit of measurement for block stats.*/
public enum StatUnit {
blocks,
powerSecond,
liquidSecond,
itemsSecond,
pixelsSecond,
liquidUnits,
powerUnits,
degrees,
seconds,
none,
items;
public String localized(){
return Bundles.get("text.unit." + name().toLowerCase());
}
}

View File

@@ -0,0 +1,10 @@
package io.anuke.mindustry.world.meta;
import io.anuke.ucore.scene.ui.layout.Table;
/**A base interface for a value of a stat that is displayed.*/
public interface StatValue {
/**This method should all elements necessary to display this stat to the specified table.
* For example, a stat that is just text would add label to the table. */
void display(Table table);
}

View File

@@ -0,0 +1,32 @@
package io.anuke.mindustry.world.meta.values;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.scene.ui.layout.Table;
public class ItemFilterValue implements StatValue {
private final Predicate<Item> filter;
public ItemFilterValue(Predicate<Item> filter) {
this.filter = filter;
}
@Override
public void display(Table table) {
Array<Item> list = new Array<>();
for(Item item : Item.all()){
if(filter.test(item)) list.add(item);
}
for (int i = 0; i < list.size; i++) {
Item item = list.get(i);
table.addImage(item.region).size(8*3).padRight(2).padLeft(2);
if(i != list.size - 1){
table.add("/");
}
}
}
}

View File

@@ -0,0 +1,35 @@
package io.anuke.mindustry.world.meta.values;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.ui.ItemImage;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.scene.ui.layout.Table;
public class ItemListValue implements StatValue{
private final Item[] items;
private final ItemStack[] stacks;
public ItemListValue(Item[] items) {
this.items = items;
this.stacks = null;
}
public ItemListValue(ItemStack[] stacks) {
this.stacks = stacks;
this.items = null;
}
@Override
public void display(Table table) {
if(items != null){
for(Item item : items){
table.addImage(item.region).size(8*3).padRight(5);
}
}else{
for(ItemStack stack : stacks){
table.add(new ItemImage(stack)).size(8*3).padRight(5);
}
}
}
}

View File

@@ -0,0 +1,20 @@
package io.anuke.mindustry.world.meta.values;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.ui.ItemImage;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.scene.ui.layout.Table;
public class ItemValue implements StatValue {
private final ItemStack item;
public ItemValue(ItemStack item) {
this.item = item;
}
@Override
public void display(Table table) {
//TODO better implementation, quantity support
table.add(new ItemImage(item)).size(8*3);
}
}

View File

@@ -0,0 +1,32 @@
package io.anuke.mindustry.world.meta.values;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.scene.ui.layout.Table;
public class LiquidFilterValue implements StatValue {
private final Predicate<Liquid> filter;
public LiquidFilterValue(Predicate<Liquid> filter) {
this.filter = filter;
}
@Override
public void display(Table table) {
Array<Liquid> list = new Array<>();
for(Liquid item : Liquid.all()){
if(filter.test(item)) list.add(item);
}
for (int i = 0; i < list.size; i++) {
Liquid item = list.get(i);
table.addImage("liquid-icon").color(item.color).size(8*3).padRight(2).padLeft(2);
if(i != list.size - 1){
table.add("/");
}
}
}
}

View File

@@ -0,0 +1,18 @@
package io.anuke.mindustry.world.meta.values;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.scene.ui.layout.Table;
public class LiquidValue implements StatValue {
private final Liquid liquid;
public LiquidValue(Liquid liquid) {
this.liquid = liquid;
}
@Override
public void display(Table table) {
table.addImage("liquid-icon").color(liquid.color).size(8*3);
}
}

View File

@@ -0,0 +1,31 @@
package io.anuke.mindustry.world.meta.values;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Strings;
/**A stat that is a number with a unit attacked.
* The number is rounded to 2 decimal places by default.*/
public class NumberValue implements StatValue{
private final StatUnit unit;
private final float value;
public NumberValue(float value, StatUnit unit) {
this.unit = unit;
this.value = value;
if(unit.localized().contains("???")){
throw new RuntimeException("No bundle definition found for unit: '" + unit + "'");
}
}
@Override
public void display(Table table) {
float diff = Math.abs((int)value - value);
int precision = diff <= 0.01f ? 0 : diff <= 0.1f ? 1 : 2;
table.add(Strings.toFixed(value, precision));
table.add(" " + unit.localized());
}
}

View File

@@ -0,0 +1,18 @@
package io.anuke.mindustry.world.meta.values;
import io.anuke.mindustry.world.meta.StatValue;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Strings;
public class StringValue implements StatValue {
private final String value;
public StringValue(String value, Object... args) {
this.value = Strings.formatArgs(value, args);
}
@Override
public void display(Table table) {
table.add(value);
}
}