it is done
This commit is contained in:
66
tools/src/mindustry/tools/BundleLauncher.java
Normal file
66
tools/src/mindustry/tools/BundleLauncher.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.files.*;
|
||||
import arc.func.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
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<>();
|
||||
Fi.get("").walk(child -> {
|
||||
if(child.name().equals("bundle.properties") || child.isDirectory() || child.toString().contains("output"))
|
||||
return;
|
||||
|
||||
Log.info("Parsing bundle: {0}", child);
|
||||
|
||||
OrderedMap<String, String> other = new OrderedMap<>();
|
||||
PropertiesUtils.load(other, child.reader(2048, "UTF-8"));
|
||||
removals.clear();
|
||||
|
||||
for(String key : other.orderedKeys()){
|
||||
if(!base.containsKey(key)){
|
||||
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.get(key).trim().isEmpty()){
|
||||
other.put(key, base.get(key));
|
||||
added++;
|
||||
Log.info("&lc- Adding missing key '{0}'...", key);
|
||||
}
|
||||
}
|
||||
|
||||
Func2<String, String, String> processor = (key, value) -> (key + " = " + value).replace("\\", "\\\\").replace("\n", "\\n") + "\n";
|
||||
Fi output = child.sibling("output/" + child.name());
|
||||
|
||||
Log.info("&lc{0} keys added.", added);
|
||||
Log.info("Writing bundle to {0}", output);
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
//add everything ordered
|
||||
for(String key : base.orderedKeys()){
|
||||
result.append(processor.get(key, other.get(key)));
|
||||
other.remove(key);
|
||||
}
|
||||
|
||||
child.writeString(result.toString());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
293
tools/src/mindustry/tools/Generators.java
Normal file
293
tools/src/mindustry/tools/Generators.java
Normal file
@@ -0,0 +1,293 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.files.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import arc.util.noise.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.tools.ImagePacker.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Generators{
|
||||
|
||||
public static void generate(){
|
||||
|
||||
ImagePacker.generate("cracks", () -> {
|
||||
RidgedPerlin r = new RidgedPerlin(1, 3);
|
||||
for(int size = 1; size <= Block.maxCrackSize; size++){
|
||||
int dim = size * 32;
|
||||
int steps = Block.crackRegions;
|
||||
for(int i = 0; i < steps; i++){
|
||||
float fract = i / (float)steps;
|
||||
|
||||
Image image = new Image(dim, dim);
|
||||
for(int x = 0; x < dim; x++){
|
||||
for(int y = 0; y < dim; y++){
|
||||
float dst = Mathf.dst((float)x/dim, (float)y/dim, 0.5f, 0.5f) * 2f;
|
||||
if(dst < 1.2f && r.getValue(x, y, 1f / 40f) - dst*(1f-fract) > 0.16f){
|
||||
image.draw(x, y, Color.white);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image output = new Image(image.width, image.height);
|
||||
int rad = 3;
|
||||
|
||||
//median filter
|
||||
for(int x = 0; x < output.width; x++){
|
||||
for(int y = 0; y < output.height; y++){
|
||||
int whites = 0, clears = 0;
|
||||
for(int cx = -rad; cx < rad; cx++){
|
||||
for(int cy = -rad; cy < rad; cy++){
|
||||
int wx = Mathf.clamp(cx + x, 0, output.width - 1), wy = Mathf.clamp(cy + y, 0, output.height - 1);
|
||||
Color color = image.getColor(wx, wy);
|
||||
if(color.a > 0.5f){
|
||||
whites ++;
|
||||
}else{
|
||||
clears ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
output.draw(x, y, whites >= clears ? Color.white : Color.clear);
|
||||
}
|
||||
}
|
||||
|
||||
output.save("cracks-" + size + "-" + i);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("block-icons", () -> {
|
||||
Image colors = new Image(content.blocks().size, 1);
|
||||
|
||||
for(Block block : content.blocks()){
|
||||
TextureRegion[] regions = block.getGeneratedIcons();
|
||||
|
||||
if(block instanceof Floor){
|
||||
block.load();
|
||||
for(TextureRegion region : block.variantRegions()){
|
||||
GenRegion gen = (GenRegion)region;
|
||||
if(gen.path == null) continue;
|
||||
gen.path.copyTo(Fi.get("../editor/editor-" + gen.path.name()));
|
||||
}
|
||||
}
|
||||
|
||||
if(regions.length == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
try{
|
||||
Image last = null;
|
||||
if(block.outlineIcon){
|
||||
int radius = 4;
|
||||
GenRegion region = (GenRegion)regions[regions.length - 1];
|
||||
Image base = ImagePacker.get(region);
|
||||
Image out = last = new Image(region.getWidth(), region.getHeight());
|
||||
for(int x = 0; x < out.width; x++){
|
||||
for(int y = 0; y < out.height; y++){
|
||||
|
||||
Color color = base.getColor(x, y);
|
||||
out.draw(x, y, color);
|
||||
if(color.a < 1f){
|
||||
boolean found = false;
|
||||
outer:
|
||||
for(int rx = -radius; rx <= radius; rx++){
|
||||
for(int ry = -radius; ry <= radius; ry++){
|
||||
if(Mathf.dst(rx, ry) <= radius && base.getColor(rx + x, ry + y).a > 0.01f){
|
||||
found = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
out.draw(x, y, block.outlineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
region.path.delete();
|
||||
|
||||
out.save(block.name);
|
||||
}
|
||||
|
||||
Image image = ImagePacker.get(regions[0]);
|
||||
|
||||
int i = 0;
|
||||
for(TextureRegion region : regions){
|
||||
i++;
|
||||
if(i != regions.length || last == null){
|
||||
image.draw(region);
|
||||
}else{
|
||||
image.draw(last);
|
||||
}
|
||||
}
|
||||
|
||||
image.save("block-" + block.name + "-full");
|
||||
|
||||
image.save("../editor/" + block.name + "-icon-editor");
|
||||
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Image scaled = new Image(icon.size, icon.size);
|
||||
scaled.drawScaled(image);
|
||||
scaled.save("../ui/block-" + block.name + "-" + icon.name());
|
||||
}
|
||||
|
||||
Color average = new Color();
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = 0; y < image.height; y++){
|
||||
Color color = image.getColor(x, y);
|
||||
average.r += color.r;
|
||||
average.g += color.g;
|
||||
average.b += color.b;
|
||||
}
|
||||
}
|
||||
average.mul(1f / (image.width * image.height));
|
||||
if(block instanceof Floor){
|
||||
average.mul(0.8f);
|
||||
}else{
|
||||
average.mul(1.1f);
|
||||
}
|
||||
average.a = 1f;
|
||||
colors.draw(block.id, 0, average);
|
||||
}catch(IllegalArgumentException e){
|
||||
Log.info("Skipping &ly'{0}'", block.name);
|
||||
}catch(NullPointerException e){
|
||||
Log.err("Block &ly'{0}'&lr has an null region!");
|
||||
}
|
||||
}
|
||||
|
||||
colors.save("../../../assets/sprites/block_colors");
|
||||
});
|
||||
|
||||
ImagePacker.generate("item-icons", () -> {
|
||||
for(UnlockableContent item : (Array<? extends UnlockableContent>)(Array)Array.withArrays(content.items(), content.liquids())){
|
||||
Image base = ImagePacker.get(item.getContentType().name() + "-" + item.name);
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
//if(icon.size == base.width) continue;
|
||||
Image image = new Image(icon.size, icon.size);
|
||||
image.drawScaled(base);
|
||||
image.save(item.getContentType().name() + "-" + item.name + "-" + icon.name(), false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("mech-icons", () -> {
|
||||
for(Mech mech : content.<Mech>getBy(ContentType.mech)){
|
||||
mech.load();
|
||||
mech.weapon.load();
|
||||
|
||||
Image image = ImagePacker.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 / 2 - mech.weapon.region.getWidth() / 2;
|
||||
|
||||
for(int i : Mathf.signs){
|
||||
image.draw(mech.weapon.region, i * (int)mech.weaponOffsetX*4 + off, -(int)mech.weaponOffsetY*4 + off, i > 0, false);
|
||||
}
|
||||
|
||||
image.save("mech-" + mech.name + "-full");
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("unit-icons", () -> {
|
||||
content.<UnitType>getBy(ContentType.unit).each(type -> !type.flying, type -> {
|
||||
type.load();
|
||||
type.weapon.load();
|
||||
|
||||
Image image = ImagePacker.get(type.region);
|
||||
|
||||
image.draw(type.baseRegion);
|
||||
image.draw(type.legRegion);
|
||||
image.draw(type.legRegion, true, false);
|
||||
image.draw(type.region);
|
||||
|
||||
for(boolean b : Mathf.booleans){
|
||||
image.draw(type.weapon.region,
|
||||
(int)(Mathf.sign(b) * type.weapon.width / Draw.scl + image.width / 2 - type.weapon.region.getWidth() / 2),
|
||||
(int)(type.weaponOffsetY / Draw.scl + image.height / 2f - type.weapon.region.getHeight() / 2f),
|
||||
b, false);
|
||||
}
|
||||
|
||||
image.save("unit-" + type.name + "-full");
|
||||
});
|
||||
});
|
||||
|
||||
ImagePacker.generate("ore-icons", () -> {
|
||||
content.blocks().<OreBlock>each(b -> b instanceof OreBlock, ore -> {
|
||||
Item item = ore.itemDrop;
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
//get base image to draw on
|
||||
Image image = new Image(32, 32);
|
||||
Image shadow = ImagePacker.get(item.name + (i + 1));
|
||||
|
||||
int offset = image.width / tilesize - 1;
|
||||
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = offset; y < image.height; y++){
|
||||
Color color = shadow.getColor(x, y - offset);
|
||||
|
||||
//draw semi transparent background
|
||||
if(color.a > 0.001f){
|
||||
color.set(0, 0, 0, 0.3f);
|
||||
image.draw(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image.draw(ImagePacker.get(item.name + (i + 1)));
|
||||
image.save("../blocks/environment/ore-" + item.name + (i + 1));
|
||||
image.save("../editor/editor-ore-" + item.name + (i + 1));
|
||||
|
||||
//save icons
|
||||
image.save("block-" + ore.name + "-full");
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Image scaled = new Image(icon.size, icon.size);
|
||||
scaled.drawScaled(image);
|
||||
scaled.save("block-" + ore.name + "-" + icon.name());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ImagePacker.generate("edges", () -> {
|
||||
content.blocks().<Floor>each(b -> b instanceof Floor && !(b instanceof OverlayFloor), floor -> {
|
||||
|
||||
if(ImagePacker.has(floor.name + "-edge") || floor.blendGroup != floor){
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
Image image = ImagePacker.get(floor.generateIcons()[0]);
|
||||
Image edge = ImagePacker.get("edge-stencil");
|
||||
Image result = new Image(edge.width, edge.height);
|
||||
|
||||
for(int x = 0; x < edge.width; x++){
|
||||
for(int y = 0; y < edge.height; y++){
|
||||
result.draw(x, y, edge.getColor(x, y).mul(image.getColor(x % image.width, y % image.height)));
|
||||
}
|
||||
}
|
||||
|
||||
result.save("../blocks/environment/" + floor.name + "-edge");
|
||||
|
||||
}catch(Exception ignored){}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
137
tools/src/mindustry/tools/Image.java
Normal file
137
tools/src/mindustry/tools/Image.java
Normal file
@@ -0,0 +1,137 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.graphics.Color;
|
||||
import arc.graphics.g2d.TextureRegion;
|
||||
import arc.util.Structs;
|
||||
import mindustry.tools.ImagePacker.GenRegion;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Image{
|
||||
private static ArrayList<Image> toDispose = new ArrayList<>();
|
||||
|
||||
private BufferedImage image;
|
||||
private Graphics2D graphics;
|
||||
private Color color = new Color();
|
||||
|
||||
public final int width, height;
|
||||
|
||||
Image(TextureRegion region){
|
||||
this(ImagePacker.buf(region));
|
||||
}
|
||||
|
||||
Image(BufferedImage src){
|
||||
this.image = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
this.graphics = image.createGraphics();
|
||||
this.graphics.drawImage(src, 0, 0, null);
|
||||
this.width = image.getWidth();
|
||||
this.height = image.getHeight();
|
||||
|
||||
toDispose.add(this);
|
||||
}
|
||||
|
||||
Image(int width, int height){
|
||||
this(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB));
|
||||
}
|
||||
|
||||
boolean isEmpty(int x, int y){
|
||||
if(!Structs.inBounds(x, y, width, height)){
|
||||
return true;
|
||||
}
|
||||
Color color = getColor(x, y);
|
||||
return color.a <= 0.001f;
|
||||
}
|
||||
|
||||
Color getColor(int x, int y){
|
||||
if(!Structs.inBounds(x, y, width, height)) return color.set(0, 0, 0, 0);
|
||||
int i = image.getRGB(x, y);
|
||||
Color.argb8888ToColor(color, i);
|
||||
return color;
|
||||
}
|
||||
|
||||
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. */
|
||||
void draw(TextureRegion region){
|
||||
draw(region, 0, 0, false, false);
|
||||
}
|
||||
|
||||
/** Draws a region at the center. */
|
||||
void drawCenter(TextureRegion region){
|
||||
draw(region, (width - region.getWidth()) / 2, (height - region.getHeight()) / 2, false, false);
|
||||
}
|
||||
|
||||
/** Draws a region at the center. */
|
||||
void drawCenter(TextureRegion region, boolean flipx, boolean flipy){
|
||||
draw(region, (width - region.getWidth()) / 2, (height - region.getHeight()) / 2, flipx, flipy);
|
||||
}
|
||||
|
||||
void drawScaled(Image image){
|
||||
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);
|
||||
}
|
||||
|
||||
/** Draws an image at the coordinates specified. */
|
||||
void draw(Image image, int x, int y){
|
||||
graphics.drawImage(image.image, x, y, null);
|
||||
}
|
||||
|
||||
void draw(TextureRegion region, boolean flipx, boolean flipy){
|
||||
draw(region, 0, 0, flipx, flipy);
|
||||
}
|
||||
|
||||
void draw(TextureRegion region, int x, int y, boolean flipx, boolean flipy){
|
||||
GenRegion.validate(region);
|
||||
|
||||
int ofx = 0, ofy = 0;
|
||||
|
||||
graphics.drawImage(ImagePacker.get(region).image,
|
||||
x, y,
|
||||
x + region.getWidth(),
|
||||
y + region.getHeight(),
|
||||
(flipx ? region.getWidth() : 0) + ofx,
|
||||
(flipy ? region.getHeight() : 0) + ofy,
|
||||
(flipx ? 0 : region.getWidth()) + ofx,
|
||||
(flipy ? 0 : region.getHeight()) + ofy,
|
||||
null);
|
||||
}
|
||||
|
||||
/** @param name Name of texture file name to create, without any extensions. */
|
||||
void save(String name){
|
||||
try{
|
||||
ImageIO.write(image, "png", new File(name + ".png"));
|
||||
}catch(IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void save(String name, boolean antialias){
|
||||
save(name);
|
||||
if(!antialias){
|
||||
new File(name + ".png").setLastModified(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int total(){
|
||||
return toDispose.size();
|
||||
}
|
||||
|
||||
static void dispose(){
|
||||
for(Image image : toDispose){
|
||||
image.graphics.dispose();
|
||||
}
|
||||
toDispose.clear();
|
||||
}
|
||||
}
|
||||
146
tools/src/mindustry/tools/ImagePacker.java
Normal file
146
tools/src/mindustry/tools/ImagePacker.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.files.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.graphics.g2d.TextureAtlas.*;
|
||||
import arc.util.*;
|
||||
import arc.util.Log.*;
|
||||
import mindustry.*;
|
||||
import mindustry.core.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
|
||||
public class ImagePacker{
|
||||
static ObjectMap<String, TextureRegion> regionCache = new ObjectMap<>();
|
||||
static ObjectMap<TextureRegion, BufferedImage> imageCache = new ObjectMap<>();
|
||||
|
||||
public static void main(String[] args){
|
||||
Vars.headless = true;
|
||||
|
||||
Log.setLogger(new NoopLogHandler());
|
||||
Vars.content = new ContentLoader();
|
||||
Vars.content.createBaseContent();
|
||||
Log.setLogger(new DefaultLogHandler());
|
||||
|
||||
Fi.get("../../../assets-raw/sprites_out").walk(path -> {
|
||||
String fname = path.nameWithoutExtension();
|
||||
|
||||
try{
|
||||
BufferedImage image = ImageIO.read(path.file());
|
||||
GenRegion region = new GenRegion(fname, path){
|
||||
|
||||
@Override
|
||||
public int getX(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(){
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(){
|
||||
return image.getHeight();
|
||||
}
|
||||
};
|
||||
|
||||
regionCache.put(fname, region);
|
||||
imageCache.put(region, image);
|
||||
}catch(IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
Core.atlas = new TextureAtlas(){
|
||||
@Override
|
||||
public AtlasRegion find(String name){
|
||||
if(!regionCache.containsKey(name)){
|
||||
GenRegion region = new GenRegion(name, null);
|
||||
region.invalid = true;
|
||||
return region;
|
||||
}
|
||||
return (AtlasRegion)regionCache.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasRegion find(String name, TextureRegion def){
|
||||
if(!regionCache.containsKey(name)){
|
||||
return (AtlasRegion)def;
|
||||
}
|
||||
return (AtlasRegion)regionCache.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String s){
|
||||
return regionCache.containsKey(s);
|
||||
}
|
||||
};
|
||||
|
||||
Draw.scl = 1f / Core.atlas.find("scale_marker").getWidth();
|
||||
|
||||
Time.mark();
|
||||
Generators.generate();
|
||||
Log.info("&ly[Generator]&lc Total time to generate: &lg{0}&lcms", Time.elapsed());
|
||||
Log.info("&ly[Generator]&lc Total images created: &lg{0}", Image.total());
|
||||
Image.dispose();
|
||||
}
|
||||
|
||||
static void generate(String name, Runnable run){
|
||||
Time.mark();
|
||||
run.run();
|
||||
Log.info("&ly[Generator]&lc Time to generate &lm{0}&lc: &lg{1}&lcms", name, Time.elapsed());
|
||||
}
|
||||
|
||||
static BufferedImage buf(TextureRegion region){
|
||||
return imageCache.get(region);
|
||||
}
|
||||
|
||||
static Image create(int width, int height){
|
||||
return new Image(width, height);
|
||||
}
|
||||
|
||||
static Image get(String name){
|
||||
return get(Core.atlas.find(name));
|
||||
}
|
||||
|
||||
static boolean has(String name){
|
||||
return Core.atlas.has(name);
|
||||
}
|
||||
|
||||
static Image get(TextureRegion region){
|
||||
GenRegion.validate(region);
|
||||
|
||||
return new Image(imageCache.get(region));
|
||||
}
|
||||
|
||||
static void err(String message, Object... args){
|
||||
throw new IllegalArgumentException(Strings.format(message, args));
|
||||
}
|
||||
|
||||
static class GenRegion extends AtlasRegion{
|
||||
String name;
|
||||
boolean invalid;
|
||||
Fi path;
|
||||
|
||||
GenRegion(String name, Fi path){
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
static void validate(TextureRegion region){
|
||||
if(((GenRegion)region).invalid){
|
||||
ImagePacker.err("Region does not exist: {0}", ((GenRegion)region).name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
tools/src/mindustry/tools/ScriptStubGenerator.java
Normal file
79
tools/src/mindustry/tools/ScriptStubGenerator.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.Array;
|
||||
import arc.struct.*;
|
||||
import arc.files.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.graphics.g2d.TextureAtlas.*;
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import mindustry.gen.*;
|
||||
import org.reflections.*;
|
||||
import org.reflections.scanners.*;
|
||||
import org.reflections.util.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ScriptStubGenerator{
|
||||
|
||||
public static void main(String[] args){
|
||||
String base = "io.anuke.mindustry";
|
||||
Array<String> blacklist = Array.with("plugin", "mod", "net", "io", "tools");
|
||||
Array<String> nameBlacklist = Array.with("ClientLauncher", "NetClient", "NetServer", "ClassAccess");
|
||||
Array<Class<?>> whitelist = Array.with(Draw.class, Fill.class, Lines.class, Core.class, TextureAtlas.class, TextureRegion.class, Time.class, System.class, PrintStream.class,
|
||||
AtlasRegion.class, String.class, Mathf.class, Angles.class, Color.class, Runnable.class, Object.class, Icon.class, Tex.class,
|
||||
Sounds.class, Musics.class, Call.class, Texture.class, TextureData.class, Pixmap.class, I18NBundle.class);
|
||||
Array<String> nopackage = Array.with("java.lang", "java");
|
||||
|
||||
String fileTemplate = "package mindustry.mod;\n" +
|
||||
"\n" +
|
||||
"import arc.struct.*;\n" +
|
||||
"//obviously autogenerated, do not touch\n" +
|
||||
"public class ClassAccess{\n" +
|
||||
"\tpublic static final ObjectSet<String> allowedClassNames = ObjectSet.with($ALLOWED_CLASS_NAMES$);\n" +
|
||||
"}";
|
||||
|
||||
List<ClassLoader> classLoadersList = new LinkedList<>();
|
||||
classLoadersList.add(ClasspathHelper.contextClassLoader());
|
||||
classLoadersList.add(ClasspathHelper.staticClassLoader());
|
||||
|
||||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||||
.setScanners(new SubTypesScanner(false), new ResourcesScanner())
|
||||
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
|
||||
.filterInputsBy(new FilterBuilder()
|
||||
.include(FilterBuilder.prefix("io.anuke.mindustry"))
|
||||
.include(FilterBuilder.prefix("arc.func"))
|
||||
.include(FilterBuilder.prefix("arc.struct"))
|
||||
.include(FilterBuilder.prefix("arc.scene"))
|
||||
));
|
||||
|
||||
Array<Class<?>> classes = Array.with(reflections.getSubTypesOf(Object.class));
|
||||
classes.addAll(reflections.getSubTypesOf(Enum.class));
|
||||
classes.addAll(whitelist);
|
||||
classes.sort(Structs.comparing(Class::getName));
|
||||
|
||||
classes.removeAll(type -> type.isSynthetic() || type.isAnonymousClass() || type.getCanonicalName() == null || Modifier.isPrivate(type.getModifiers())
|
||||
|| blacklist.contains(s -> type.getName().startsWith(base + "." + s + ".")) || nameBlacklist.contains(type.getSimpleName()));
|
||||
classes.distinct();
|
||||
ObjectSet<String> used = ObjectSet.with();
|
||||
|
||||
StringBuilder result = new StringBuilder("//Generated class. Do not modify.\n");
|
||||
result.append("\n").append(new Fi("core/assets/scripts/base.js").readString()).append("\n");
|
||||
for(Class type : classes){
|
||||
if(used.contains(type.getPackage().getName()) || nopackage.contains(s -> type.getName().startsWith(s))) continue;
|
||||
result.append("importPackage(Packages.").append(type.getPackage().getName()).append(")\n");
|
||||
used.add(type.getPackage().getName());
|
||||
}
|
||||
|
||||
//Log.info(result);
|
||||
|
||||
new Fi("core/assets/scripts/global.js").writeString(result.toString());
|
||||
new Fi("core/src/io/anuke/mindustry/mod/ClassAccess.java").writeString(fileTemplate
|
||||
.replace("$ALLOWED_CLASSES$", classes.toString(", ", type -> type.getName() + ".class"))
|
||||
.replace("$ALLOWED_CLASS_NAMES$", classes.toString(", ", type -> "\"" + type.getName() + "\"")));
|
||||
}
|
||||
}
|
||||
212
tools/src/mindustry/tools/SquareMarcher.java
Normal file
212
tools/src/mindustry/tools/SquareMarcher.java
Normal file
@@ -0,0 +1,212 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.Core;
|
||||
import arc.files.Fi;
|
||||
import arc.graphics.Color;
|
||||
import arc.graphics.Pixmap;
|
||||
import arc.graphics.g2d.Draw;
|
||||
import arc.graphics.g2d.Fill;
|
||||
import arc.graphics.gl.FrameBuffer;
|
||||
import arc.util.ScreenUtils;
|
||||
import arc.util.Tmp;
|
||||
|
||||
public class SquareMarcher{
|
||||
final int resolution;
|
||||
FrameBuffer buffer;
|
||||
|
||||
SquareMarcher(int resolution){
|
||||
this.resolution = resolution;
|
||||
this.buffer = new FrameBuffer(resolution, resolution);
|
||||
}
|
||||
|
||||
void render(Pixmap pixmap, Fi file){
|
||||
boolean[][] grid = new boolean[pixmap.getWidth()][pixmap.getHeight()];
|
||||
|
||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||
Tmp.c1.set(pixmap.getPixel(x, y));
|
||||
grid[x][pixmap.getHeight() - 1 - y] = Tmp.c1.a > 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
float xscl = resolution / (float)pixmap.getWidth(), yscl = resolution / (float)pixmap.getHeight();
|
||||
float scl = xscl;
|
||||
|
||||
Draw.flush();
|
||||
Draw.proj().setOrtho(-xscl / 2f, -yscl / 2f, resolution, resolution);
|
||||
|
||||
buffer.begin();
|
||||
Core.graphics.clear(Color.clear);
|
||||
Draw.color(Color.white);
|
||||
|
||||
for(int x = -1; x < pixmap.getWidth(); x++){
|
||||
for(int y = -1; y < pixmap.getHeight(); y++){
|
||||
int index = index(x, y, pixmap.getWidth(), pixmap.getHeight(), grid);
|
||||
|
||||
float leftx = x * xscl, boty = y * yscl, rightx = x * xscl + xscl, topy = y * xscl + yscl,
|
||||
midx = x * xscl + xscl / 2f, midy = y * yscl + yscl / 2f;
|
||||
|
||||
switch(index){
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
Fill.tri(
|
||||
leftx, midy,
|
||||
leftx, topy,
|
||||
midx, topy
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
Fill.tri(
|
||||
midx, topy,
|
||||
rightx, topy,
|
||||
rightx, midy
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
Fill.crect(leftx, midy, scl, scl / 2f);
|
||||
break;
|
||||
case 4:
|
||||
Fill.tri(
|
||||
midx, boty,
|
||||
rightx, boty,
|
||||
rightx, midy
|
||||
);
|
||||
break;
|
||||
case 5:
|
||||
//ambiguous
|
||||
|
||||
//7
|
||||
Fill.tri(
|
||||
leftx, midy,
|
||||
midx, midy,
|
||||
midx, boty
|
||||
);
|
||||
|
||||
//13
|
||||
Fill.tri(
|
||||
midx, topy,
|
||||
midx, midy,
|
||||
rightx, midy
|
||||
);
|
||||
|
||||
Fill.crect(leftx, midy, scl / 2f, scl / 2f);
|
||||
Fill.crect(midx, boty, scl / 2f, scl / 2f);
|
||||
|
||||
break;
|
||||
case 6:
|
||||
Fill.crect(midx, boty, scl / 2f, scl);
|
||||
break;
|
||||
case 7:
|
||||
//invert triangle
|
||||
Fill.tri(
|
||||
leftx, midy,
|
||||
midx, midy,
|
||||
midx, boty
|
||||
);
|
||||
|
||||
//3
|
||||
Fill.crect(leftx, midy, scl, scl / 2f);
|
||||
|
||||
Fill.crect(midx, boty, scl / 2f, scl / 2f);
|
||||
break;
|
||||
case 8:
|
||||
Fill.tri(
|
||||
leftx, boty,
|
||||
leftx, midy,
|
||||
midx, boty
|
||||
);
|
||||
break;
|
||||
case 9:
|
||||
Fill.crect(leftx, boty, scl / 2f, scl);
|
||||
break;
|
||||
case 10:
|
||||
//ambiguous
|
||||
|
||||
//11
|
||||
Fill.tri(
|
||||
midx, boty,
|
||||
midx, midy,
|
||||
rightx, midy
|
||||
);
|
||||
|
||||
//14
|
||||
Fill.tri(
|
||||
leftx, midy,
|
||||
midx, midy,
|
||||
midx, topy
|
||||
);
|
||||
|
||||
Fill.crect(midx, midy, scl / 2f, scl / 2f);
|
||||
Fill.crect(leftx, boty, scl / 2f, scl / 2f);
|
||||
|
||||
break;
|
||||
case 11:
|
||||
//invert triangle
|
||||
|
||||
Fill.tri(
|
||||
midx, boty,
|
||||
midx, midy,
|
||||
rightx, midy
|
||||
);
|
||||
|
||||
//3
|
||||
Fill.crect(leftx, midy, scl, scl / 2f);
|
||||
|
||||
Fill.crect(leftx, boty, scl / 2f, scl / 2f);
|
||||
break;
|
||||
case 12:
|
||||
Fill.crect(leftx, boty, scl, scl / 2f);
|
||||
break;
|
||||
case 13:
|
||||
//invert triangle
|
||||
|
||||
Fill.tri(
|
||||
midx, topy,
|
||||
midx, midy,
|
||||
rightx, midy
|
||||
);
|
||||
|
||||
//12
|
||||
Fill.crect(leftx, boty, scl, scl / 2f);
|
||||
|
||||
Fill.crect(leftx, midy, scl / 2f, scl / 2f);
|
||||
break;
|
||||
case 14:
|
||||
//invert triangle
|
||||
|
||||
Fill.tri(
|
||||
leftx, midy,
|
||||
midx, midy,
|
||||
midx, topy
|
||||
);
|
||||
|
||||
//12
|
||||
Fill.crect(leftx, boty, scl, scl / 2f);
|
||||
|
||||
Fill.crect(midx, midy, scl / 2f, scl / 2f);
|
||||
break;
|
||||
case 15:
|
||||
Fill.square(midx, midy, scl / 2f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Draw.flush();
|
||||
ScreenUtils.saveScreenshot(file, 0, 0, resolution, resolution);
|
||||
buffer.end();
|
||||
}
|
||||
|
||||
int index(int x, int y, int w, int h, boolean[][] grid){
|
||||
int botleft = sample(grid, x, y);
|
||||
int botright = sample(grid, x + 1, y);
|
||||
int topright = sample(grid, x + 1, y + 1);
|
||||
int topleft = sample(grid, x, y + 1);
|
||||
return (botleft << 3) | (botright << 2) | (topright << 1) | topleft;
|
||||
}
|
||||
|
||||
int sample(boolean[][] grid, int x, int y){
|
||||
return (x < 0 || y < 0 || x >= grid.length || y >= grid.length) ? 0 : grid[x][y] ? 1 : 0;
|
||||
}
|
||||
}
|
||||
47
tools/src/mindustry/tools/Upscaler.java
Normal file
47
tools/src/mindustry/tools/Upscaler.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.*;
|
||||
import io.anuke.arc.backends.sdl.*;
|
||||
import arc.files.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
public class Upscaler{
|
||||
public static void main(String[] args){
|
||||
new SdlApplication(new ApplicationListener(){
|
||||
@Override
|
||||
public void init(){
|
||||
scale();
|
||||
}
|
||||
}, new SdlConfig(){{
|
||||
initialVisible = false;
|
||||
}});
|
||||
}
|
||||
|
||||
static void scale(){
|
||||
Core.batch = new SpriteBatch();
|
||||
Core.atlas = new TextureAtlas();
|
||||
Core.atlas.addRegion("white", Pixmaps.blankTextureRegion());
|
||||
Fi file = Core.files.local("");
|
||||
|
||||
Log.info("Upscaling icons...");
|
||||
Time.mark();
|
||||
Fi[] list = file.list();
|
||||
|
||||
for(IconSize size : IconSize.values()){
|
||||
String suffix = size == IconSize.def ? "" : "-" + size.name();
|
||||
SquareMarcher marcher = new SquareMarcher(size.size);
|
||||
|
||||
for(Fi img : list){
|
||||
if(img.extension().equals("png")){
|
||||
marcher.render(new Pixmap(img), img.sibling(img.nameWithoutExtension() + suffix + ".png"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.info("Done upscaling icons in &lm{0}&lgs.", Time.elapsed()/1000f);
|
||||
Core.app.exit();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user