Partial 7.0 merge - API preview
This commit is contained in:
+45
-200
@@ -1,14 +1,17 @@
|
||||
sourceSets.main.java.srcDirs = ["src/"]
|
||||
|
||||
import arc.struct.*
|
||||
import arc.graphics.*
|
||||
import arc.packer.*
|
||||
import arc.util.*
|
||||
|
||||
import javax.imageio.*
|
||||
import java.awt.Graphics2D
|
||||
import java.awt.image.*
|
||||
import java.util.concurrent.*
|
||||
|
||||
import arc.files.Fi
|
||||
import arc.graphics.Color
|
||||
import arc.graphics.Pixmap
|
||||
import arc.packer.TexturePacker
|
||||
import arc.struct.IntIntMap
|
||||
import arc.struct.IntMap
|
||||
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
def genFolder = "../core/assets-raw/sprites_out/generated/"
|
||||
def doAntialias = !project.hasProperty("disableAntialias")
|
||||
@@ -25,16 +28,17 @@ def transformColors = { List<List<String>> list ->
|
||||
}
|
||||
|
||||
newColors.each{ color ->
|
||||
colorMap.put(color.argb8888(), newColors)
|
||||
colorIndexMap.put(color.argb8888(), newColors.indexOf(color))
|
||||
colorMap.put(color.rgba(), newColors)
|
||||
colorIndexMap.put(color.rgba(), newColors.indexOf(color))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO implementing this in gradle is a bad idea
|
||||
//d4816b
|
||||
transformColors([["a387ea", "8a73c6", "5c5e9f"], ["6e7080", "989aa4", "b0bac0"], ["bc5452", "ea8878", "feb380"],
|
||||
["de9458", "f8c266", "ffe18f"], ["feb380", "ea8878", "bc5452"], ["d4816b", "eab678", "ffd37f"], ["ffffff", "dcc6c6", "9d7f7f"]])
|
||||
["de9458", "f8c266", "ffe18f"], ["feb380", "ea8878", "bc5452"], ["d4816b", "eab678", "ffd37f"],
|
||||
["ffffff", "dcc6c6", "9d7f7f"], ["df7646", "b23a4d", "752249"], ["3c3837", "515151", "646567"]])
|
||||
|
||||
def antialias = { File file ->
|
||||
if(!doAntialias) return
|
||||
@@ -44,11 +48,10 @@ def antialias = { File file ->
|
||||
return
|
||||
}
|
||||
|
||||
def image = ImageIO.read(file)
|
||||
def out = ImageIO.read(file)
|
||||
def image = new Pixmap(new Fi(file))
|
||||
def out = image.copy()
|
||||
def getRGB = { int ix, int iy ->
|
||||
//if(ix <= 0 || iy <= 0 || ix >= image.width || iy >= image.height) return 0
|
||||
return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0))
|
||||
return image.getRaw(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0))
|
||||
}
|
||||
|
||||
def color = new Color()
|
||||
@@ -56,8 +59,8 @@ def antialias = { File file ->
|
||||
def suma = new Color()
|
||||
int[] p = new int[9]
|
||||
|
||||
for(int x = 0; x < image.getWidth(); x++){
|
||||
for(int y = 0; y < image.getHeight(); y++){
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = 0; y < image.height; y++){
|
||||
int A = getRGB(x - 1, y + 1),
|
||||
B = getRGB(x, y + 1),
|
||||
C = getRGB(x + 1, y + 1),
|
||||
@@ -68,7 +71,7 @@ def antialias = { File file ->
|
||||
H = getRGB(x, y - 1),
|
||||
I = getRGB(x + 1, y - 1)
|
||||
|
||||
Arrays.fill(p, E);
|
||||
Arrays.fill(p, E)
|
||||
|
||||
if(D == B && D != H && B != F) p[0] = D
|
||||
if((D == B && D != H && B != F && E != C) || (B == F && B != D && F != H && E != A)) p[1] = B
|
||||
@@ -82,21 +85,21 @@ def antialias = { File file ->
|
||||
suma.set(0)
|
||||
|
||||
for(int val : p){
|
||||
color.argb8888(val)
|
||||
color.rgba8888(val)
|
||||
suma.r += color.r * color.a
|
||||
suma.g += color.g * color.a
|
||||
suma.b += color.b * color.a
|
||||
suma.a += color.a
|
||||
}
|
||||
|
||||
float fm = suma.a <= 0.001f ? 0f : (float) (1f / suma.a)
|
||||
float fm = suma.a <= 0.001f ? 0f : (float)(1f / suma.a)
|
||||
suma.mul(fm, fm, fm, fm)
|
||||
|
||||
float total = 0
|
||||
sum.set(0)
|
||||
|
||||
for(int val : p){
|
||||
color.argb8888(val)
|
||||
color.rgba8888(val)
|
||||
float a = color.a
|
||||
color.lerp(suma, (float) (1f - a))
|
||||
sum.r += color.r
|
||||
@@ -108,92 +111,19 @@ def antialias = { File file ->
|
||||
|
||||
fm = (float)(1f / total)
|
||||
sum.mul(fm, fm, fm, fm)
|
||||
out.setRGB(x, y, sum.argb8888())
|
||||
out.setRaw(x, y, sum.rgba8888())
|
||||
sum.set(0)
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(out, "png", file)
|
||||
}
|
||||
image.dispose()
|
||||
out.dispose()
|
||||
|
||||
def medianBlur = { File file ->
|
||||
def image = ImageIO.read(file)
|
||||
def result = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_ARGB)
|
||||
def radius = 4
|
||||
IntSeq array = new IntSeq()
|
||||
|
||||
def getRGB = { int ix, int iy ->
|
||||
return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0))
|
||||
}
|
||||
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = 0; y < image.height; y++){
|
||||
array.clear()
|
||||
|
||||
for(int dx = -radius; dx <= radius; dx ++){
|
||||
for(int dy = -radius; dy <= radius; dy ++){
|
||||
if(dx*dx + dy*dy <= radius*radius){
|
||||
array.add(getRGB(x + dx, y + dy))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
array.sort()
|
||||
|
||||
result.setRGB(x, y, array.get((int)(array.size / 2)))
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(result, "png", file)
|
||||
}
|
||||
|
||||
def scaleImage = { File file ->
|
||||
def image = ImageIO.read(file)
|
||||
for(int iteration in 0..1){
|
||||
def scaled = new BufferedImage(image.width * 2, image.height * 2, BufferedImage.TYPE_INT_ARGB)
|
||||
|
||||
def getRGB = { int ix, int iy ->
|
||||
return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0))
|
||||
}
|
||||
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = 0; y < image.height; y++){
|
||||
int p = image.getRGB(x, y)
|
||||
int p1 = p, p2 = p, p3 = p, p4 = p
|
||||
|
||||
int A = getRGB(x - 1, y + 1),
|
||||
B = getRGB(x, y + 1),
|
||||
C = getRGB(x + 1, y + 1),
|
||||
D = getRGB(x - 1, y),
|
||||
E = getRGB(x, y),
|
||||
F = getRGB(x + 1, y),
|
||||
G = getRGB(x - 1, y - 1),
|
||||
H = getRGB(x, y - 1),
|
||||
I = getRGB(x + 1, y - 1),
|
||||
J = getRGB(x, y + 2),
|
||||
K = getRGB(x - 2, y),
|
||||
L = getRGB(x + 2, y),
|
||||
M = getRGB(x, y - 2)
|
||||
|
||||
if(B == D && B != F && D != H && (E != A || E == C || E == G || A == J || A == K)) p1 = B
|
||||
if(B == F && B != D && F != H && (E != C || E == A || E == I || C == J || C == L)) p2 = F
|
||||
if(D == H && B != D && F != H && (E != G || E == A || E == I || G == K || G == M)) p3 = D
|
||||
if(F == H && B != F && D != H && (E != I || E == C || E == G || I == L || I == M)) p4 = H
|
||||
|
||||
scaled.setRGB(x * 2, y * 2 + 1, p1)
|
||||
scaled.setRGB(x * 2 + 1, y * 2 + 1, p2)
|
||||
scaled.setRGB(x * 2, y * 2, p3)
|
||||
scaled.setRGB(x * 2 + 1, y * 2, p4)
|
||||
}
|
||||
}
|
||||
image = scaled
|
||||
}
|
||||
|
||||
ImageIO.write(image, "png", file)
|
||||
new Fi(file).writePng(out)
|
||||
}
|
||||
|
||||
def tileImage = { File file ->
|
||||
def image = ImageIO.read(file)
|
||||
def image = new Pixmap(new Fi(file))
|
||||
|
||||
for(x in 0..image.width-1){
|
||||
for(y in 0..image.height-1){
|
||||
@@ -201,104 +131,36 @@ def tileImage = { File file ->
|
||||
def rx = image.height - 1 - y
|
||||
def ry = x
|
||||
|
||||
image.setRGB(x, y, image.getRGB(rx, image.height - 1 - ry))
|
||||
image.setRaw(x, y, image.getRaw(rx, image.height - 1 - ry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def result = new BufferedImage(image.width * 2, image.height * 2, image.getType())
|
||||
Graphics2D graphics = result.createGraphics()
|
||||
graphics.drawImage(image, image.width, 0, -image.width, image.height, null)
|
||||
def result = new Pixmap(image.width * 2, image.height * 2)
|
||||
|
||||
graphics.drawImage(image, image.width, 0, image.width, image.height, null)
|
||||
result.draw(image.flipX(), 0, 0)
|
||||
result.draw(image, image.width, 0)
|
||||
result.draw(image.flipX().flipY(), 0, image.height)
|
||||
result.draw(image.flipY(), image.width, image.height)
|
||||
|
||||
graphics.drawImage(image, image.width, image.height*2, -image.width, -image.height, null)
|
||||
|
||||
graphics.drawImage(image, image.width, image.height*2, image.width, -image.height, null)
|
||||
|
||||
for(int x = 0; x < result.width; x++){
|
||||
for(int y = 0; y < result.height; y++){
|
||||
int p = result.getRGB(x, y)
|
||||
for(x in 0..result.width-1){
|
||||
for(y in 0..result.height-1){
|
||||
int p = result.getRaw(x, y)
|
||||
if(x <= y){
|
||||
List<Color> list = colorMap.get(p)
|
||||
int index = colorIndexMap.get(p, -1)
|
||||
|
||||
if(index != -1){
|
||||
int resultIndex = (x == y ? 1 : index == 2 ? 0 : index == 0 ? 2 : 1);
|
||||
result.setRGB(x, y, list[resultIndex].argb8888())
|
||||
result.setRaw(x, y, list[resultIndex].rgba())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(result, "png", file)
|
||||
}
|
||||
|
||||
task swapColors(){
|
||||
doLast{
|
||||
if(project.hasProperty("colors")){
|
||||
def carr = new File(getProperty("colors")).text.split("\n")
|
||||
def map = [:]
|
||||
def swaps = 0
|
||||
carr.each{ str -> map[Color.valueOf(str.split("=")[0]).argb8888()] = Color.valueOf(str.split("=")[1]).argb8888() }
|
||||
def tmpc = new Color()
|
||||
|
||||
fileTree(dir: '../core/assets-raw/sprites', include: "**/*.png").visit{ file ->
|
||||
if(file.isDirectory()) return
|
||||
|
||||
boolean found = false
|
||||
|
||||
def img = ImageIO.read(file.file)
|
||||
for(x in (0..img.getWidth() - 1)){
|
||||
for(y in (0..img.getHeight() - 1)){
|
||||
def c = img.getRGB(x, y)
|
||||
tmpc.argb8888(c)
|
||||
if(tmpc.a < 0.1f) continue
|
||||
if(map.containsKey(c)){
|
||||
img.setRGB(x, y, (int)map.get(c))
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
swaps++
|
||||
ImageIO.write(img, "png", file.file)
|
||||
}
|
||||
}
|
||||
println "Swapped $swaps images."
|
||||
}else{
|
||||
throw new InvalidUserDataException("No replacement colors specified. Use -Pcolors=\"<path to color file>\"")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task genPalette(){
|
||||
doLast{
|
||||
def total = 0
|
||||
def size = 32
|
||||
def outImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB)
|
||||
def colorsUsed = new IntSet()
|
||||
|
||||
fileTree(dir: '../core/assets-raw/sprites/blocks', include: "**/*.png").visit{ file ->
|
||||
if(file.isDirectory()) return
|
||||
|
||||
def img = ImageIO.read(file.file)
|
||||
for(x in (0..img.getWidth() - 1)){
|
||||
for(y in (0..img.getHeight() - 1)){
|
||||
def c = img.getRGB(x, y)
|
||||
|
||||
if(Tmp.c1.argb8888(c).a > 0.999f && colorsUsed.add(c)){
|
||||
outImage.setRGB((int)(total / size), total % size, c)
|
||||
total ++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(outImage, "png", new File("palette.png"))
|
||||
println "Found $total colors."
|
||||
|
||||
}
|
||||
new Fi(file).writePng(result)
|
||||
result.dispose()
|
||||
image.dispose()
|
||||
}
|
||||
|
||||
task antialiasImages(){
|
||||
@@ -310,15 +172,6 @@ task antialiasImages(){
|
||||
}
|
||||
}
|
||||
|
||||
task scaleImages(){
|
||||
doLast{
|
||||
for(def img : project.getProperty("images").split(",")){
|
||||
println(project.getProperty("startdir") + "/" + img)
|
||||
scaleImage(new File(project.getProperty("startdir") + "/" + img))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task tileImages(){
|
||||
doLast{
|
||||
for(def img : project.getProperty("images").split(",")){
|
||||
@@ -383,7 +236,7 @@ task pack(dependsOn: [classes, configurations.runtimeClasspath]){
|
||||
println("\n\nPacking normal 4096 sprites...\n\n")
|
||||
|
||||
//pack normal sprites
|
||||
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/").absolutePath, "sprites.atlas")
|
||||
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/").absolutePath, "sprites.aatls")
|
||||
|
||||
println("\n\nPacking fallback 2048 sprites...\n\n")
|
||||
|
||||
@@ -393,7 +246,7 @@ task pack(dependsOn: [classes, configurations.runtimeClasspath]){
|
||||
}
|
||||
|
||||
//pack fallback 2048x2048 sprites
|
||||
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/fallback/").absolutePath, "sprites.atlas")
|
||||
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/fallback/").absolutePath, "sprites.aatls")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +255,6 @@ task genSprites(dependsOn: classes, type: JavaExec){
|
||||
|
||||
main = "mindustry.tools.ImagePacker"
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
jvmArgs("-Djava.awt.headless=true")
|
||||
standardInput = System.in
|
||||
workingDir = genFolder
|
||||
}
|
||||
@@ -435,11 +287,4 @@ task updateScripts(dependsOn: classes, type: JavaExec){
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
standardInput = System.in
|
||||
workingDir = "../"
|
||||
}
|
||||
|
||||
task genBindings(dependsOn: classes, type: JavaExec){
|
||||
main = "mindustry.tools.BindingsGenerator"
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
standardInput = System.in
|
||||
workingDir = "../"
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.files.*;
|
||||
import arc.graphics.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
|
||||
public class Edgifier{
|
||||
|
||||
public static void main(String[] args){
|
||||
ArcNativesLoader.load();
|
||||
|
||||
Pixmap pixmap = new Pixmap(Fi.get("/home/anuke/Projects/Mindustry/core/assets-raw/sprites/units/reaper.png"));
|
||||
|
||||
Fi.get("/home/anuke/out.png").writePNG(edgify(pixmap, 5));
|
||||
}
|
||||
|
||||
private static Pixmap edgify(Pixmap in, int chunk){
|
||||
Pixmap out = new Pixmap(in.getWidth(), in.getHeight());
|
||||
IntSeq side1 = new IntSeq(), side2 = new IntSeq();
|
||||
|
||||
for(int x = 0; x < in.getWidth(); x += chunk){
|
||||
for(int y = 0; y < in.getHeight(); y += chunk){
|
||||
int bestErrors = Integer.MAX_VALUE;
|
||||
int bestRotation = 0;
|
||||
int bestSide1 = 0, bestSide2 = 0;
|
||||
|
||||
for(int rotation = 0; rotation < 8; rotation++){
|
||||
side1.clear();
|
||||
side2.clear();
|
||||
|
||||
//assign pixels present on each side
|
||||
for(int cx = 0; cx < chunk; cx++){
|
||||
for(int cy = 0; cy < chunk; cy++){
|
||||
boolean side = classify(rotation, cx, cy, chunk);
|
||||
|
||||
int pixel = in.getPixel(x + cx, y + cy);
|
||||
if(Pixmaps.empty(pixel)) pixel = 0; //all alpha=0 pixels are treated as 0
|
||||
|
||||
(side ? side1 : side2).add(pixel);
|
||||
}
|
||||
}
|
||||
|
||||
//find most popular element here
|
||||
int mode1 = side1.mode(), mode2 = side2.mode();
|
||||
//total errors; 'incorrect' pixels
|
||||
int errors = (side1.size - side1.count(mode1)) + (side2.size - side2.count(mode2));
|
||||
|
||||
//Log.info("errors for rotation={0}: {1}", rotation, errors);
|
||||
|
||||
//update if better
|
||||
if(errors < bestErrors){
|
||||
bestRotation = rotation;
|
||||
bestSide1 = mode1;
|
||||
bestSide2 = mode2;
|
||||
bestErrors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
//Log.info("Best result for {0},{1}: rotation={2} 1={3} 2={4} errors={5}", x, y, bestRotation, bestSide1, bestSide2, bestErrors);
|
||||
|
||||
//draw with the best result
|
||||
for(int cx = 0; cx < chunk; cx++){
|
||||
for(int cy = 0; cy < chunk; cy++){
|
||||
boolean side = classify(bestRotation, cx, cy, chunk);
|
||||
out.draw(x + cx, y + cy, side ? bestSide1 : bestSide2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private static boolean classify(int rotation, int x, int y, int chunk){
|
||||
switch(rotation){
|
||||
case 0: //return y >= chunk / 2;
|
||||
case 1: return y < x;
|
||||
case 2: //return x <= chunk / 2;
|
||||
case 3: return (chunk - 1 - y) < x;
|
||||
case 4: //return (y > chunk / 2);
|
||||
case 5: return (y <= x);
|
||||
case 6: //return (x < chunk / 2);
|
||||
case 7: return ((chunk - 1 - y) <= x);
|
||||
default: throw new IllegalArgumentException("Invalid rotation: " + rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,48 +14,25 @@ import mindustry.ctype.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.tools.ImagePacker.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
import mindustry.world.blocks.legacy.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.tools.ImagePacker.*;
|
||||
|
||||
public class Generators{
|
||||
//used for changing colors in the UI - testing only
|
||||
static final IntIntMap paletteMap = IntIntMap.with(
|
||||
//empty for now
|
||||
0x454545ff, 0x00000000,//0x32394bff,
|
||||
0x00000099, 0x00000000//0x000000ff
|
||||
);
|
||||
static final Cicon logicIcon = Cicon.medium;
|
||||
static final int logicIconSize = (int)iconMed, maxUiIcon = 128;
|
||||
|
||||
public static void generate(){
|
||||
ObjectMap<Block, Image> gens = new ObjectMap<>();
|
||||
public static void run(){
|
||||
ObjectMap<Block, Pixmap> gens = new ObjectMap<>();
|
||||
|
||||
if(!paletteMap.isEmpty()){
|
||||
ImagePacker.generate("uipalette", () -> {
|
||||
Fi.get("../ui").walk(fi -> {
|
||||
if(!fi.extEquals("png")) return;
|
||||
|
||||
Pixmap pix = new Pixmap(fi);
|
||||
pix.setBlending(Pixmap.Blending.sourceOver);
|
||||
pix.each((x, y) -> {
|
||||
int value = pix.getPixel(x, y);
|
||||
pix.draw(x, y, paletteMap.get(value, value));
|
||||
});
|
||||
|
||||
fi.writePNG(pix);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ImagePacker.generate("splashes", () -> {
|
||||
ArcNativesLoader.load();
|
||||
generate("splashes", () -> {
|
||||
|
||||
int frames = 12;
|
||||
int size = 32;
|
||||
@@ -70,90 +47,129 @@ public class Generators{
|
||||
pixmap.each((x, y) -> {
|
||||
float dst = Mathf.dst(x, y, size/2f, size/2f);
|
||||
if(Math.abs(dst - radius) <= stroke){
|
||||
pixmap.draw(x, y, Color.white);
|
||||
pixmap.set(x, y, Color.white);
|
||||
}
|
||||
});
|
||||
|
||||
Fi.get("splash-" + i + ".png").writePNG(pixmap);
|
||||
Fi.get("splash-" + i + ".png").writePng(pixmap);
|
||||
|
||||
pixmap.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("cliffs", () -> {
|
||||
int size = 64;
|
||||
Color dark = new Color(0.5f, 0.5f, 0.6f, 1f).mul(0.98f);
|
||||
Color mid = Color.lightGray;
|
||||
generate("bubbles", () -> {
|
||||
|
||||
Image[] images = new Image[8];
|
||||
int frames = 16;
|
||||
int size = 40;
|
||||
for(int i = 0; i < frames; i++){
|
||||
float fin = (float)i / (frames);
|
||||
float fout = 1f - fin;
|
||||
float stroke = 3.5f * fout;
|
||||
float radius = (size/2f) * fin;
|
||||
float shinelen = radius / 2.5f, shinerad = stroke*1.5f + 0.3f;
|
||||
float shinex = size/2f + shinelen / Mathf.sqrt2, shiney = size/2f - shinelen / Mathf.sqrt2;
|
||||
|
||||
Pixmap pixmap = new Pixmap(size, size);
|
||||
|
||||
pixmap.each((x, y) -> {
|
||||
float dst = Mathf.dst(x, y, size/2f, size/2f);
|
||||
if(Math.abs(dst - radius) <= stroke || Mathf.within(x, y, shinex, shiney, shinerad)){
|
||||
pixmap.set(x, y, Color.white);
|
||||
}
|
||||
});
|
||||
|
||||
Fi.get("bubble-" + i + ".png").writePng(pixmap);
|
||||
|
||||
pixmap.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
generate("cliffs", () -> {
|
||||
ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
int size = 64;
|
||||
int dark = new Color(0.5f, 0.5f, 0.6f, 1f).mul(0.98f).rgba();
|
||||
int mid = Color.lightGray.rgba();
|
||||
|
||||
Pixmap[] images = new Pixmap[8];
|
||||
for(int i = 0; i < 8; i++){
|
||||
images[i] = ImagePacker.get("cliff" + i);
|
||||
images[i] = new Pixmap(((GenRegion)Core.atlas.find("cliff" + i)).path);
|
||||
}
|
||||
|
||||
for(int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++){
|
||||
Image result = new Image(size, size);
|
||||
byte[][] mask = new byte[size][size];
|
||||
int bi = i;
|
||||
exec.execute(() -> {
|
||||
Color color = new Color();
|
||||
Pixmap result = new Pixmap(size, size);
|
||||
byte[][] mask = new byte[size][size];
|
||||
|
||||
byte val = (byte)i;
|
||||
//check each bit/direction
|
||||
for(int j = 0; j < 8; j++){
|
||||
if((val & (1 << j)) != 0){
|
||||
if(j % 2 == 1 && (((val & (1 << (j + 1))) != 0) != ((val & (1 << (j - 1))) != 0))){
|
||||
continue;
|
||||
}
|
||||
|
||||
Image image = images[j];
|
||||
image.each((x, y) -> {
|
||||
Color color = image.getColor(x, y);
|
||||
if(color.a > 0.1){
|
||||
//white -> bit 1 -> top
|
||||
//black -> bit 2 -> bottom
|
||||
mask[x][y] |= (color.r > 0.5f ? 1 : 2);
|
||||
byte val = (byte)bi;
|
||||
//check each bit/direction
|
||||
for(int j = 0; j < 8; j++){
|
||||
if((val & (1 << j)) != 0){
|
||||
if(j % 2 == 1 && (((val & (1 << (j + 1))) != 0) != ((val & (1 << (j - 1))) != 0))){
|
||||
continue;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
result.each((x, y) -> {
|
||||
byte m = mask[x][y];
|
||||
if(m != 0){
|
||||
//mid
|
||||
if(m == 3){
|
||||
//find nearest non-mid color
|
||||
byte best = 0;
|
||||
float bestDst = 0;
|
||||
boolean found = false;
|
||||
//expand search range until found
|
||||
for(int rad = 9; rad < 64; rad += 7){
|
||||
for(int cx = Math.max(x - rad, 0); cx <= Math.min(x + rad, size - 1); cx++){
|
||||
for(int cy = Math.max(y - rad, 0); cy <= Math.min(y + rad, size - 1); cy++){
|
||||
byte nval = mask[cx][cy];
|
||||
if(nval == 1 || nval == 2){
|
||||
float dst2 = Mathf.dst2(cx, cy, x, y);
|
||||
if(dst2 <= rad * rad && (!found || dst2 < bestDst)){
|
||||
best = nval;
|
||||
bestDst = dst2;
|
||||
found = true;
|
||||
Pixmap image = images[j];
|
||||
image.each((x, y) -> {
|
||||
color.set(image.getRaw(x, y));
|
||||
if(color.a > 0.1){
|
||||
//white -> bit 1 -> top
|
||||
//black -> bit 2 -> bottom
|
||||
mask[x][y] |= (color.r > 0.5f ? 1 : 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
result.each((x, y) -> {
|
||||
byte m = mask[x][y];
|
||||
if(m != 0){
|
||||
//mid
|
||||
if(m == 3){
|
||||
//find nearest non-mid color
|
||||
byte best = 0;
|
||||
float bestDst = 0;
|
||||
boolean found = false;
|
||||
//expand search range until found
|
||||
for(int rad = 9; rad < 64; rad += 7){
|
||||
for(int cx = Math.max(x - rad, 0); cx <= Math.min(x + rad, size - 1); cx++){
|
||||
for(int cy = Math.max(y - rad, 0); cy <= Math.min(y + rad, size - 1); cy++){
|
||||
byte nval = mask[cx][cy];
|
||||
if(nval == 1 || nval == 2){
|
||||
float dst2 = Mathf.dst2(cx, cy, x, y);
|
||||
if(dst2 <= rad * rad && (!found || dst2 < bestDst)){
|
||||
best = nval;
|
||||
bestDst = dst2;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
m = best;
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
m = best;
|
||||
}
|
||||
result.setRaw(x, y, m == 1 ? Color.whiteRgba : m == 2 ? dark : mid);
|
||||
}
|
||||
});
|
||||
|
||||
result.draw(x, y, m == 1 ? Color.white : m == 2 ? dark : mid);
|
||||
}
|
||||
Fi.get("../blocks/environment/cliffmask" + (val & 0xff) + ".png").writePng(result);
|
||||
});
|
||||
}
|
||||
|
||||
result.save("../blocks/environment/cliffmask" + (val & 0xff));
|
||||
try{
|
||||
exec.shutdown();
|
||||
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException("go away", e);
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("cracks", () -> {
|
||||
generate("cracks", () -> {
|
||||
RidgedPerlin r = new RidgedPerlin(1, 3);
|
||||
for(int size = 1; size <= BlockRenderer.maxCrackSize; size++){
|
||||
int dim = size * 32;
|
||||
@@ -161,17 +177,17 @@ public class Generators{
|
||||
for(int i = 0; i < steps; i++){
|
||||
float fract = i / (float)steps;
|
||||
|
||||
Image image = new Image(dim, dim);
|
||||
Pixmap image = new Pixmap(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.setRaw(x, y, Color.whiteRgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image output = new Image(image.width, image.height);
|
||||
Pixmap output = new Pixmap(image.width, image.height);
|
||||
int rad = 3;
|
||||
|
||||
//median filter
|
||||
@@ -181,30 +197,31 @@ public class Generators{
|
||||
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){
|
||||
int color = image.getRaw(wx, wy);
|
||||
if((color & 0xff) > 127){
|
||||
whites ++;
|
||||
}else{
|
||||
clears ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
output.draw(x, y, whites >= clears ? Color.white : Color.clear);
|
||||
output.setRaw(x, y, whites >= clears ? Color.whiteRgba : Color.clearRgba);
|
||||
}
|
||||
}
|
||||
|
||||
output.save("cracks-" + size + "-" + i);
|
||||
Fi.get("cracks-" + size + "-" + i + ".png").writePng(output);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("block-icons", () -> {
|
||||
Image colors = new Image(content.blocks().size, 1);
|
||||
generate("block-icons", () -> {
|
||||
Pixmap colors = new Pixmap(content.blocks().size, 1);
|
||||
|
||||
for(Block block : content.blocks()){
|
||||
if(block.isAir() || block instanceof ConstructBlock || block instanceof OreBlock || block instanceof LegacyBlock) continue;
|
||||
|
||||
block.load();
|
||||
block.loadIcon();
|
||||
|
||||
TextureRegion[] regions = block.getGeneratedIcons();
|
||||
|
||||
@@ -216,20 +233,25 @@ public class Generators{
|
||||
}
|
||||
}
|
||||
|
||||
Image shardTeamTop = null;
|
||||
for(TextureRegion region : block.makeIconRegions()){
|
||||
GenRegion gen = (GenRegion)region;
|
||||
save(get(region).outline(block.outlineColor, block.outlineRadius), gen.name + "-outline");
|
||||
}
|
||||
|
||||
Pixmap shardTeamTop = null;
|
||||
|
||||
if(block.teamRegion.found()){
|
||||
Image teamr = ImagePacker.get(block.teamRegion);
|
||||
Pixmap teamr = get(block.teamRegion);
|
||||
|
||||
for(Team team : Team.all){
|
||||
if(team.hasPalette){
|
||||
Image out = new Image(teamr.width, teamr.height);
|
||||
Pixmap out = new Pixmap(teamr.width, teamr.height);
|
||||
teamr.each((x, y) -> {
|
||||
int color = teamr.getColor(x, y).rgba8888();
|
||||
int color = teamr.getRaw(x, y);
|
||||
int index = color == 0xffffffff ? 0 : color == 0xdcc6c6ff ? 1 : color == 0x9d7f7fff ? 2 : -1;
|
||||
out.draw(x, y, index == -1 ? teamr.getColor(x, y) : team.palette[index]);
|
||||
out.setRaw(x, y, index == -1 ? teamr.getRaw(x, y) : team.palette[index].rgba());
|
||||
});
|
||||
out.save(block.name + "-team-" + team.name);
|
||||
save(out, block.name + "-team-" + team.name);
|
||||
|
||||
if(team == Team.sharded){
|
||||
shardTeamTop = out;
|
||||
@@ -243,87 +265,63 @@ public class Generators{
|
||||
}
|
||||
|
||||
try{
|
||||
Image last = null;
|
||||
Pixmap last = null;
|
||||
if(block.outlineIcon){
|
||||
int radius = 4;
|
||||
GenRegion region = (GenRegion)regions[block.outlinedIcon >= 0 ? block.outlinedIcon : regions.length -1];
|
||||
Image base = ImagePacker.get(region);
|
||||
Image out = last = new Image(region.width, region.height);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Pixmap base = get(region);
|
||||
Pixmap out = last = base.outline(block.outlineColor, block.outlineRadius);
|
||||
|
||||
//do not run for legacy ones
|
||||
if(block.outlinedIcon >= 0){
|
||||
//prevents the regions above from being ignored/invisible/etc
|
||||
for(int i = block.outlinedIcon + 1; i < regions.length; i++){
|
||||
out.draw(ImagePacker.get(regions[i]));
|
||||
out.draw(get(regions[i]), true);
|
||||
}
|
||||
}
|
||||
|
||||
region.path.delete();
|
||||
|
||||
out.save(block.name);
|
||||
save(out, block.name);
|
||||
}
|
||||
|
||||
Image image = ImagePacker.get(regions[0]);
|
||||
if(!regions[0].found()){
|
||||
continue;
|
||||
}
|
||||
|
||||
Pixmap image = get(regions[0]);
|
||||
|
||||
int i = 0;
|
||||
for(TextureRegion region : regions){
|
||||
i++;
|
||||
if(i != regions.length || last == null){
|
||||
image.draw(region);
|
||||
image.draw(get(region), true);
|
||||
}else{
|
||||
image.draw(last);
|
||||
image.draw(last, true);
|
||||
}
|
||||
|
||||
//draw shard (default team top) on top of first sprite
|
||||
if(region == block.teamRegions[Team.sharded.id] && shardTeamTop != null){
|
||||
image.draw(shardTeamTop);
|
||||
image.draw(shardTeamTop, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(regions.length == 1 && regions[0] == Core.atlas.find(block.name) && shardTeamTop == null)){
|
||||
image.save("block-" + block.name + "-full");
|
||||
save(image, "block-" + block.name + "-full");
|
||||
}
|
||||
|
||||
image.save("../editor/" + block.name + "-icon-editor");
|
||||
save(image, "../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());
|
||||
|
||||
if(icon == logicIcon && block.synthetic() && block.buildVisibility != BuildVisibility.hidden){
|
||||
image.save(block.name + "-icon-logic");
|
||||
}
|
||||
if(block.buildVisibility != BuildVisibility.hidden){
|
||||
saveScaled(image, block.name + "-icon-logic", logicIconSize);
|
||||
}
|
||||
saveScaled(image, "../ui/block-" + block.name + "-ui", Math.min(image.width, maxUiIcon));
|
||||
|
||||
boolean hasEmpty = false;
|
||||
Color average = new Color();
|
||||
Color average = new Color(), c = new Color();
|
||||
float asum = 0f;
|
||||
for(int x = 0; x < image.width; x++){
|
||||
for(int y = 0; y < image.height; y++){
|
||||
Color color = image.getColor(x, y);
|
||||
Color color = c.set(image.get(x, y));
|
||||
average.r += color.r*color.a;
|
||||
average.g += color.g*color.a;
|
||||
average.b += color.b*color.a;
|
||||
@@ -343,94 +341,81 @@ public class Generators{
|
||||
}
|
||||
//encode square sprite in alpha channel
|
||||
average.a = hasEmpty ? 0.1f : 1f;
|
||||
colors.draw(block.id, 0, average);
|
||||
colors.setRaw(block.id, 0, average.rgba());
|
||||
}catch(NullPointerException e){
|
||||
Log.err("Block &ly'@'&lr has an null region!", block);
|
||||
}
|
||||
}
|
||||
|
||||
colors.save("../../../assets/sprites/block_colors");
|
||||
save(colors, "../../../assets/sprites/block_colors");
|
||||
});
|
||||
|
||||
ImagePacker.generate("shallows", () -> {
|
||||
generate("shallows", () -> {
|
||||
content.blocks().<ShallowLiquid>each(b -> b instanceof ShallowLiquid, floor -> {
|
||||
Image overlay = ImagePacker.get(floor.liquidBase.region);
|
||||
Pixmap overlay = get(floor.liquidBase.region);
|
||||
int index = 0;
|
||||
for(TextureRegion region : floor.floorBase.variantRegions()){
|
||||
Image res = new Image(32, 32);
|
||||
res.draw(ImagePacker.get(region));
|
||||
Pixmap res = get(region).copy();
|
||||
for(int x = 0; x < res.width; x++){
|
||||
for(int y = 0; y < res.height; y++){
|
||||
Color color = overlay.getColor(x, y).a(floor.liquidOpacity);
|
||||
res.draw(x, y, color);
|
||||
res.set(x, y, Pixmap.blend((overlay.getRaw(x, y) & 0xffffff00) | (int)(floor.liquidOpacity * 255), res.getRaw(x, y)));
|
||||
}
|
||||
}
|
||||
|
||||
String name = floor.name + "" + (++index);
|
||||
res.save("../blocks/environment/" + name);
|
||||
res.save("../editor/editor-" + name);
|
||||
save(res, "../blocks/environment/" + name);
|
||||
save(res, "../editor/editor-" + name);
|
||||
|
||||
gens.put(floor, res);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ImagePacker.generate("item-icons", () -> {
|
||||
generate("item-icons", () -> {
|
||||
for(UnlockableContent item : Seq.<UnlockableContent>withArrays(content.items(), content.liquids(), content.statusEffects())){
|
||||
if(item instanceof StatusEffect && !ImagePacker.has(item.getContentType().name() + "-" + item.name)){
|
||||
if(item instanceof StatusEffect && !has(item.getContentType().name() + "-" + item.name)){
|
||||
continue;
|
||||
}
|
||||
|
||||
Image base = ImagePacker.get(item.getContentType().name() + "-" + item.name);
|
||||
Pixmap base = get(item.getContentType().name() + "-" + item.name);
|
||||
//tint status effect icon color
|
||||
if(item instanceof StatusEffect){
|
||||
StatusEffect stat = (StatusEffect)item;
|
||||
Image tint = base;
|
||||
base.each((x, y) -> tint.draw(x, y, tint.getColor(x, y).mul(stat.color)));
|
||||
Pixmap tint = base;
|
||||
base.each((x, y) -> tint.setRaw(x, y, Color.muli(tint.getRaw(x, y), stat.color.rgba())));
|
||||
|
||||
//outline the image
|
||||
Image container = new Image(38, 38);
|
||||
container.draw(base, 3, 3);
|
||||
base = container.outline(3, Pal.gray);
|
||||
Pixmap container = new Pixmap(38, 38);
|
||||
container.draw(base, 3, 3, true);
|
||||
base = container.outline(Pal.gray, 3);
|
||||
}
|
||||
|
||||
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 instanceof StatusEffect ? "../ui/" : "") + item.getContentType().name() + "-" + item.name + "-" + icon.name(), !(item instanceof StatusEffect));
|
||||
|
||||
if(icon == Cicon.medium){
|
||||
image.save("../ui/" + item.getContentType() + "-" + item.name + "-icon");
|
||||
}
|
||||
|
||||
if(icon == logicIcon){
|
||||
image.save(item.name + "-icon-logic");
|
||||
}
|
||||
}
|
||||
saveScaled(base, item.name + "-icon-logic", logicIconSize);
|
||||
save(base, "../ui/" + item.getContentType().name() + "-" + item.name + "-ui");
|
||||
}
|
||||
});
|
||||
|
||||
ImagePacker.generate("unit-icons", () -> content.units().each(type -> {
|
||||
//TODO broken, freezes
|
||||
generate("unit-icons", () -> content.units().each(type -> {
|
||||
if(type.isHidden()) return; //hidden units don't generate
|
||||
|
||||
ObjectSet<String> outlined = new ObjectSet<>();
|
||||
|
||||
try{
|
||||
type.load();
|
||||
type.loadIcon();
|
||||
type.init();
|
||||
|
||||
Color outc = Pal.darkerMetal;
|
||||
Func<Image, Image> outline = i -> i.outline(3, outc);
|
||||
Func<Pixmap, Pixmap> outline = i -> i.outline(Pal.darkerMetal, 3);
|
||||
Cons<TextureRegion> outliner = t -> {
|
||||
if(t != null && t.found()){
|
||||
ImagePacker.replace(t, outline.get(ImagePacker.get(t)));
|
||||
replace(t, outline.get(get(t)));
|
||||
}
|
||||
};
|
||||
|
||||
for(Weapon weapon : type.weapons){
|
||||
if(outlined.add(weapon.name) && ImagePacker.has(weapon.name)){
|
||||
outline.get(ImagePacker.get(weapon.name)).save(weapon.name + "-outline");
|
||||
if(outlined.add(weapon.name) && has(weapon.name)){
|
||||
save(outline.get(get(weapon.name)), weapon.name + "-outline");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,47 +425,54 @@ public class Generators{
|
||||
outliner.get(type.baseJointRegion);
|
||||
if(type.constructor.get() instanceof Legsc) outliner.get(type.legRegion);
|
||||
|
||||
Image image = outline.get(ImagePacker.get(type.region));
|
||||
Pixmap image = outline.get(get(type.region));
|
||||
|
||||
image.save(type.name + "-outline");
|
||||
save(image, type.name + "-outline");
|
||||
|
||||
//draw mech parts
|
||||
if(type.constructor.get() instanceof Mechc){
|
||||
image.drawCenter(type.baseRegion);
|
||||
image.drawCenter(type.legRegion);
|
||||
image.drawCenter(type.legRegion, true, false);
|
||||
image.draw(type.region);
|
||||
drawCenter(image, get(type.baseRegion));
|
||||
drawCenter(image, get(type.legRegion));
|
||||
drawCenter(image, get(type.legRegion).flipX());
|
||||
image.draw(get(type.region), true);
|
||||
}
|
||||
|
||||
//draw outlines
|
||||
for(Weapon weapon : type.weapons){
|
||||
weapon.load();
|
||||
|
||||
image.draw(outline.get(ImagePacker.get(weapon.region)),
|
||||
image.draw(weapon.flipSprite ? outline.get(get(weapon.region)).flipX() : outline.get(get(weapon.region)),
|
||||
(int)(weapon.x / Draw.scl + image.width / 2f - weapon.region.width / 2f),
|
||||
(int)(-weapon.y / Draw.scl + image.height / 2f - weapon.region.height / 2f),
|
||||
weapon.flipSprite, false);
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
//draw base region on top to mask weapons
|
||||
image.draw(type.region);
|
||||
image.draw(get(type.region), true);
|
||||
int baseColor = Color.valueOf("ffa665").rgba();
|
||||
|
||||
Image baseCell = ImagePacker.get(type.cellRegion);
|
||||
Image cell = new Image(type.cellRegion.width, type.cellRegion.height);
|
||||
cell.each((x, y) -> cell.draw(x, y, baseCell.getColor(x, y).mul(Color.valueOf("ffa665"))));
|
||||
Pixmap baseCell = get(type.cellRegion);
|
||||
Pixmap cell = new Pixmap(type.cellRegion.width, type.cellRegion.height);
|
||||
cell.each((x, y) -> cell.set(x, y, Color.muli(baseCell.getRaw(x, y), baseColor)));
|
||||
|
||||
image.draw(cell, image.width / 2 - cell.width / 2, image.height / 2 - cell.height / 2);
|
||||
image.draw(cell, image.width / 2 - cell.width / 2, image.height / 2 - cell.height / 2, true);
|
||||
|
||||
for(Weapon weapon : type.weapons){
|
||||
weapon.load();
|
||||
|
||||
image.draw(weapon.top ? outline.get(ImagePacker.get(weapon.region)) : ImagePacker.get(weapon.region),
|
||||
Pixmap wepReg = weapon.top ? outline.get(get(weapon.region)) : get(weapon.region);
|
||||
if(weapon.flipSprite){
|
||||
wepReg = wepReg.flipX();
|
||||
}
|
||||
|
||||
image.draw(wepReg,
|
||||
(int)(weapon.x / Draw.scl + image.width / 2f - weapon.region.width / 2f),
|
||||
(int)(-weapon.y / Draw.scl + image.height / 2f - weapon.region.height / 2f),
|
||||
weapon.flipSprite, false);
|
||||
true);
|
||||
}
|
||||
|
||||
image.save("unit-" + type.name + "-full");
|
||||
save(image, "unit-" + type.name + "-full");
|
||||
|
||||
Rand rand = new Rand();
|
||||
rand.setSeed(type.name.hashCode());
|
||||
@@ -492,9 +484,9 @@ public class Generators{
|
||||
float offsetRange = Math.max(image.width, image.height) * 0.15f;
|
||||
Vec2 offset = new Vec2(1, 1).rotate(rand.random(360f)).setLength(rand.random(0, offsetRange)).add(image.width/2f, image.height/2f);
|
||||
|
||||
Image[] wrecks = new Image[splits];
|
||||
Pixmap[] wrecks = new Pixmap[splits];
|
||||
for(int i = 0; i < wrecks.length; i++){
|
||||
wrecks[i] = new Image(image.width, image.height);
|
||||
wrecks[i] = new Pixmap(image.width, image.height);
|
||||
}
|
||||
|
||||
RidgedPerlin r = new RidgedPerlin(1, 3);
|
||||
@@ -510,92 +502,82 @@ public class Generators{
|
||||
//distort edges with random noise
|
||||
float noise = (float)Noise.rawNoise(dst / (9f + image.width/70f)) * (60 + image.width/30f);
|
||||
int section = (int)Mathf.clamp(Mathf.mod(offset.angleTo(x, y) + noise + degrees, 360f) / 360f * splits, 0, splits - 1);
|
||||
if(!vval) wrecks[section].draw(x, y, image.getColor(x, y).mul(rValue ? 0.7f : 1f));
|
||||
if(!vval) wrecks[section].setRaw(x, y, Color.muli(image.getRaw(x, y), rValue ? 0.7f : 1f));
|
||||
});
|
||||
|
||||
for(int i = 0; i < wrecks.length; i++){
|
||||
wrecks[i].save(type.name + "-wreck" + i);
|
||||
save(wrecks[i], "../rubble/" + type.name + "-wreck" + i);
|
||||
}
|
||||
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Vec2 size = Scaling.fit.apply(image.width, image.height, icon.size, icon.size);
|
||||
Image scaled = new Image((int)size.x, (int)size.y);
|
||||
int maxd = Math.min(Math.max(image.width, image.height), maxUiIcon);
|
||||
Pixmap fit = new Pixmap(maxd, maxd);
|
||||
drawScaledFit(fit, image);
|
||||
|
||||
scaled.drawScaled(image);
|
||||
scaled.save("../ui/unit-" + type.name + "-" + icon.name());
|
||||
|
||||
if(icon == logicIcon){
|
||||
scaled.save(type.name + "-icon-logic");
|
||||
}
|
||||
}
|
||||
saveScaled(fit, type.name + "-icon-logic", logicIconSize);
|
||||
save(fit, "../ui/unit-" + type.name + "-ui");
|
||||
}catch(IllegalArgumentException e){
|
||||
Log.err("WARNING: Skipping unit @: @", type.name, e.getMessage());
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
ImagePacker.generate("ore-icons", () -> {
|
||||
generate("ore-icons", () -> {
|
||||
content.blocks().<OreBlock>each(b -> b instanceof OreBlock, ore -> {
|
||||
String prefix = ore instanceof WallOreBlock ? "wall-ore-" : "ore-";
|
||||
Item item = ore.itemDrop;
|
||||
int shadowColor = Color.rgba8888(0, 0, 0, 0.3f);
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
for(int i = 0; i < ore.variants; i++){
|
||||
//get base image to draw on
|
||||
Image image = new Image(32, 32);
|
||||
Image shadow = ImagePacker.get(item.name + (i + 1));
|
||||
Pixmap base = get((ore instanceof WallOreBlock ? "wall-" : "") + item.name + (i + 1));
|
||||
Pixmap image = base.copy();
|
||||
|
||||
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);
|
||||
if(base.getA(x, y - offset) != 0){
|
||||
image.setRaw(x, y, Pixmap.blend(shadowColor, base.getRaw(x, y)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
image.draw(base, true);
|
||||
save(image, "../blocks/environment/" + prefix + item.name + (i + 1));
|
||||
save(image, "../editor/editor-" + prefix + item.name + (i + 1));
|
||||
|
||||
image.save("block-" + ore.name + "-full");
|
||||
for(Cicon icon : Cicon.scaled){
|
||||
Image scaled = new Image(icon.size, icon.size);
|
||||
scaled.drawScaled(image);
|
||||
scaled.save("../ui/block-" + ore.name + "-" + icon.name());
|
||||
}
|
||||
save(image, "block-" + ore.name + "-full");
|
||||
save(image, "../ui/block-" + ore.name + "-ui");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ImagePacker.generate("edges", () -> {
|
||||
generate("edges", () -> {
|
||||
content.blocks().<Floor>each(b -> b instanceof Floor && !(b instanceof OverlayFloor), floor -> {
|
||||
|
||||
if(ImagePacker.has(floor.name + "-edge") || floor.blendGroup != floor){
|
||||
if(has(floor.name + "-edge") || floor.blendGroup != floor){
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
Image image = gens.get(floor, ImagePacker.get(floor.getGeneratedIcons()[0]));
|
||||
Image edge = ImagePacker.get("edge-stencil");
|
||||
Image result = new Image(edge.width, edge.height);
|
||||
Pixmap image = gens.get(floor, get(floor.getGeneratedIcons()[0]));
|
||||
Pixmap edge = get("edge-stencil");
|
||||
Pixmap result = new Pixmap(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.set(x, y, Color.muli(edge.getRaw(x, y), image.get(x % image.width, y % image.height)));
|
||||
}
|
||||
}
|
||||
|
||||
result.save("../blocks/environment/" + floor.name + "-edge");
|
||||
save(result, "../blocks/environment/" + floor.name + "-edge");
|
||||
|
||||
}catch(Exception ignored){}
|
||||
});
|
||||
});
|
||||
|
||||
ImagePacker.generate("scorches", () -> {
|
||||
generate("scorches", () -> {
|
||||
for(int size = 0; size < 10; size++){
|
||||
for(int i = 0; i < 3; i++){
|
||||
ScorchGenerator gen = new ScorchGenerator();
|
||||
@@ -615,7 +597,7 @@ public class Generators{
|
||||
|
||||
Pixmap out = gen.generate();
|
||||
Pixmap median = Pixmaps.median(out, 2, 0.75);
|
||||
Fi.get("../rubble/scorch-" + size + "-" + i + ".png").writePNG(median);
|
||||
Fi.get("../rubble/scorch-" + size + "-" + i + ".png").writePng(median);
|
||||
out.dispose();
|
||||
median.dispose();
|
||||
}
|
||||
@@ -623,4 +605,30 @@ public class Generators{
|
||||
});
|
||||
}
|
||||
|
||||
/** Generates a scorch pixmap based on parameters. Thread safe, unless multiple scorch generators are running in parallel. */
|
||||
public static class ScorchGenerator{
|
||||
private static final Simplex sim = new Simplex();
|
||||
|
||||
public int size = 80, seed = 0, color = Color.whiteRgba;
|
||||
public double scale = 18, pow = 2, octaves = 4, pers = 0.4, add = 2, nscl = 4.5f;
|
||||
|
||||
public Pixmap generate(){
|
||||
Pixmap pix = new Pixmap(size, size);
|
||||
sim.setSeed(seed);
|
||||
|
||||
pix.each((x, y) -> {
|
||||
double dst = Mathf.dst(x, y, size/2, size/2) / (size / 2f);
|
||||
double scaled = Math.abs(dst - 0.5f) * 5f + add;
|
||||
scaled -= noise(Angles.angle(x, y, size/2, size/2))*nscl;
|
||||
if(scaled < 1.5f) pix.setRaw(x, y, color);
|
||||
});
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
private double noise(float angle){
|
||||
return Math.pow(sim.octaveNoise2D(octaves, pers, 1 / scale, Angles.trnsx(angle, size/2f) + size/2f, Angles.trnsy(angle, size/2f) + size/2f), pow);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ public class IconConverter{
|
||||
Fi.get("fontgen/icon_parts").deleteDirectory();
|
||||
Fi[] list = new Fi("icons").list();
|
||||
|
||||
ArcNativesLoader.load();
|
||||
Seq<Fi> files = new Seq<>();
|
||||
|
||||
for(Fi img : list){
|
||||
@@ -42,25 +41,25 @@ public class IconConverter{
|
||||
}
|
||||
|
||||
void convert(Pixmap pixmap, Fi output){
|
||||
boolean[][] grid = new boolean[pixmap.getWidth()][pixmap.getHeight()];
|
||||
boolean[][] grid = new boolean[pixmap.width][pixmap.height];
|
||||
|
||||
for(int x = 0; x < pixmap.getWidth(); x++){
|
||||
for(int y = 0; y < pixmap.getHeight(); y++){
|
||||
grid[x][pixmap.getHeight() - 1 - y] = !Pixmaps.empty(pixmap.getPixel(x, y));
|
||||
for(int x = 0; x < pixmap.width; x++){
|
||||
for(int y = 0; y < pixmap.height; y++){
|
||||
grid[x][pixmap.height - 1 - y] = !pixmap.empty(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
float xscl = 1f, yscl = 1f;//resolution / (float)pixmap.getWidth(), yscl = resolution / (float)pixmap.getHeight();
|
||||
float scl = xscl;
|
||||
|
||||
width = pixmap.getWidth();
|
||||
height = pixmap.getHeight();
|
||||
width = pixmap.width;
|
||||
height = pixmap.height;
|
||||
|
||||
out.append("<svg width=\"").append(pixmap.getWidth()).append("\" height=\"").append(pixmap.getHeight()).append("\">\n");
|
||||
out.append("<svg width=\"").append(pixmap.width).append("\" height=\"").append(pixmap.height).append("\">\n");
|
||||
|
||||
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);
|
||||
for(int x = -1; x < pixmap.width; x++){
|
||||
for(int y = -1; y < pixmap.height; y++){
|
||||
int index = index(x, y, pixmap.width, pixmap.height, 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;
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
package mindustry.tools;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.graphics.Color;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.tools.ImagePacker.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
|
||||
class Image{
|
||||
private static Seq<Image> toDispose = new Seq<>();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
Image copy(){
|
||||
Image out =new Image(width, height);
|
||||
out.draw(this);
|
||||
return out;
|
||||
}
|
||||
|
||||
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.argb8888(i);
|
||||
return color;
|
||||
}
|
||||
|
||||
Image outline(int radius, Color outlineColor){
|
||||
Image out = copy();
|
||||
for(int x = 0; x < out.width; x++){
|
||||
for(int y = 0; y < out.height; y++){
|
||||
|
||||
Color color = 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 && getColor(rx + x, ry + y).a > 0.01f){
|
||||
found = true;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
out.draw(x, y, outlineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Image shadow(float alpha, int rad){
|
||||
Image out = silhouette(new Color(0f, 0f, 0f, alpha)).blur(rad);
|
||||
out.draw(this);
|
||||
return out;
|
||||
}
|
||||
|
||||
Image silhouette(Color color){
|
||||
Image out = copy();
|
||||
|
||||
each((x, y) -> out.draw(x, y, getColor(x, y).set(color.r, color.g, color.b, this.color.a * color.a)));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Image blur(int radius){
|
||||
Image out = copy();
|
||||
Color c = new Color();
|
||||
int[] sum = {0};
|
||||
|
||||
for(int x = 0; x < out.width; x++){
|
||||
for(int y = 0; y < out.height; y++){
|
||||
sum[0] = 0;
|
||||
|
||||
Geometry.circle(x, y, radius, (cx, cy) -> {
|
||||
int rx = Mathf.clamp(cx, 0, out.width - 1), ry = Mathf.clamp(cy, 0, out.height - 1);
|
||||
|
||||
Color other = getColor(rx, ry);
|
||||
c.r += other.r;
|
||||
c.g += other.g;
|
||||
c.b += other.b;
|
||||
c.a += other.a;
|
||||
sum[0] ++;
|
||||
});
|
||||
|
||||
c.mula(1f / sum[0]);
|
||||
|
||||
out.draw(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void each(Intc2 cons){
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
cons.get(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.width) / 2, (height - region.height) / 2, false, false);
|
||||
}
|
||||
|
||||
/** Draws a region at the center. */
|
||||
void drawCenter(TextureRegion region, boolean flipx, boolean flipy){
|
||||
draw(region, (width - region.width) / 2, (height - region.height) / 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);
|
||||
|
||||
draw(ImagePacker.get(region), x, y, flipx, flipy);
|
||||
}
|
||||
|
||||
void draw(Image region, int x, int y, boolean flipx, boolean flipy){
|
||||
|
||||
int ofx = 0, ofy = 0;
|
||||
|
||||
graphics.drawImage(region.image,
|
||||
x, y,
|
||||
x + region.width,
|
||||
y + region.height,
|
||||
(flipx ? region.width : 0) + ofx,
|
||||
(flipy ? region.height : 0) + ofy,
|
||||
(flipx ? 0 : region.width) + ofx,
|
||||
(flipy ? 0 : region.height) + 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();
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package mindustry.tools;
|
||||
|
||||
import arc.*;
|
||||
import arc.files.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.graphics.g2d.TextureAtlas.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.Log.*;
|
||||
@@ -12,20 +14,16 @@ import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
|
||||
public class ImagePacker{
|
||||
static ObjectMap<String, TextureRegion> regionCache = new ObjectMap<>();
|
||||
static ObjectMap<String, BufferedImage> imageCache = new ObjectMap<>();
|
||||
static ObjectMap<String, PackIndex> cache = new ObjectMap<>();
|
||||
|
||||
public static void main(String[] args) throws Exception{
|
||||
Vars.headless = true;
|
||||
//makes PNG loading slightly faster
|
||||
ArcNativesLoader.load();
|
||||
|
||||
Log.logger = new NoopLogHandler();
|
||||
@@ -36,66 +34,59 @@ public class ImagePacker{
|
||||
Fi.get("../../../assets-raw/sprites_out").walk(path -> {
|
||||
if(!path.extEquals("png")) return;
|
||||
|
||||
String fname = path.nameWithoutExtension();
|
||||
|
||||
try{
|
||||
BufferedImage image = ImageIO.read(path.file());
|
||||
|
||||
if(image == null) throw new IOException("image " + path.absolutePath() + " is null for terrible reasons");
|
||||
GenRegion region = new GenRegion(fname, path){{
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
u2 = v2 = 1f;
|
||||
u = v = 0f;
|
||||
}};
|
||||
|
||||
regionCache.put(fname, region);
|
||||
imageCache.put(fname, image);
|
||||
}catch(IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cache.put(path.nameWithoutExtension(), new PackIndex(path));
|
||||
});
|
||||
|
||||
Core.atlas = new TextureAtlas(){
|
||||
@Override
|
||||
public AtlasRegion find(String name){
|
||||
if(!regionCache.containsKey(name)){
|
||||
if(!cache.containsKey(name)){
|
||||
GenRegion region = new GenRegion(name, null);
|
||||
region.invalid = true;
|
||||
return region;
|
||||
}
|
||||
return (AtlasRegion)regionCache.get(name);
|
||||
|
||||
PackIndex index = cache.get(name);
|
||||
if(index.pixmap == null){
|
||||
index.pixmap = new Pixmap(index.file);
|
||||
index.region = new GenRegion(name, index.file){{
|
||||
width = index.pixmap.width;
|
||||
height = index.pixmap.height;
|
||||
u2 = v2 = 1f;
|
||||
u = v = 0f;
|
||||
}};
|
||||
}
|
||||
return index.region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasRegion find(String name, TextureRegion def){
|
||||
if(!regionCache.containsKey(name)){
|
||||
if(!cache.containsKey(name)){
|
||||
return (AtlasRegion)def;
|
||||
}
|
||||
return (AtlasRegion)regionCache.get(name);
|
||||
return find(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasRegion find(String name, String def){
|
||||
if(!regionCache.containsKey(name)){
|
||||
return (AtlasRegion)regionCache.get(def);
|
||||
if(!cache.containsKey(name)){
|
||||
return find(def);
|
||||
}
|
||||
return (AtlasRegion)regionCache.get(name);
|
||||
return find(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String s){
|
||||
return regionCache.containsKey(s);
|
||||
return cache.containsKey(s);
|
||||
}
|
||||
};
|
||||
|
||||
Draw.scl = 1f / Core.atlas.find("scale_marker").width;
|
||||
|
||||
Time.mark();
|
||||
Generators.generate();
|
||||
Generators.run();
|
||||
Log.info("&ly[Generator]&lc Total time to generate: &lg@&lcms", Time.elapsed());
|
||||
Log.info("&ly[Generator]&lc Total images created: &lg@", Image.total());
|
||||
Image.dispose();
|
||||
//Log.info("&ly[Generator]&lc Total images created: &lg@", Image.total());
|
||||
|
||||
//format:
|
||||
//character-ID=contentname:texture-name
|
||||
@@ -130,9 +121,7 @@ public class ImagePacker{
|
||||
}
|
||||
|
||||
static String texname(UnlockableContent c){
|
||||
if(c instanceof Block) return "block-" + c.name + "-medium";
|
||||
if(c instanceof UnitType) return "unit-" + c.name + "-medium";
|
||||
return c.getContentType() + "-" + c.name + "-icon";
|
||||
return c.getContentType() + "-" + c.name + "-ui";
|
||||
}
|
||||
|
||||
static void generate(String name, Runnable run){
|
||||
@@ -141,15 +130,7 @@ public class ImagePacker{
|
||||
Log.info("&ly[Generator]&lc Time to generate &lm@&lc: &lg@&lcms", name, Time.elapsed());
|
||||
}
|
||||
|
||||
static BufferedImage buf(TextureRegion region){
|
||||
return imageCache.get(((AtlasRegion)region).name);
|
||||
}
|
||||
|
||||
static Image create(int width, int height){
|
||||
return new Image(width, height);
|
||||
}
|
||||
|
||||
static Image get(String name){
|
||||
static Pixmap get(String name){
|
||||
return get(Core.atlas.find(name));
|
||||
}
|
||||
|
||||
@@ -157,18 +138,40 @@ public class ImagePacker{
|
||||
return Core.atlas.has(name);
|
||||
}
|
||||
|
||||
static Image get(TextureRegion region){
|
||||
GenRegion.validate(region);
|
||||
static Pixmap get(TextureRegion region){
|
||||
validate(region);
|
||||
|
||||
return new Image(imageCache.get(((AtlasRegion)region).name));
|
||||
return cache.get(((AtlasRegion)region).name).pixmap.copy();
|
||||
}
|
||||
|
||||
static void replace(String name, Image image){
|
||||
image.save(name);
|
||||
static void save(Pixmap pix, String path){
|
||||
Fi.get(path + ".png").writePng(pix);
|
||||
}
|
||||
|
||||
static void drawCenter(Pixmap pix, Pixmap other){
|
||||
pix.draw(other, pix.width/2 - other.width/2, pix.height/2 - other.height/2, true);
|
||||
}
|
||||
|
||||
static void saveScaled(Pixmap pix, String name, int size){
|
||||
Pixmap scaled = new Pixmap(size, size);
|
||||
//TODO bad linear scaling
|
||||
scaled.draw(pix, 0, 0, pix.width, pix.height, 0, 0, size, size, true, true);
|
||||
save(scaled, name);
|
||||
}
|
||||
|
||||
static void drawScaledFit(Pixmap base, Pixmap image){
|
||||
Vec2 size = Scaling.fit.apply(image.width, image.height, base.width, base.height);
|
||||
int wx = (int)size.x, wy = (int)size.y;
|
||||
//TODO bad linear scaling
|
||||
base.draw(image, 0, 0, image.width, image.height, base.width/2 - wx/2, base.height/2 - wy/2, wx, wy, true, true);
|
||||
}
|
||||
|
||||
static void replace(String name, Pixmap image){
|
||||
Fi.get(name + ".png").writePng(image);
|
||||
((GenRegion)Core.atlas.find(name)).path.delete();
|
||||
}
|
||||
|
||||
static void replace(TextureRegion region, Image image){
|
||||
static void replace(TextureRegion region, Pixmap image){
|
||||
replace(((GenRegion)region).name, image);
|
||||
}
|
||||
|
||||
@@ -176,6 +179,12 @@ public class ImagePacker{
|
||||
throw new IllegalArgumentException(Strings.format(message, args));
|
||||
}
|
||||
|
||||
static void validate(TextureRegion region){
|
||||
if(((GenRegion)region).invalid){
|
||||
ImagePacker.err("Region does not exist: @", ((GenRegion)region).name);
|
||||
}
|
||||
}
|
||||
|
||||
static class GenRegion extends AtlasRegion{
|
||||
boolean invalid;
|
||||
Fi path;
|
||||
@@ -190,11 +199,15 @@ public class ImagePacker{
|
||||
public boolean found(){
|
||||
return !invalid;
|
||||
}
|
||||
}
|
||||
|
||||
static void validate(TextureRegion region){
|
||||
if(((GenRegion)region).invalid){
|
||||
ImagePacker.err("Region does not exist: @", ((GenRegion)region).name);
|
||||
}
|
||||
static class PackIndex{
|
||||
@Nullable AtlasRegion region;
|
||||
@Nullable Pixmap pixmap;
|
||||
Fi file;
|
||||
|
||||
public PackIndex(Fi file){
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,15 +79,18 @@ public class ScriptMainGenerator{
|
||||
"mindustry.entities.abilities",
|
||||
"mindustry.ai.types",
|
||||
"mindustry.type.weather",
|
||||
"mindustry.type.weapons",
|
||||
"mindustry.game.Objectives",
|
||||
"mindustry.world.blocks",
|
||||
"mindustry.world.draw"
|
||||
"mindustry.world.draw",
|
||||
"mindustry.type"
|
||||
);
|
||||
|
||||
String classTemplate = "package mindustry.mod;\n" +
|
||||
"\n" +
|
||||
"import arc.struct.*;\n" +
|
||||
"/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */\n" +
|
||||
"@SuppressWarnings(\"deprecation\")\n" +
|
||||
"public class ClassMap{\n" +
|
||||
" public static final ObjectMap<String, Class<?>> classes = new ObjectMap<>();\n" +
|
||||
" \n" +
|
||||
|
||||
Reference in New Issue
Block a user