diff --git a/core/src/mindustry/world/blocks/TileBitmask.java b/core/src/mindustry/world/blocks/TileBitmask.java
index f911469267..b8ebacf6a9 100644
--- a/core/src/mindustry/world/blocks/TileBitmask.java
+++ b/core/src/mindustry/world/blocks/TileBitmask.java
@@ -1,5 +1,8 @@
package mindustry.world.blocks;
+import arc.*;
+import arc.graphics.g2d.*;
+
public class TileBitmask{
/** Autotile bitmasks for 8-directional sprites (see tile-gen)*/
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,
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;
+ }
}
diff --git a/core/src/mindustry/world/blocks/environment/Floor.java b/core/src/mindustry/world/blocks/environment/Floor.java
index 7b9f9ebe3f..343c94f50b 100644
--- a/core/src/mindustry/world/blocks/environment/Floor.java
+++ b/core/src/mindustry/world/blocks/environment/Floor.java
@@ -141,10 +141,7 @@ public class Floor extends Block{
}
if(autotile){
- autotileRegions = new TextureRegion[47];
- for(int i = 0; i < 47; i++){
- autotileRegions[i] = Core.atlas.find(name + "-" + i);
- }
+ autotileRegions = TileBitmask.load(name);
}
if(Core.atlas.has(name + "-edge")){
diff --git a/core/src/mindustry/world/blocks/environment/StaticWall.java b/core/src/mindustry/world/blocks/environment/StaticWall.java
index c65c8a186b..a287b2a419 100644
--- a/core/src/mindustry/world/blocks/environment/StaticWall.java
+++ b/core/src/mindustry/world/blocks/environment/StaticWall.java
@@ -8,12 +8,17 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.graphics.*;
import mindustry.world.*;
+import mindustry.world.blocks.*;
import static mindustry.Vars.*;
public class StaticWall extends Prop{
public @Load("@-large") TextureRegion large;
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){
super(name);
@@ -30,15 +35,28 @@ public class StaticWall extends Prop{
@Override
public void drawBase(Tile tile){
- int rx = tile.x / 2 * 2;
- int ry = tile.y / 2 * 2;
+ if(autotile){
+ 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){
- 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());
+ for(int i = 0; i < 8; i++){
+ Tile other = tile.nearby(Geometry.d8[i]);
+ if(other != null && other.block() == this){
+ bits |= (1 << i);
+ }
+ }
+
+ Draw.rect(autotileRegions[TileBitmask.values[bits]], tile.worldx(), tile.worldy());
}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
@@ -59,6 +77,10 @@ public class StaticWall extends Prop{
}
}
}
+
+ if(autotile){
+ autotileRegions = TileBitmask.load(name);
+ }
}
@Override
diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java
index d4de29df11..8d1dfe0683 100644
--- a/core/src/mindustry/world/blocks/logic/LogicBlock.java
+++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java
@@ -32,6 +32,7 @@ import static mindustry.Vars.*;
public class LogicBlock extends Block{
private static final int maxByteLen = 1024 * 100;
+ private static final int maxLinks = 6000;
public static final int maxNameLength = 32;
public int maxInstructionScale = 5;
@@ -198,7 +199,7 @@ public class LogicBlock extends Block{
byte[] bytes = new byte[bytelen];
stream.readFully(bytes);
- int total = stream.readInt();
+ int total = Math.min(stream.readInt(), maxLinks);
Seq links = new Seq<>();
@@ -274,7 +275,7 @@ public class LogicBlock extends Block{
links.clear();
- int total = stream.readInt();
+ int total = Math.min(stream.readInt(), maxLinks);
if(version == 0){
//old version just had links, ignore those
diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java
index 8fbda7d9f8..a7c46b41e6 100644
--- a/tools/src/mindustry/tools/Generators.java
+++ b/tools/src/mindustry/tools/Generators.java
@@ -70,23 +70,32 @@ public class Generators{
ObjectMap gens = new ObjectMap<>();
generate("autotiles", () -> {
- for(Floor floor : content.blocks().select(b -> b.isFloor() && b.asFloor().autotile).as()){
- Fi basePath = new Fi("../../../assets-raw/sprites_out/blocks/environment/" + floor.name + "-autotile.png");
+ 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/" + block.name + "-autotile.png"), iconPath = basePath.parent().child(block.name + ".png");
if(basePath.exists()){
//theoretically this might not finish in time, but I doubt that will ever happen
mainExecutor.submit(() -> {
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){
- Log.err("Failed to autotile: " + floor.name, e);
+ Log.err("Failed to autotile: " + block.name, e);
}finally{
//the raw autotile source image must never be included, it isn't useful
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{
- 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", () -> {
- content.blocks().each(b -> b instanceof Floor && !(b instanceof OverlayFloor), floor -> {
+ content.blocks().each(b -> b instanceof Floor && !(b instanceof OverlayFloor) && !b.isAir(), floor -> {
if(has(floor.name + "-edge") || floor.blendGroup != floor){
return;
}
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 result = new Pixmap(edge.width, edge.height);
@@ -838,7 +848,9 @@ public class Generators{
save(result, "../blocks/environment/" + floor.name + "-edge");
- }catch(Exception ignored){}
+ }catch(Exception e){
+ Log.err("Failed to generate edge for " + floor, e);
+ }
});
});