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.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){
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);
}
}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);
}
}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)};
}
return icon;
public TextureRegion[] getGeneratedIcons(){
if(generatedIcons == null){
generatedIcons = generateIcons();
}
/** 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){
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{