Created test module
This commit is contained in:
73
tools/src/io/anuke/mindustry/BundleLauncher.java
Normal file
73
tools/src/io/anuke/mindustry/BundleLauncher.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.OrderedMap;
|
||||
import com.badlogic.gdx.utils.PropertiesUtils;
|
||||
import io.anuke.ucore.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class BundleLauncher {
|
||||
|
||||
public static void main(String[] args) throws Exception{
|
||||
File file = new File("bundle.properties");
|
||||
OrderedMap<String, String> base = new OrderedMap<>();
|
||||
PropertiesUtils.load(base, new InputStreamReader(new FileInputStream(file)));
|
||||
Array<String> removals = new Array<>();
|
||||
|
||||
Files.walk(Paths.get("")).forEach(child -> {
|
||||
try {
|
||||
if (child.getFileName().toString().equals("bundle.properties") || Files.isDirectory(child) || child.toString().contains("output")) return;
|
||||
|
||||
Log.info("Parsing bundle: {0}", child);
|
||||
|
||||
OrderedMap<String, String> other = new OrderedMap<>();
|
||||
PropertiesUtils.load(other, Files.newBufferedReader(child));
|
||||
removals.clear();
|
||||
|
||||
for(String key : other.orderedKeys()){
|
||||
if(!base.containsKey(key) && !key.contains(".description")){
|
||||
removals.add(key);
|
||||
Log.info("&lr- Removing unused key '{0}'...", key);
|
||||
}
|
||||
}
|
||||
Log.info("&lr{0} keys removed.", removals.size);
|
||||
for(String s : removals){
|
||||
other.remove(s);
|
||||
}
|
||||
|
||||
int added = 0;
|
||||
|
||||
for(String key : base.orderedKeys()){
|
||||
if(!other.containsKey(key)){
|
||||
other.put(key, base.get(key));
|
||||
added ++;
|
||||
Log.info("&lc- Adding missing key '{0}'...", key);
|
||||
}
|
||||
}
|
||||
|
||||
Path output = child.resolveSibling("output/" + child.getFileName());
|
||||
|
||||
Log.info("&lc{0} keys added.", added);
|
||||
Log.info("Writing bundle to {0}", output);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(ObjectMap.Entry<String, String> e : other.entries()){
|
||||
result.append(e.toString().replace("\\", "\\\\").replace("\n", "\\n"));
|
||||
result.append("\n");
|
||||
}
|
||||
Files.write(child, result.toString().getBytes());
|
||||
|
||||
}catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
15
tools/src/io/anuke/mindustry/GenRegion.java
Normal file
15
tools/src/io/anuke/mindustry/GenRegion.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
|
||||
public class GenRegion extends TextureRegion {
|
||||
public String name;
|
||||
public boolean invalid;
|
||||
public ImageContext context;
|
||||
|
||||
public static void validate(TextureRegion region){
|
||||
if(((GenRegion)region).invalid){
|
||||
((GenRegion) region).context.err("Region does not exist: {0}", ((GenRegion)region).name);
|
||||
}
|
||||
}
|
||||
}
|
||||
203
tools/src/io/anuke/mindustry/Generators.java
Normal file
203
tools/src/io/anuke/mindustry/Generators.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.entities.units.UnitType;
|
||||
import io.anuke.mindustry.type.ContentType;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.type.Mech;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.blocks.Floor;
|
||||
import io.anuke.mindustry.world.blocks.OreBlock;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Generators {
|
||||
|
||||
public static void generate(ImageContext context){
|
||||
|
||||
context.generate("block-icons", () -> {
|
||||
for(Block block : content.blocks()){
|
||||
TextureRegion[] regions = block.getBlockIcon();
|
||||
|
||||
if(regions.length == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(block.turretIcon){
|
||||
Color color = Color.ROYAL;
|
||||
|
||||
Image image = context.get(block.name);
|
||||
|
||||
Image read = context.create(image.width(), image.height());
|
||||
read.draw(image);
|
||||
|
||||
for (int x = 0; x < image.width(); x++) {
|
||||
for (int y = 0; y < image.height(); y++) {
|
||||
if(read.isEmpty(x, y) &&
|
||||
(!read.isEmpty(x, y + 1) || !read.isEmpty(x, y - 1) || !read.isEmpty(x + 1, y) || !read.isEmpty(x - 1, y))){
|
||||
image.draw(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image base = context.get("block-" + block.size);
|
||||
Image top = context.get("block-" + block.size + "-top");
|
||||
|
||||
for (int x = 0; x < base.width(); x++) {
|
||||
for (int y = 0; y < base.height(); y++) {
|
||||
Color result = top.getColor(x, y);
|
||||
if(result.a > 0.01f){
|
||||
Hue.mix(result, color, 0.45f, result);
|
||||
base.draw(x, y, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.draw(image);
|
||||
|
||||
base.save("block-icon-" + block.name);
|
||||
}else {
|
||||
|
||||
Image image = context.get(regions[0]);
|
||||
|
||||
for (TextureRegion region : regions) {
|
||||
image.draw(region);
|
||||
}
|
||||
|
||||
image.save("block-icon-" + block.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
context.generate("mech-icons", () -> {
|
||||
for(Mech mech : content.<Mech>getBy(ContentType.mech)){
|
||||
|
||||
mech.load();
|
||||
mech.weapon.load();
|
||||
|
||||
Image image = context.get(mech.region);
|
||||
|
||||
if(!mech.flying){
|
||||
image.drawCenter(mech.baseRegion);
|
||||
image.drawCenter(mech.legRegion);
|
||||
image.drawCenter(mech.legRegion, true, false);
|
||||
image.drawCenter(mech.region);
|
||||
}
|
||||
|
||||
int off = (image.width() - mech.weapon.equipRegion.getRegionWidth())/2;
|
||||
|
||||
image.draw(mech.weapon.equipRegion, -(int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, false, false);
|
||||
image.draw(mech.weapon.equipRegion, (int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, true, false);
|
||||
|
||||
|
||||
image.save("mech-icon-" + mech.name);
|
||||
}
|
||||
});
|
||||
|
||||
context.generate("unit-icons", () -> {
|
||||
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
|
||||
|
||||
type.load();
|
||||
type.weapon.load();
|
||||
|
||||
Image image = context.get(type.region);
|
||||
|
||||
if(!type.isFlying){
|
||||
image.draw(type.baseRegion);
|
||||
image.draw(type.legRegion);
|
||||
image.draw(type.legRegion, true, false);
|
||||
image.draw(type.region);
|
||||
|
||||
image.draw(type.weapon.equipRegion,
|
||||
-(int)type.weaponOffsetX + (image.width() - type.weapon.equipRegion.getRegionWidth())/2,
|
||||
(int)type.weaponOffsetY - (image.height() - type.weapon.equipRegion.getRegionHeight())/2 + 1,
|
||||
false, false);
|
||||
image.draw(type.weapon.equipRegion,
|
||||
(int)type.weaponOffsetX + (image.width() - type.weapon.equipRegion.getRegionWidth())/2,
|
||||
(int)type.weaponOffsetY - (image.height() - type.weapon.equipRegion.getRegionHeight())/2 + 1,
|
||||
true, false);
|
||||
}
|
||||
|
||||
image.save("unit-icon-" + type.name);
|
||||
}
|
||||
});
|
||||
|
||||
context.generate("liquid-icons", () -> {
|
||||
for(Liquid liquid : content.liquids()){
|
||||
Image image = context.get("liquid-icon");
|
||||
for (int x = 0; x < image.width(); x++) {
|
||||
for (int y = 0; y < image.height(); y++) {
|
||||
Color color = image.getColor(x, y);
|
||||
color.mul(liquid.color);
|
||||
image.draw(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
image.save("liquid-icon-" + liquid.name);
|
||||
}
|
||||
});
|
||||
|
||||
context.generate("block-edges", () -> {
|
||||
for(Block block : content.blocks()){
|
||||
if(!(block instanceof Floor)) continue;
|
||||
Floor floor = (Floor)block;
|
||||
if(floor.getIcon().length > 0 && !Draw.hasRegion(floor.name + "-cliff-side")){
|
||||
Image floori = context.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 = context.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
context.generate("ore-icons", () -> {
|
||||
for(Block block : content.blocks()){
|
||||
if(!(block instanceof OreBlock)) continue;
|
||||
|
||||
OreBlock ore = (OreBlock)block;
|
||||
Item item = ore.drops.item;
|
||||
Block base = ore.base;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
//get base image to draw on
|
||||
Image image = context.get(base.name + (i+1));
|
||||
Image shadow = context.get(item.name + (i+1));
|
||||
|
||||
for (int x = 0; x < image.width(); x++) {
|
||||
for (int y = 1; y < image.height(); y++) {
|
||||
Color color = shadow.getColor(x, y - 1);
|
||||
|
||||
//draw semi transparent background
|
||||
if(color.a > 0.001f){
|
||||
color.set(0, 0, 0, 0.3f);
|
||||
image.draw(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image.draw(context.get(item.name + (i+1)));
|
||||
image.save("ore-" + item.name + "-" + base.name + (i+1));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
139
tools/src/io/anuke/mindustry/Image.java
Normal file
139
tools/src/io/anuke/mindustry/Image.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Image {
|
||||
private static ArrayList<Image> toDispose = new ArrayList<>();
|
||||
|
||||
private BufferedImage atlas;
|
||||
|
||||
private BufferedImage image;
|
||||
private Graphics2D graphics;
|
||||
private Color color = new Color();
|
||||
|
||||
public Image(BufferedImage atlas, TextureRegion region){
|
||||
this(atlas, region.getRegionWidth(), region.getRegionHeight());
|
||||
|
||||
draw(region);
|
||||
}
|
||||
|
||||
public Image(BufferedImage atlas, int width, int height){
|
||||
this.atlas = atlas;
|
||||
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.graphics = image.createGraphics();
|
||||
|
||||
toDispose.add(this);
|
||||
}
|
||||
|
||||
public int width(){
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
public int height(){
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
public boolean isEmpty(int x, int y){
|
||||
if(!Mathf.inBounds(x, y, width(), height())){
|
||||
return true;
|
||||
}
|
||||
Color color = getColor(x, y);
|
||||
return color.a <= 0.001f;
|
||||
}
|
||||
|
||||
public Color getColor(int x, int y){
|
||||
int i = image.getRGB(x, y);
|
||||
Color.argb8888ToColor(color, i);
|
||||
return color;
|
||||
}
|
||||
|
||||
public void draw(int x, int y, Color color){
|
||||
graphics.setColor(new java.awt.Color(color.r, color.g, color.b, color.a));
|
||||
graphics.fillRect(x, y, 1, 1);
|
||||
}
|
||||
|
||||
/**Draws a region at the top left corner.*/
|
||||
public void draw(TextureRegion region){
|
||||
draw(region, 0, 0, false, false);
|
||||
}
|
||||
|
||||
/**Draws a region at the center.*/
|
||||
public void drawCenter(TextureRegion region){
|
||||
draw(region, (width() - region.getRegionWidth())/2, (height() - region.getRegionHeight())/2, false, false);
|
||||
}
|
||||
|
||||
/**Draws a region at the center.*/
|
||||
public void drawCenter(TextureRegion region, boolean flipx, boolean flipy){
|
||||
draw(region, (width() - region.getRegionWidth())/2, (height() - region.getRegionHeight())/2, flipx, flipy);
|
||||
}
|
||||
|
||||
/**Draws an image at the top left corner.*/
|
||||
public void draw(Image image){
|
||||
draw(image, 0, 0);
|
||||
}
|
||||
|
||||
/**Draws an image at the coordinates specified.*/
|
||||
public void draw(Image image, int x, int y){
|
||||
graphics.drawImage(image.image, x, y, null);
|
||||
}
|
||||
|
||||
public void draw(TextureRegion region, boolean flipx, boolean flipy){
|
||||
draw(region, 0, 0, flipx, flipy);
|
||||
}
|
||||
|
||||
public void draw(TextureRegion region, int x, int y, boolean flipx, boolean flipy){
|
||||
GenRegion.validate(region);
|
||||
|
||||
int ofx = 0, ofy = 0;
|
||||
|
||||
if(x < 0){
|
||||
ofx = x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(y < 0){
|
||||
ofy = y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
graphics.drawImage(atlas,
|
||||
x, y,
|
||||
x + region.getRegionWidth(),
|
||||
y + region.getRegionHeight(),
|
||||
(flipx ? region.getRegionX() + region.getRegionWidth() : region.getRegionX()) + ofx,
|
||||
(flipy ? region.getRegionY() + region.getRegionHeight() : region.getRegionY()) + ofy,
|
||||
(flipx ? region.getRegionX() : region.getRegionX() + region.getRegionWidth()) + ofx,
|
||||
(flipy ? region.getRegionY() : region.getRegionY() + region.getRegionHeight()) + ofy,
|
||||
null);
|
||||
}
|
||||
|
||||
/** @param name Name of texture file name to create, without any extensions.*/
|
||||
public void save(String name){
|
||||
try {
|
||||
ImageIO.write(image, "png", new File(name + ".png"));
|
||||
}catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static int total(){
|
||||
return toDispose.size();
|
||||
}
|
||||
|
||||
public static void dispose(){
|
||||
for(Image image : toDispose){
|
||||
image.graphics.dispose();
|
||||
}
|
||||
toDispose.clear();
|
||||
}
|
||||
}
|
||||
115
tools/src/io/anuke/mindustry/ImageContext.java
Normal file
115
tools/src/io/anuke/mindustry/ImageContext.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData.Region;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.core.ContentLoader;
|
||||
import io.anuke.ucore.core.Core;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Atlas;
|
||||
import io.anuke.ucore.util.Log;
|
||||
import io.anuke.ucore.util.Log.LogHandler;
|
||||
import io.anuke.ucore.util.Log.NoopLogHandler;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ImageContext {
|
||||
private BufferedImage image;
|
||||
|
||||
public void load() throws IOException{
|
||||
Log.setLogger(new NoopLogHandler());
|
||||
Vars.content = new ContentLoader();
|
||||
Vars.content.load();
|
||||
Log.setLogger(new LogHandler());
|
||||
|
||||
String spritesFolder = new File("../../../assets/sprites").getAbsolutePath();
|
||||
TextureAtlasData data = new TextureAtlasData(new FileHandle(spritesFolder + "/sprites.atlas"),
|
||||
new FileHandle(spritesFolder), false);
|
||||
|
||||
ObjectMap<String, TextureRegion> regionCache = new ObjectMap<>();
|
||||
|
||||
for(Region region : data.getRegions()){
|
||||
int x = region.left, y = region.top, width = region.width, height = region.height;
|
||||
|
||||
regionCache.put(region.name, new GenRegion(){
|
||||
{
|
||||
name = region.name;
|
||||
context = ImageContext.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionX(){
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionY(){
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionWidth(){
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionHeight(){
|
||||
return height;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Core.atlas = new Atlas(){
|
||||
@Override
|
||||
public TextureRegion getRegion(String name){
|
||||
if(!regionCache.containsKey(name)){
|
||||
GenRegion region = new GenRegion();
|
||||
region.name = name;
|
||||
region.context = ImageContext.this;
|
||||
region.invalid = true;
|
||||
return region;
|
||||
}
|
||||
return regionCache.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRegion(String s) {
|
||||
return regionCache.containsKey(s);
|
||||
}
|
||||
};
|
||||
|
||||
Core.atlas.setErrorRegion("error");
|
||||
|
||||
image = ImageIO.read(new File(spritesFolder + "/sprites.png"));
|
||||
}
|
||||
|
||||
public void generate(String name, Runnable run){
|
||||
Timers.mark();
|
||||
run.run();
|
||||
Log.info("&ly[Generator]&lc Time to generate &lm{0}&lc: &lg{1}&lcms", name, Timers.elapsed());
|
||||
}
|
||||
|
||||
public Image create(int width, int height){
|
||||
return new Image(image, width, height);
|
||||
}
|
||||
|
||||
public Image get(String name){
|
||||
return get(Core.atlas.getRegion(name));
|
||||
}
|
||||
|
||||
public Image get(TextureRegion region){
|
||||
GenRegion.validate(region);
|
||||
|
||||
return new Image(image, region);
|
||||
}
|
||||
|
||||
public void err(String message, Object... args){
|
||||
Log.err(message, args);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
21
tools/src/io/anuke/mindustry/PackerLauncher.java
Normal file
21
tools/src/io/anuke/mindustry/PackerLauncher.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PackerLauncher {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Vars.headless = true;
|
||||
ImageContext context = new ImageContext();
|
||||
context.load();
|
||||
Timers.mark();
|
||||
Generators.generate(context);
|
||||
Log.info("&ly[Generator]&lc Total time to generate: &lg{0}&lcms", Timers.elapsed());
|
||||
Log.info("&ly[Generator]&lc Total images created: &lg{0}", Image.total());
|
||||
Image.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user