Block icon rework / Dynamic icon generation / Tech tree tweaks

This commit is contained in:
Anuken 2019-01-19 12:42:02 -05:00
parent 49253964d8
commit 5e951f27c9
45 changed files with 5208 additions and 2006 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 614 KiB

After

Width:  |  Height:  |  Size: 969 KiB

View File

@ -205,7 +205,7 @@ public class BlockIndexer{
for(int x = Math.max(0, tile.x - oreQuadrantSize / 2); x < tile.x + oreQuadrantSize / 2 && x < world.width(); x++){
for(int y = Math.max(0, tile.y - oreQuadrantSize / 2); y < tile.y + oreQuadrantSize / 2 && y < world.height(); y++){
Tile res = world.tile(x, y);
if(res.block() == Blocks.air && res.floor().drops != null && res.floor().drops.item == item){
if(res.block() == Blocks.air && res.floor().itemDrop == item){
return res;
}
}
@ -243,9 +243,9 @@ public class BlockIndexer{
for(int x = quadrantX * structQuadrantSize; x < world.width() && x < (quadrantX + 1) * structQuadrantSize; x++){
for(int y = quadrantY * structQuadrantSize; y < world.height() && y < (quadrantY + 1) * structQuadrantSize; y++){
Tile result = world.tile(x, y);
if( result == null || result.block().drops == null || !scanOres.contains(result.block().drops.item)) continue;
if( result == null || result.floor().itemDrop == null || !scanOres.contains(result.floor().itemDrop)) continue;
itemSet.add(result.block().drops.item);
itemSet.add(result.floor().itemDrop);
}
}
@ -322,8 +322,8 @@ public class BlockIndexer{
Tile tile = world.tile(x, y);
//add position of quadrant to list when an ore is found
if(tile.floor().drops != null && scanOres.contains(tile.floor().drops.item) && tile.block() == Blocks.air){
ores.get(tile.floor().drops.item).add(world.tile(
if(tile.floor().itemDrop != null && scanOres.contains(tile.floor().itemDrop) && tile.block() == Blocks.air){
ores.get(tile.floor().itemDrop).add(world.tile(
//make sure to clamp quadrant middle position, since it might go off bounds
Mathf.clamp(qx * oreQuadrantSize + oreQuadrantSize / 2, 0, world.width() - 1),
Mathf.clamp(qy * oreQuadrantSize + oreQuadrantSize / 2, 0, world.height() - 1)));

View File

@ -166,7 +166,7 @@ public class Blocks implements ContentList{
}};
sand = new Floor("sand"){{
drops = new ItemStack(Items.sand, 1);
itemDrop = Items.sand;
minimapColor = Color.valueOf("988a67");
hasOres = true;
playerUnmineable = true;

View File

@ -5,7 +5,7 @@ import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.Liquid;
public class Liquids implements ContentList{
public static Liquid water, slag, oil, cryofluid, acid;
public static Liquid water, slag, oil, cryofluid;
@Override
public void load(){
@ -38,10 +38,5 @@ public class Liquids implements ContentList{
tier = 1;
effect = StatusEffects.freezing;
}};
acid = new Liquid("acid", Color.valueOf("e9f9b3")){{
heatCapacity = 0.1f; //don't use acid as coolant, it's bad
effect = StatusEffects.corroded;
}};
}
}

View File

@ -1,8 +1,8 @@
package io.anuke.mindustry.content;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.ContentList;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import static io.anuke.mindustry.type.ItemStack.with;
@ -11,7 +11,7 @@ public class TechTree implements ContentList{
@Override
public void load(){
root = new TechNode(Items.copper, with(),
root = new TechNode(null, with(),
new TechNode(Blocks.copperWall, with(Items.copper, 100),
new TechNode(Blocks.copperWallLarge, with(Items.copper, 100))
),
@ -26,26 +26,23 @@ public class TechTree implements ContentList{
new TechNode(Blocks.itemBridge, with(Items.copper, 10))
),
new TechNode(Items.lead, with(),
new TechNode(Items.metaglass, with(),
new TechNode(Blocks.conduit, with(Items.metaglass, 10)),
new TechNode(Blocks.liquidJunction, with(Items.metaglass, 10)),
new TechNode(Blocks.liquidRouter, with(Items.metaglass, 10),
new TechNode(Blocks.liquidTank, with(Items.metaglass, 10))
)
new TechNode(Blocks.conduit, with(Items.metaglass, 10),
new TechNode(Blocks.liquidJunction, with(Items.metaglass, 10)),
new TechNode(Blocks.liquidRouter, with(Items.metaglass, 10),
new TechNode(Blocks.liquidTank, with(Items.metaglass, 10))
)
)
);
}
public static class TechNode{
public final Content content;
public final Block block;
public final ItemStack[] requirements;
public final TechNode[] children;
public TechNode parent;
TechNode(Content content, ItemStack[] requirements, TechNode... children){
this.content = content;
TechNode(Block block, ItemStack[] requirements, TechNode... children){
this.block = block;
this.requirements = requirements;
this.children = children;
for(TechNode node : children){

View File

@ -11,8 +11,8 @@ import io.anuke.arc.input.KeyCode;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.scene.actions.Actions;
import io.anuke.arc.scene.style.TextureRegionDrawable;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.layout.Stack;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.scene.ui.layout.Unit;
import io.anuke.arc.scene.utils.UIUtils;
@ -26,6 +26,7 @@ import io.anuke.mindustry.maps.MapMeta;
import io.anuke.mindustry.maps.MapTileData;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import java.io.DataInputStream;
import java.io.InputStream;
@ -498,20 +499,14 @@ public class MapEditorDialog extends Dialog implements Disposable{
int i = 0;
for(Block block : Vars.content.blocks()){
TextureRegion[] regions = block.getCompactIcon();
TextureRegion region = block.icon(Icon.medium);
if(regions.length == 0 || regions[0] == Core.atlas.find("jjfgj")) continue;
Stack stack = new Stack();
for(TextureRegion region : regions){
stack.add(new Image(region));
}
if(region == Core.atlas.find("jjfgj")) continue;
ImageButton button = new ImageButton("white", "clear-toggle");
button.getStyle().imageUp = new TextureRegionDrawable(region);
button.clicked(() -> editor.setDrawBlock(block));
button.resizeImage(8 * 4f);
button.replaceImage(stack);
button.update(() -> button.setChecked(editor.getDrawBlock() == block));
group.add(button);
content.add(button).size(50f);

View File

@ -12,6 +12,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.IndexedRenderer;
import io.anuke.mindustry.maps.MapTileData.DataPosition;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.tilesize;
@ -111,7 +112,7 @@ public class MapRenderer implements Disposable{
TextureRegion region;
if(bw != 0){
region = wall.getEditorIcon();
region = wall.icon(Icon.full);
if(wall.rotate){
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
@ -124,7 +125,7 @@ public class MapRenderer implements Disposable{
region.getWidth() * Draw.scl, region.getHeight() * Draw.scl);
}
}else{
region = floor.getEditorIcon();
region = floor.icon(Icon.full);
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
}

View File

@ -33,6 +33,7 @@ import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
@ -472,7 +473,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
Draw.color();
Draw.rect(request.recipe.result.getEditorIcon(),
Draw.rect(request.recipe.result.icon(Icon.full),
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(), rad*2, rad*2, request.rotation * 90);

View File

@ -264,10 +264,10 @@ public interface BuilderTrait extends Entity{
TileEntity core = unit.getClosestCore();
if(core == null || tile.block() != Blocks.air || unit.dst(tile.worldx(), tile.worldy()) > mineDistance
|| tile.floor().drops == null || !unit.inventory.canAcceptItem(tile.floor().drops.item) || !canMine(tile.floor().drops.item)){
|| tile.floor().itemDrop == null || !unit.inventory.canAcceptItem(tile.floor().itemDrop) || !canMine(tile.floor().itemDrop)){
setMineTile(null);
}else{
Item item = tile.floor().drops.item;
Item item = tile.floor().itemDrop;
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f);
if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){

View File

@ -1,5 +1,6 @@
package io.anuke.mindustry.graphics;
//TODO implement effects again
public enum CacheLayer{
water{
},
@ -9,7 +10,9 @@ public enum CacheLayer{
},
space{
},
normal;
normal,
walls{ //TODO implement walls
};
public void begin(){

View File

@ -15,6 +15,7 @@ import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult;
import io.anuke.mindustry.input.PlaceUtils.NormalizeResult;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*;
@ -45,13 +46,10 @@ public class DesktopInput extends InputHandler{
if(validPlace(x, y, block, rotation)){
Draw.color();
TextureRegion[] regions = block.getBlockIcon();
for(TextureRegion region : regions){
Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(),
region.getWidth() * selectScale * Draw.scl,
region.getHeight() * selectScale * Draw.scl, block.rotate ? rotation * 90 : 0);
}
TextureRegion region = block.icon(Icon.full);
Draw.rect(region, x * tilesize + block.offset(), y * tilesize + block.offset(),
region.getWidth() * selectScale * Draw.scl,
region.getHeight() * selectScale * Draw.scl, block.rotate ? rotation * 90 : 0);
}else{
Draw.color(Palette.removeBack);
Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f);

View File

@ -231,9 +231,9 @@ public abstract class InputHandler implements InputProcessor{
boolean canMine(Tile tile){
return !Core.scene.hasMouse()
&& tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower
&& tile.floor().itemDrop != null && tile.floor().itemDrop.hardness <= player.mech.drillPower
&& !tile.floor().playerUnmineable
&& player.inventory.canAcceptItem(tile.floor().drops.item)
&& player.inventory.canAcceptItem(tile.floor().itemDrop)
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= Player.mineDistance;
}

View File

@ -33,6 +33,7 @@ import io.anuke.mindustry.input.PlaceUtils.NormalizeResult;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*;
@ -171,17 +172,15 @@ public class MobileInput extends InputHandler implements GestureListener{
if(!request.remove){
//draw placing request
float offset = request.recipe.result.offset();
TextureRegion[] regions = request.recipe.result.getBlockIcon();
TextureRegion region = request.recipe.result.icon(Icon.full);
Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f));
Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness);
for(TextureRegion region : regions){
Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset,
region.getWidth() * request.scale * Draw.scl,
region.getHeight() * request.scale * Draw.scl,
request.recipe.result.rotate ? request.rotation * 90 : 0);
}
Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset,
region.getWidth() * request.scale * Draw.scl,
region.getHeight() * request.scale * Draw.scl,
request.recipe.result.rotate ? request.rotation * 90 : 0);
}else{
float rad = (tile.block().size * tilesize / 2f - 1) * request.scale;
Draw.alpha(0f);
@ -343,14 +342,12 @@ public class MobileInput extends InputHandler implements GestureListener{
if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){
Draw.color();
TextureRegion[] regions = recipe.result.getBlockIcon();
TextureRegion region = recipe.result.icon(Icon.full);
for(TextureRegion region : regions){
Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(),
region.getWidth() * lineScale * Draw.scl,
region.getHeight() * lineScale * Draw.scl,
recipe.result.rotate ? result.rotation * 90 : 0);
}
Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(),
region.getWidth() * lineScale * Draw.scl,
region.getHeight() * lineScale * Draw.scl,
recipe.result.rotate ? result.rotation * 90 : 0);
}else{
Draw.color(Palette.removeBack);
Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset() - 1, recipe.result.size * tilesize / 2f);

View File

@ -12,6 +12,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.ui.ContentDisplay;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.ContentStatValue;
import io.anuke.mindustry.world.meta.StatValue;
@ -102,7 +103,7 @@ public class Recipe extends UnlockableContent{
@Override
public TextureRegion getContentIcon(){
return result.getEditorIcon();
return result.icon(Icon.large);
}
@Override

View File

@ -12,6 +12,7 @@ import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.BlockStats;
import io.anuke.mindustry.world.meta.StatCategory;
@ -25,7 +26,7 @@ public class ContentDisplay{
table.table(title -> {
int size = 8 * 6;
title.addImage(Core.atlas.find("block-icon-" + block.name)).size(size);
title.addImage(recipe.result.icon(Icon.large)).size(size);
title.add("[accent]" + block.formalName).padLeft(5);
});

View File

@ -1,14 +0,0 @@
package io.anuke.mindustry.ui;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.scene.ui.Image;
import io.anuke.arc.scene.ui.layout.Stack;
public class ImageStack extends Stack{
public ImageStack(TextureRegion... regions){
for(TextureRegion region : regions){
add(new Image(region));
}
}
}

View File

@ -11,14 +11,16 @@ import io.anuke.arc.math.geom.Rectangle;
import io.anuke.arc.scene.Element;
import io.anuke.arc.scene.event.InputEvent;
import io.anuke.arc.scene.event.InputListener;
import io.anuke.arc.util.Log;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.TechTree;
import io.anuke.mindustry.content.TechTree.TechNode;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Recipe.RecipeVisibility;
import io.anuke.mindustry.ui.TreeLayout;
import io.anuke.mindustry.ui.TreeLayout.TreeNode;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
public class TechTreeDialog extends FloatingDialog{
private TreeLayout layout;
@ -31,9 +33,11 @@ public class TechTreeDialog extends FloatingDialog{
layout.gapBetweenLevels = 60f;
layout.gapBetweenNodes = 40f;
layout.layout(new TechTreeNode(TechTree.root, null));
cont.add(new View()).grow();
double total = Vars.content.recipes().count(r -> r.visibility == RecipeVisibility.all);
if(total > nodes.size) Log.err("Recipe tree coverage: {0}%", (int)(nodes.size / total * 100));
addCloseButton();
}
@ -95,10 +99,8 @@ public class TechTreeDialog extends FloatingDialog{
for(TechTreeNode node : nodes){
Draw.drawable("content-background", node.x + offsetX - node.width/2f, node.y + offsetY - node.height/2f, node.width, node.height);
Content content = node.node.content;
TextureRegion region = content instanceof Block ? ((Block)content).getEditorIcon() :
((UnlockableContent)content).getContentIcon();
Draw.rect(region, node.x + offsetX, node.y + offsetY, 8*3, 8*3);
TextureRegion region = node.node.block == null ? Blocks.core.icon(Icon.medium) : node.node.block.icon(Icon.medium);
Draw.rect(region, node.x + offsetX, node.y + offsetY - 0.5f, region.getWidth(), region.getHeight());
}
ScissorStack.popScissors();

View File

@ -23,8 +23,8 @@ 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.ImageStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
@ -144,7 +144,7 @@ public class PlacementFragment extends Fragment{
if(!ulock){
button.replaceImage(new Image("icon-locked"));
}else{
button.replaceImage(new ImageStack(recipe.result.getCompactIcon()));
button.replaceImage(new Image(recipe.result.icon(Icon.medium)));
}
});
@ -174,7 +174,7 @@ public class PlacementFragment extends Fragment{
if(lastDisplay != null){ //show selected recipe
topTable.table(header -> {
header.left();
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8 * 4);
header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4);
header.labelWrap(() ->
!data.isUnlocked(Recipe.getByResult(lastDisplay)) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5);
@ -210,7 +210,7 @@ public class PlacementFragment extends Fragment{
}else if(tileDisplayBlock() != null){ //show selected tile
lastDisplay = tileDisplayBlock();
topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
topTable.add(new Image(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
topTable.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5);
}
});

View File

@ -27,7 +27,6 @@ import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.consumers.ConsumePower;
import io.anuke.mindustry.world.meta.*;
@ -58,10 +57,8 @@ public class Block extends BaseBlock {
public int health = -1;
/** base block explosiveness */
public float baseExplosiveness = 0f;
/** whether this block can be placed on liquids. */
/** whether this block can be placed on edges of liquids. */
public boolean floating = false;
/** stuff that drops when broken */
public ItemStack drops = null;
/** multiblock size */
public int size = 1;
/** Whether to draw this block in the expanded draw range. */
@ -84,28 +81,21 @@ public class Block extends BaseBlock {
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. */
public boolean autoSleep;
/** Whether the block can be tapped and selected to configure. */
public boolean configurable;
/** Whether this block consumes touchDown events when tapped. */
public boolean consumesTap;
/** The color of this block when displayed on the minimap or map preview. */
public Color minimapColor = Color.CLEAR;
/**Whether the top icon is outlined, like a turret.*/
public boolean turretIcon = false;
/**Whether units target this block.*/
public boolean targetable = true;
/**Whether the overdrive core has any effect on this block.*/
public boolean canOverdrive = true;
protected Array<Tile> tempTiles = new Array<>();
protected TextureRegion[] blockIcon;
protected TextureRegion[] icon;
protected TextureRegion[] compactIcon;
protected TextureRegion editorIcon;
public TextureRegion region;
protected TextureRegion[] icons = new TextureRegion[Icon.values().length];
protected TextureRegion[] generatedIcons;
protected TextureRegion region;
public Block(String name){
this.name = name;
@ -128,10 +118,6 @@ public class Block extends BaseBlock {
return true;
}
public boolean dropsItem(Item item){
return drops != null && drops.item == item;
}
public void onProximityRemoved(Tile tile){
if(tile.entity.power != null){
tile.block().powerGraphRemoved(tile);
@ -443,55 +429,25 @@ public class Block extends BaseBlock {
}
public TextureRegion getDisplayIcon(Tile tile){
return getEditorIcon();
return icon(Icon.medium);
}
public TextureRegion getEditorIcon(){
if(editorIcon == null){
editorIcon = Core.atlas.find("block-icon-" + name, Core.atlas.find("clear"));
public TextureRegion icon(Icon icon){
if(icons[icon.ordinal()] == null){
icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name());
}
return editorIcon;
return icons[icon.ordinal()];
}
/** Returns the icon used for displaying this block in the place menu */
public TextureRegion[] getIcon(){
if(icon == null){
if(Core.atlas.has(name + "-icon")){
icon = new TextureRegion[]{Core.atlas.find(name + "-icon")};
}else if(Core.atlas.has(name)){
icon = new TextureRegion[]{Core.atlas.find(name)};
}else if(Core.atlas.has(name + "1")){
icon = new TextureRegion[]{Core.atlas.find(name + "1")};
}else{
icon = new TextureRegion[]{};
}
protected TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name)};
}
public TextureRegion[] getGeneratedIcons(){
if(generatedIcons == null){
generatedIcons = generateIcons();
}
return icon;
}
/** Returns a list of regions that represent this block in the world */
public TextureRegion[] getBlockIcon(){
return getIcon();
}
/** Returns a list of icon regions that have been cropped to 8x8 */
public TextureRegion[] getCompactIcon(){
if(compactIcon == null){
compactIcon = new TextureRegion[getIcon().length];
for(int i = 0; i < compactIcon.length; i++){
compactIcon[i] = iconRegion(getIcon()[i]);
}
}
return compactIcon;
}
/** Crops a regionto 8x8 */
protected TextureRegion iconRegion(TextureRegion src){
TextureRegion region = new TextureRegion(src);
region.setWidth((int)(8 / Draw.scl));
region.setHeight((int)(8 / Draw.scl));
return region;
return generatedIcons;
}
public boolean hasEntity(){
@ -533,4 +489,18 @@ public class Block extends BaseBlock {
"entity.graph", tile.entity.power != null && tile.entity.power.graph != null ? tile.entity.power.graph.getID() : null
);
}
public enum Icon{
small(8 * 3),
medium(8 * 4),
large(8 * 6),
/**uses whatever the size of the block is*/
full(0);
public final int size;
Icon(int size){
this.size = size;
}
}
}

View File

@ -80,7 +80,7 @@ public class BuildBlock extends Block{
@Override
public TextureRegion getDisplayIcon(Tile tile){
BuildEntity entity = tile.entity();
return (entity.recipe == null ? entity.previous : entity.recipe.result).getEditorIcon();
return (entity.recipe == null ? entity.previous : entity.recipe.result).icon(Icon.full);
}
@Override
@ -125,9 +125,7 @@ public class BuildBlock extends Block{
if(entity.previous == null) return;
for(TextureRegion region : entity.previous.getBlockIcon()){
Draw.rect(region, tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0);
}
Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0);
}
@Override
@ -141,7 +139,7 @@ public class BuildBlock extends Block{
if(target == null) return;
for(TextureRegion region : target.getBlockIcon()){
for(TextureRegion region : target.getGeneratedIcons()){
Shaders.blockbuild.region = region;
Shaders.blockbuild.progress = entity.progress;

View File

@ -11,6 +11,7 @@ import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.type.StatusEffect;
import io.anuke.mindustry.world.Block;
@ -43,11 +44,13 @@ public class Floor extends Block{
public Color liquidColor;
/** liquids that drop from this block, used for pumps */
public Liquid liquidDrop = null;
/** item that drops from this block, used for drills */
public Item itemDrop = null;
/** Whether ores generate on this block. */
public boolean hasOres = false;
/** whether this block can be drowned in */
public boolean isLiquid;
/** if true, this block cannot be mined by players. useful for annoying things like stone. */
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
public boolean playerUnmineable = false;
protected TextureRegion edgeRegion;
protected TextureRegion[] edgeRegions;
@ -125,29 +128,12 @@ public class Floor extends Block{
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
/*
if(tile.hasCliffs() && cliffRegions != null){
for(int i = 0; i < 4; i++){
if((tile.getCliffs() & (1 << i * 2)) != 0){
Draw.colorl(i > 1 ? 0.6f : 1f);
//drawEdges(tile, false);
}
boolean above = (tile.getCliffs() & (1 << ((i + 1) % 4) * 2)) != 0, below = (tile.getCliffs() & (1 << (Mathf.mod(i - 1, 4)) * 2)) != 0;
if(above && below){
Draw.rect(cliffRegions[0], tile.worldx(), tile.worldy(), i * 90);
}else if(above){
Draw.rect(cliffRegions[1], tile.worldx(), tile.worldy(), i * 90);
}else if(below){
Draw.rect(cliffRegions[2], tile.worldx(), tile.worldy(), i * 90);
}else{
Draw.rect(cliffRegions[3], tile.worldx(), tile.worldy(), i * 90);
}
}
}
}
Draw.reset();
drawEdges(tile, false);*/
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")};
}
public boolean blendOverride(Block block){

View File

@ -30,7 +30,7 @@ public class LiquidBlock extends Block{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name() + "-bottom"), Core.atlas.find(name() + "-top")};
}

View File

@ -2,10 +2,8 @@ package io.anuke.mindustry.world.blocks;
import io.anuke.arc.collection.ObjectMap;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
@ -17,7 +15,7 @@ public class OreBlock extends Floor{
public OreBlock(Item ore, Floor base){
super("ore-" + ore.name + "-" + base.name);
this.formalName = ore.localizedName() + " " + base.formalName;
this.drops = new ItemStack(ore, 1);
this.itemDrop = ore;
this.base = base;
this.variants = 3;
this.minimapColor = ore.color;
@ -28,15 +26,7 @@ public class OreBlock extends Floor{
@Override
public String getDisplayName(Tile tile){
return drops.item.localizedName();
}
@Override
public TextureRegion getEditorIcon(){
if(editorIcon == null){
editorIcon = variantRegions[0];
}
return editorIcon;
return itemDrop.localizedName();
}
@Override

View File

@ -28,6 +28,11 @@ public class Rock extends Block{
Draw.color();
}
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "1")};
}
@Override
public void load(){
super.load();

View File

@ -83,7 +83,6 @@ public abstract class Turret extends Block{
solid = true;
layer = Layer.turret;
group = BlockGroup.turrets;
turretIcon = true;
flags = EnumSet.of(BlockFlag.turret);
}
@ -133,19 +132,8 @@ public abstract class Turret extends Block{
}
@Override
public TextureRegion[] getBlockIcon(){
if(blockIcon == null){
blockIcon = new TextureRegion[]{Core.atlas.find("block-icon-" + name)};
}
return blockIcon;
}
@Override
public TextureRegion[] getCompactIcon(){
if(compactIcon == null){
compactIcon = new TextureRegion[]{iconRegion(Core.atlas.find("block-icon-" + name))};
}
return compactIcon;
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find("block-" + size), Core.atlas.find(name)};
}
@Override

View File

@ -101,11 +101,8 @@ public class Conduit extends LiquidBlock{
}
@Override
public TextureRegion[] getIcon(){
if(icon == null){
icon = new TextureRegion[]{Core.atlas.find("conduit-bottom"), Core.atlas.find(name + "-top-0")};
}
return icon;
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find("conduit-bottom"), Core.atlas.find(name + "-top-0")};
}
@Override

View File

@ -48,7 +48,6 @@ public class Conveyor extends Block{
layer = Layer.overlay;
group = BlockGroup.transportation;
hasItems = true;
autoSleep = true;
itemCapacity = 4;
}
@ -122,11 +121,8 @@ public class Conveyor extends Block{
}
@Override
public TextureRegion[] getIcon(){
if(icon == null){
icon = new TextureRegion[]{Core.atlas.find(name + "-0-0")};
}
return super.getIcon();
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "-0-0")};
}
@Override

View File

@ -27,7 +27,7 @@ public class LiquidJunction extends LiquidBlock{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name)};
}

View File

@ -109,11 +109,8 @@ public class MassDriver extends Block{
}
@Override
public TextureRegion[] getBlockIcon(){
if(blockIcon == null){
blockIcon = new TextureRegion[]{region, turretRegion};
}
return super.getBlockIcon();
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-turret")};
}
@Override

View File

@ -96,7 +96,7 @@ public class FusionReactor extends PowerGenerator{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name), Core.atlas.find(name + "-top")};
}

View File

@ -43,7 +43,7 @@ public class Compressor extends PowerCrafter{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
}
}

View File

@ -92,7 +92,7 @@ public class Cultivator extends Drill{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top"),};
}

View File

@ -11,12 +11,11 @@ import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.consumers.ConsumeLiquid;
@ -114,7 +113,7 @@ public class Drill extends Block{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")};
}
@ -239,13 +238,13 @@ public class Drill extends Block{
}
public Item getDrop(Tile tile){
return tile.floor().drops.item;
return tile.floor().itemDrop;
}
public boolean isValid(Tile tile){
if(tile == null) return false;
ItemStack drops = tile.floor().drops;
return drops != null && drops.item.hardness <= tier;
Item drops = tile.floor().itemDrop;
return drops != null && drops.hardness <= tier;
}
public static class DrillEntity extends TileEntity{

View File

@ -48,7 +48,7 @@ public class Fracker extends SolidPump{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")};
}

View File

@ -1,7 +1,10 @@
package io.anuke.mindustry.world.blocks.production;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Item;
@ -10,11 +13,6 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.consumers.ConsumeItem;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.arc.entities.Effects;
import io.anuke.arc.entities.Effects.Effect;
import io.anuke.arc.util.Time;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
@ -62,11 +60,6 @@ public class GenericCrafter extends Block{
Draw.color();
}
@Override
public TextureRegion[] getIcon(){
return new TextureRegion[]{Core.atlas.find(name)};
}
@Override
public void update(Tile tile){
GenericCrafterEntity entity = tile.entity();

View File

@ -27,11 +27,8 @@ public class PhaseWeaver extends PowerSmelter{
}
@Override
public TextureRegion[] getIcon(){
if(icon == null){
icon = new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)};
}
return icon;
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name)};
}
@Override

View File

@ -29,7 +29,7 @@ public class Pulverizer extends GenericCrafter{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator")};
}
}

View File

@ -56,7 +56,7 @@ public class Pump extends LiquidBlock{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name)};
}

View File

@ -56,7 +56,7 @@ public class SolidPump extends Pump{
}
@Override
public TextureRegion[] getIcon(){
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator"), Core.atlas.find(name + "-top")};
}

View File

@ -94,11 +94,8 @@ public class UnitFactory extends Block{
}
@Override
public TextureRegion[] getIcon(){
return new TextureRegion[]{
Core.atlas.find(name),
Core.atlas.find(name + "-top")
};
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
}
@Override

View File

@ -157,6 +157,14 @@ task scaleSprites4x(){
task scaleSprites(){
finalizedBy 'genSprites'
doLast{
copy{
from "../core/assets-raw/sprites_replacement/"
into "../core/assets-raw/sprites_out/"
}
}
dependsOn 'scaleSprites4x'
}
@ -166,11 +174,6 @@ task pack(){
doLast{
copy{
from "../core/assets-raw/sprites_replacement/"
into "../core/assets-raw/sprites_out/"
}
fileTree(dir: '../core/assets-raw/sprites_out/', include: "**/*.png").visit{ file ->
if(file.isDirectory() || file.toString().contains("/ui/")) return

View File

@ -1,14 +1,14 @@
package io.anuke.mindustry;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.util.Log;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.type.ContentType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.blocks.OreBlock;
import static io.anuke.mindustry.Vars.content;
@ -20,33 +20,31 @@ public class Generators {
ImagePacker.generate("block-icons", () -> {
for(Block block : content.blocks()){
TextureRegion[] regions = block.getBlockIcon();
TextureRegion[] regions = block.getGeneratedIcons();
if(regions.length == 0){
continue;
}
if(block.turretIcon){
Image image = ImagePacker.get(block.name);
Image read = ImagePacker.create(image.width(), image.height());
read.draw(image);
Image base = ImagePacker.get("block-" + block.size);
base.draw(image);
base.save("block-icon-" + block.name);
}else {
try{
Image image = ImagePacker.get(regions[0]);
for (TextureRegion region : regions) {
for(TextureRegion region : regions){
image.draw(region);
}
image.save("block-icon-" + block.name);
image.save(block.name + "-icon-full");
for(Icon icon : Icon.values()){
if(icon.size == 0) continue;
Image scaled = new Image(icon.size, icon.size);
scaled.drawScaled(image);
scaled.save(block.name + "-icon-" + icon.name());
}
}catch(IllegalArgumentException e){
Log.info("Skipping &ly'{0}'", block.name);
}catch(NullPointerException e){
Log.err("Block &ly'{0}'&lr has an null region!");
}
}
});
@ -104,39 +102,12 @@ public class Generators {
}
});
ImagePacker.generate("block-edges", () -> {
for(Block block : content.blocks()){
if(!(block instanceof Floor)) continue;
Floor floor = (Floor)block;
if(floor.getIcon().length > 0 && !Core.atlas.has(floor.name + "-cliff-side")){
Image floori = ImagePacker.get(floor.getIcon()[0]);
Color color = floori.getColor(0, 0).mul(1.3f, 1.3f, 1.3f, 1f);
String[] names = {"cliff-edge-2", "cliff-edge", "cliff-edge-1", "cliff-side"};
for(String str : names){
Image image = ImagePacker.get("generic-" + str);
for(int x = 0; x < image.width(); x++){
for(int y = 0; y < image.height(); y++){
Color other = image.getColor(x, y);
if(other.a > 0){
image.draw(x, y, color);
}
}
}
image.save(floor.name + "-" + str);
}
}
}
});
ImagePacker.generate("ore-icons", () -> {
for(Block block : content.blocks()){
if(!(block instanceof OreBlock)) continue;
OreBlock ore = (OreBlock)block;
Item item = ore.drops.item;
Item item = ore.itemDrop;
Block base = ore.base;
for (int i = 0; i < 3; i++) {
@ -160,8 +131,16 @@ public class Generators {
image.draw(ImagePacker.get(item.name + (i+1)));
image.save("ore-" + item.name + "-" + base.name + (i+1));
}
//save icons
image.save(block.name + "-icon-full");
for(Icon icon : Icon.values()){
if(icon.size == 0) continue;
Image scaled = new Image(icon.size, icon.size);
scaled.drawScaled(image);
scaled.save(block.name + "-icon-" + icon.name());
}
}
}
});
}

View File

@ -77,6 +77,11 @@ class Image {
draw(region, (width() - region.getWidth())/2, (height() - region.getHeight())/2, flipx, flipy);
}
void drawScaled(Image image){
//graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.drawImage(image.image.getScaledInstance(width(), height(), java.awt.Image.SCALE_AREA_AVERAGING), 0, 0, width(), height(), null);
}
/**Draws an image at the top left corner.*/
void draw(Image image){
draw(image, 0, 0);

View File

@ -8,6 +8,7 @@ import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Log.LogHandler;
import io.anuke.arc.util.Log.NoopLogHandler;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.core.ContentLoader;
@ -117,8 +118,7 @@ public class ImagePacker{
}
static void err(String message, Object... args){
Log.err(message, args);
System.exit(-1);
throw new IllegalArgumentException(Strings.formatArgs(message, args));
}
static class GenRegion extends AtlasRegion{