Static wall autotile support
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
package mindustry.world.blocks;
|
package mindustry.world.blocks;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
|
||||||
public class TileBitmask{
|
public class TileBitmask{
|
||||||
/** Autotile bitmasks for 8-directional sprites (see <a href="https://github.com/GglLfr/tile-gen">tile-gen</a>)*/
|
/** Autotile bitmasks for 8-directional sprites (see <a href="https://github.com/GglLfr/tile-gen">tile-gen</a>)*/
|
||||||
public static final int[] values = {
|
public static final int[] values = {
|
||||||
@@ -20,4 +23,12 @@ public class TileBitmask{
|
|||||||
3, 0, 3, 0, 15, 42, 15, 12, 3, 0, 3, 0, 15, 42, 15, 12,
|
3, 0, 3, 0, 15, 42, 15, 12, 3, 0, 3, 0, 15, 42, 15, 12,
|
||||||
2, 1, 2, 1, 9, 45, 9, 19, 2, 1, 2, 1, 14, 18, 14, 13,
|
2, 1, 2, 1, 9, 45, 9, 19, 2, 1, 2, 1, 14, 18, 14, 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static TextureRegion[] load(String name){
|
||||||
|
var regions = new TextureRegion[47];
|
||||||
|
for(int i = 0; i < 47; i++){
|
||||||
|
regions[i] = Core.atlas.find(name + "-" + i);
|
||||||
|
}
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,10 +141,7 @@ public class Floor extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(autotile){
|
if(autotile){
|
||||||
autotileRegions = new TextureRegion[47];
|
autotileRegions = TileBitmask.load(name);
|
||||||
for(int i = 0; i < 47; i++){
|
|
||||||
autotileRegions[i] = Core.atlas.find(name + "-" + i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Core.atlas.has(name + "-edge")){
|
if(Core.atlas.has(name + "-edge")){
|
||||||
|
|||||||
@@ -8,12 +8,17 @@ import mindustry.annotations.Annotations.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class StaticWall extends Prop{
|
public class StaticWall extends Prop{
|
||||||
public @Load("@-large") TextureRegion large;
|
public @Load("@-large") TextureRegion large;
|
||||||
public TextureRegion[][] split;
|
public TextureRegion[][] split;
|
||||||
|
/** If true, this wall uses autotiling; variants are not supported. See https://github.com/GglLfr/tile-gen*/
|
||||||
|
public boolean autotile;
|
||||||
|
|
||||||
|
protected TextureRegion[] autotileRegions;
|
||||||
|
|
||||||
public StaticWall(String name){
|
public StaticWall(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -30,15 +35,28 @@ public class StaticWall extends Prop{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawBase(Tile tile){
|
public void drawBase(Tile tile){
|
||||||
int rx = tile.x / 2 * 2;
|
if(autotile){
|
||||||
int ry = tile.y / 2 * 2;
|
int bits = 0;
|
||||||
|
|
||||||
if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Point2.pack(rx, ry)) < 0.5 && split.length >= 2 && split[0].length >= 2){
|
for(int i = 0; i < 8; i++){
|
||||||
Draw.rect(split[tile.x % 2][1 - tile.y % 2], tile.worldx(), tile.worldy());
|
Tile other = tile.nearby(Geometry.d8[i]);
|
||||||
}else if(variants > 0){
|
if(other != null && other.block() == this){
|
||||||
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
bits |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.rect(autotileRegions[TileBitmask.values[bits]], tile.worldx(), tile.worldy());
|
||||||
}else{
|
}else{
|
||||||
Draw.rect(region, tile.worldx(), tile.worldy());
|
int rx = tile.x / 2 * 2;
|
||||||
|
int ry = tile.y / 2 * 2;
|
||||||
|
|
||||||
|
if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Point2.pack(rx, ry)) < 0.5 && split.length >= 2 && split[0].length >= 2){
|
||||||
|
Draw.rect(split[tile.x % 2][1 - tile.y % 2], tile.worldx(), tile.worldy());
|
||||||
|
}else if(variants > 0){
|
||||||
|
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
||||||
|
}else{
|
||||||
|
Draw.rect(region, tile.worldx(), tile.worldy());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw ore on top
|
//draw ore on top
|
||||||
@@ -59,6 +77,10 @@ public class StaticWall extends Prop{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(autotile){
|
||||||
|
autotileRegions = TileBitmask.load(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import static mindustry.Vars.*;
|
|||||||
|
|
||||||
public class LogicBlock extends Block{
|
public class LogicBlock extends Block{
|
||||||
private static final int maxByteLen = 1024 * 100;
|
private static final int maxByteLen = 1024 * 100;
|
||||||
|
private static final int maxLinks = 6000;
|
||||||
public static final int maxNameLength = 32;
|
public static final int maxNameLength = 32;
|
||||||
|
|
||||||
public int maxInstructionScale = 5;
|
public int maxInstructionScale = 5;
|
||||||
@@ -198,7 +199,7 @@ public class LogicBlock extends Block{
|
|||||||
byte[] bytes = new byte[bytelen];
|
byte[] bytes = new byte[bytelen];
|
||||||
stream.readFully(bytes);
|
stream.readFully(bytes);
|
||||||
|
|
||||||
int total = stream.readInt();
|
int total = Math.min(stream.readInt(), maxLinks);
|
||||||
|
|
||||||
Seq<LogicLink> links = new Seq<>();
|
Seq<LogicLink> links = new Seq<>();
|
||||||
|
|
||||||
@@ -274,7 +275,7 @@ public class LogicBlock extends Block{
|
|||||||
|
|
||||||
links.clear();
|
links.clear();
|
||||||
|
|
||||||
int total = stream.readInt();
|
int total = Math.min(stream.readInt(), maxLinks);
|
||||||
|
|
||||||
if(version == 0){
|
if(version == 0){
|
||||||
//old version just had links, ignore those
|
//old version just had links, ignore those
|
||||||
|
|||||||
@@ -70,23 +70,32 @@ public class Generators{
|
|||||||
ObjectMap<Block, Pixmap> gens = new ObjectMap<>();
|
ObjectMap<Block, Pixmap> gens = new ObjectMap<>();
|
||||||
|
|
||||||
generate("autotiles", () -> {
|
generate("autotiles", () -> {
|
||||||
for(Floor floor : content.blocks().select(b -> b.isFloor() && b.asFloor().autotile).<Floor>as()){
|
for(Block block : content.blocks().select(b -> (b.isFloor() && b.asFloor().autotile) || (b instanceof StaticWall && ((StaticWall)b).autotile))){
|
||||||
Fi basePath = new Fi("../../../assets-raw/sprites_out/blocks/environment/" + floor.name + "-autotile.png");
|
Fi basePath = new Fi("../../../assets-raw/sprites_out/blocks/environment/" + block.name + "-autotile.png"), iconPath = basePath.parent().child(block.name + ".png");
|
||||||
|
|
||||||
if(basePath.exists()){
|
if(basePath.exists()){
|
||||||
//theoretically this might not finish in time, but I doubt that will ever happen
|
//theoretically this might not finish in time, but I doubt that will ever happen
|
||||||
mainExecutor.submit(() -> {
|
mainExecutor.submit(() -> {
|
||||||
try{
|
try{
|
||||||
ImageTileGenerator.generate(basePath, floor.name, new Fi("../../../assets-raw/sprites_out/blocks/environment/" + floor.name));
|
ImageTileGenerator.generate(basePath, block.name, new Fi("../../../assets-raw/sprites_out/blocks/environment/" + block.name));
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
Log.err("Failed to autotile: " + floor.name, e);
|
Log.err("Failed to autotile: " + block.name, e);
|
||||||
}finally{
|
}finally{
|
||||||
//the raw autotile source image must never be included, it isn't useful
|
//the raw autotile source image must never be included, it isn't useful
|
||||||
basePath.delete();
|
basePath.delete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!iconPath.exists()){
|
||||||
|
//save the bottom right region as the "main" sprite for previews
|
||||||
|
Pixmap out = new Pixmap(basePath);
|
||||||
|
Pixmap cropped = out.crop(96, 96, 32, 32);
|
||||||
|
iconPath.writePng(cropped);
|
||||||
|
out.dispose();
|
||||||
|
gens.put(block, cropped);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
Log.warn("Autotile floor '@' not found: @", floor.name, basePath.absolutePath());
|
Log.warn("Autotile floor '@' not found: @", block.name, basePath.absolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -819,14 +828,15 @@ public class Generators{
|
|||||||
});
|
});
|
||||||
|
|
||||||
generate("edges", () -> {
|
generate("edges", () -> {
|
||||||
content.blocks().<Floor>each(b -> b instanceof Floor && !(b instanceof OverlayFloor), floor -> {
|
content.blocks().<Floor>each(b -> b instanceof Floor && !(b instanceof OverlayFloor) && !b.isAir(), floor -> {
|
||||||
|
|
||||||
if(has(floor.name + "-edge") || floor.blendGroup != floor){
|
if(has(floor.name + "-edge") || floor.blendGroup != floor){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Pixmap image = gens.get(floor, get(floor.getGeneratedIcons()[0]));
|
Pixmap image = gens.get(floor);
|
||||||
|
if(image == null) image = get(floor.getGeneratedIcons()[0]);
|
||||||
Pixmap edge = get("edge-stencil");
|
Pixmap edge = get("edge-stencil");
|
||||||
Pixmap result = new Pixmap(edge.width, edge.height);
|
Pixmap result = new Pixmap(edge.width, edge.height);
|
||||||
|
|
||||||
@@ -838,7 +848,9 @@ public class Generators{
|
|||||||
|
|
||||||
save(result, "../blocks/environment/" + floor.name + "-edge");
|
save(result, "../blocks/environment/" + floor.name + "-edge");
|
||||||
|
|
||||||
}catch(Exception ignored){}
|
}catch(Exception e){
|
||||||
|
Log.err("Failed to generate edge for " + floor, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user