Implemented #1329
|
Before Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 98 B |
|
Before Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 474 B |
|
Before Width: | Height: | Size: 488 B |
|
Before Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 339 B |
@@ -235,3 +235,5 @@
|
|||||||
63509=basic-reconstructor|block-basic-reconstructor-medium
|
63509=basic-reconstructor|block-basic-reconstructor-medium
|
||||||
63508=block-loader|block-block-loader-medium
|
63508=block-loader|block-block-loader-medium
|
||||||
63507=block-unloader|block-block-unloader-medium
|
63507=block-unloader|block-block-unloader-medium
|
||||||
|
63506=core-silo|block-core-silo-medium
|
||||||
|
63505=data-processor|block-data-processor-medium
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 740 B |
|
Before Width: | Height: | Size: 829 KiB After Width: | Height: | Size: 824 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 270 KiB |
|
Before Width: | Height: | Size: 876 KiB After Width: | Height: | Size: 887 KiB |
@@ -136,6 +136,9 @@ public class ContentLoader{
|
|||||||
|
|
||||||
Block block = block(i);
|
Block block = block(i);
|
||||||
block.mapColor.rgba8888(color);
|
block.mapColor.rgba8888(color);
|
||||||
|
//partial alpha colors indicate a square sprite
|
||||||
|
block.squareSprite = block.mapColor.a > 0.5f;
|
||||||
|
block.mapColor.a = 1f;
|
||||||
block.hasColor = true;
|
block.hasColor = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ public class Layer{
|
|||||||
//things such as spent casings or rubble
|
//things such as spent casings or rubble
|
||||||
debris = 20,
|
debris = 20,
|
||||||
|
|
||||||
|
//stuff under blocks, like connections of conveyors/conduits
|
||||||
|
blockUnder = 29.5f,
|
||||||
|
|
||||||
//base block layer - most blocks go here
|
//base block layer - most blocks go here
|
||||||
block = 30,
|
block = 30,
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ public class Block extends UnlockableContent{
|
|||||||
public boolean placeableOn = true;
|
public boolean placeableOn = true;
|
||||||
/** whether this block has insulating properties. */
|
/** whether this block has insulating properties. */
|
||||||
public boolean insulated = false;
|
public boolean insulated = false;
|
||||||
|
/** whether the sprite is a full square. */
|
||||||
|
public boolean squareSprite = true;
|
||||||
/** tile entity health */
|
/** tile entity health */
|
||||||
public int health = -1;
|
public int health = -1;
|
||||||
/** base block explosiveness */
|
/** base block explosiveness */
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.world.blocks;
|
package mindustry.world.blocks;
|
||||||
|
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
@@ -10,12 +11,39 @@ import mindustry.world.*;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
//TODO documentation
|
||||||
public interface Autotiler{
|
public interface Autotiler{
|
||||||
|
|
||||||
|
//holds some static temporary variables, required due to some RoboVM bugs
|
||||||
class AutotilerHolder{
|
class AutotilerHolder{
|
||||||
static final int[] blendresult = new int[4];
|
static final int[] blendresult = new int[5];
|
||||||
static final BuildRequest[] directionals = new BuildRequest[4];
|
static final BuildRequest[] directionals = new BuildRequest[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** slices a texture region:
|
||||||
|
* mode == 0 -> no slice
|
||||||
|
* mode == 1 -> bottom
|
||||||
|
* mode == 2 -> top */
|
||||||
|
default TextureRegion sliced(TextureRegion input, int mode){
|
||||||
|
return mode == 0 ? input : mode == 1 ? botHalf(input) : topHalf(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
default TextureRegion topHalf(TextureRegion input){
|
||||||
|
TextureRegion region = Tmp.tr1;
|
||||||
|
region.set(input);
|
||||||
|
region.setWidth(region.getWidth() / 2);
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
default TextureRegion botHalf(TextureRegion input){
|
||||||
|
TextureRegion region = Tmp.tr1;
|
||||||
|
region.set(input);
|
||||||
|
int width = region.getWidth();
|
||||||
|
region.setWidth(width / 2);
|
||||||
|
region.setX(region.getX() + width);
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
default @Nullable int[] getTiling(BuildRequest req, Eachable<BuildRequest> list){
|
default @Nullable int[] getTiling(BuildRequest req, Eachable<BuildRequest> list){
|
||||||
if(req.tile() == null) return null;
|
if(req.tile() == null) return null;
|
||||||
BuildRequest[] directionals = AutotilerHolder.directionals;
|
BuildRequest[] directionals = AutotilerHolder.directionals;
|
||||||
@@ -37,6 +65,19 @@ public interface Autotiler{
|
|||||||
return buildBlending(req.tile(), req.rotation, directionals, req.worldContext);
|
return buildBlending(req.tile(), req.rotation, directionals, req.worldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an array of blending values:
|
||||||
|
* [0]: the type of connection:
|
||||||
|
* - 0: straight
|
||||||
|
* - 1: curve (top)
|
||||||
|
* - 2: straight (bottom)
|
||||||
|
* - 3: all sides
|
||||||
|
* - 4: straight (top)
|
||||||
|
* [1]: X scale
|
||||||
|
* [2]: Y scale
|
||||||
|
* [3]: a 4-bit mask with bits 0-3 indicating blend state in that direction (0 being 0 degrees, 1 being 90, etc)
|
||||||
|
* [4]: same as [3] but only blends with non-square sprites
|
||||||
|
* */
|
||||||
default int[] buildBlending(Tile tile, int rotation, BuildRequest[] directional, boolean world){
|
default int[] buildBlending(Tile tile, int rotation, BuildRequest[] directional, boolean world){
|
||||||
int[] blendresult = AutotilerHolder.blendresult;
|
int[] blendresult = AutotilerHolder.blendresult;
|
||||||
blendresult[0] = 0;
|
blendresult[0] = 0;
|
||||||
@@ -59,6 +100,15 @@ public interface Autotiler{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blendresult[4] = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
int realDir = Mathf.mod(rotation - i, 4);
|
||||||
|
if(blends(tile, rotation, directional, i, world) && (tile != null && tile.getNearbyEntity(realDir) != null && !tile.getNearbyEntity(realDir).block().squareSprite)){
|
||||||
|
blendresult[4] |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return blendresult;
|
return blendresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
int lastInserted, mid;
|
int lastInserted, mid;
|
||||||
float minitem = 1;
|
float minitem = 1;
|
||||||
|
|
||||||
int blendbits;
|
int blendbits, blending;
|
||||||
int blendsclx, blendscly;
|
int blendsclx, blendscly;
|
||||||
|
|
||||||
float clogHeat = 0f;
|
float clogHeat = 0f;
|
||||||
@@ -116,10 +116,23 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
public void draw(){
|
public void draw(){
|
||||||
byte rotation = tile.rotation();
|
byte rotation = tile.rotation();
|
||||||
int frame = clogHeat <= 0.5f ? (int)(((Time.time() * speed * 8f * timeScale())) % 4) : 0;
|
int frame = clogHeat <= 0.5f ? (int)(((Time.time() * speed * 8f * timeScale())) % 4) : 0;
|
||||||
Draw.rect(regions[Mathf.clamp(blendbits, 0, regions.length - 1)][Mathf.clamp(frame, 0, regions[0].length - 1)], x, y,
|
|
||||||
tilesize * blendsclx, tilesize * blendscly, rotation * 90);
|
|
||||||
|
|
||||||
//TODO is clustering necessary? does it create garbage?
|
//draw extra conveyors facing this one for non-square tiling purposes
|
||||||
|
Draw.z(Layer.blockUnder);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if((blending & (1 << i)) != 0){
|
||||||
|
int dir = rotation - i;
|
||||||
|
float rot = i == 0 ? rotation * 90 : (dir)*90;
|
||||||
|
|
||||||
|
Draw.rect(sliced(regions[0][frame], i != 0 ? 1 : 2), x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.z(Layer.block);
|
||||||
|
|
||||||
|
Draw.rect(regions[blendbits][frame], x, y, tilesize * blendsclx, tilesize * blendscly, rotation * 90);
|
||||||
|
|
||||||
|
//TODO is sprite Z layer clustering necessary? does it create garbage?
|
||||||
Draw.z(Layer.blockOver);
|
Draw.z(Layer.blockOver);
|
||||||
|
|
||||||
for(int i = 0; i < len; i++){
|
for(int i = 0; i < len; i++){
|
||||||
@@ -128,8 +141,9 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
tr2.trns(rotation * 90, -tilesize / 2f, xs[i] * tilesize / 2f);
|
tr2.trns(rotation * 90, -tilesize / 2f, xs[i] * tilesize / 2f);
|
||||||
|
|
||||||
Draw.rect(item.icon(Cicon.medium),
|
Draw.rect(item.icon(Cicon.medium),
|
||||||
(tile.x * tilesize + tr1.x * ys[i] + tr2.x),
|
(tile.x * tilesize + tr1.x * ys[i] + tr2.x),
|
||||||
(tile.y * tilesize + tr1.y * ys[i] + tr2.y), itemSize, itemSize);
|
(tile.y * tilesize + tr1.y * ys[i] + tr2.y),
|
||||||
|
itemSize, itemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +160,7 @@ public class Conveyor extends Block implements Autotiler{
|
|||||||
blendbits = bits[0];
|
blendbits = bits[0];
|
||||||
blendsclx = bits[1];
|
blendsclx = bits[1];
|
||||||
blendscly = bits[2];
|
blendscly = bits[2];
|
||||||
|
blending = bits[4];
|
||||||
|
|
||||||
if(tile.front() != null && tile.front() != null){
|
if(tile.front() != null && tile.front() != null){
|
||||||
next = tile.front();
|
next = tile.front();
|
||||||
|
|||||||
@@ -12,17 +12,20 @@ import mindustry.annotations.Annotations.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class Conduit extends LiquidBlock implements Autotiler{
|
public class Conduit extends LiquidBlock implements Autotiler{
|
||||||
public final int timerFlow = timers++;
|
public final int timerFlow = timers++;
|
||||||
|
|
||||||
public Color botColor = Color.valueOf("565656");
|
public Color botColor = Color.valueOf("565656");
|
||||||
|
|
||||||
public @Load(value = "@-top-#", length = 7) TextureRegion[] topRegions;
|
public @Load(value = "@-top-#", length = 5) TextureRegion[] topRegions;
|
||||||
public @Load(value = "@-bottom-#", length = 7, fallback = "conduit-bottom-#") TextureRegion[] botRegions;
|
public @Load(value = "@-bottom-#", length = 5, fallback = "conduit-bottom-#") TextureRegion[] botRegions;
|
||||||
|
|
||||||
public float leakResistance = 1.5f;
|
public float leakResistance = 1.5f;
|
||||||
|
|
||||||
@@ -40,11 +43,13 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
|
|
||||||
if(bits == null) return;
|
if(bits == null) return;
|
||||||
|
|
||||||
|
Draw.scl(bits[1], bits[2]);
|
||||||
Draw.color(botColor);
|
Draw.color(botColor);
|
||||||
Draw.alpha(0.5f);
|
Draw.alpha(0.5f);
|
||||||
Draw.rect(botRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(botRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
Draw.rect(topRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
|
Draw.rect(topRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
|
||||||
|
Draw.scl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -57,11 +62,6 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
Mathf.mod(req.tile().rotation() - req.rotation, 2) == 1 ? Blocks.liquidJunction : this;
|
Mathf.mod(req.tile().rotation() - req.rotation, 2) == 1 ? Blocks.liquidJunction : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformCase(int num, int[] bits){
|
|
||||||
bits[0] = num == 0 ? 3 : num == 1 ? 6 : num == 2 ? 2 : num == 3 ? 4 : num == 4 ? 5 : num == 5 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
public boolean blends(Tile tile, int rotation, int otherx, int othery, int otherrot, Block otherblock){
|
||||||
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
|
return otherblock.hasLiquids && otherblock.outputsLiquid && lookingAt(tile, rotation, otherx, othery, otherrot, otherblock);
|
||||||
@@ -74,28 +74,51 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
|||||||
|
|
||||||
public class ConduitEntity extends LiquidBlockEntity{
|
public class ConduitEntity extends LiquidBlockEntity{
|
||||||
public float smoothLiquid;
|
public float smoothLiquid;
|
||||||
int blendbits;
|
public int blendbits, xscl, yscl, blending;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
float rotation = rotdeg();
|
float rotation = rotdeg();
|
||||||
|
int r = rotation();
|
||||||
|
|
||||||
|
//draw extra conduits facing this one for tiling purposes
|
||||||
|
Draw.z(Layer.blockUnder);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if((blending & (1 << i)) != 0){
|
||||||
|
int dir = r - i;
|
||||||
|
float rot = i == 0 ? rotation : (dir)*90;
|
||||||
|
drawAt(x + Geometry.d4x(dir) * tilesize*0.75f, y + Geometry.d4y(dir) * tilesize*0.75f, 0, rot, i != 0 ? 1 : 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.z(Layer.block);
|
||||||
|
|
||||||
|
Draw.scl(xscl, yscl);
|
||||||
|
drawAt(x, y, blendbits, rotation, 0);
|
||||||
|
Draw.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawAt(float x, float y, int bits, float rotation, int slice){
|
||||||
Draw.color(botColor);
|
Draw.color(botColor);
|
||||||
Draw.rect(botRegions[blendbits], x, y, rotation);
|
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);
|
||||||
|
|
||||||
Draw.color(liquids.current().color);
|
Draw.color(liquids.current().color);
|
||||||
Draw.alpha(smoothLiquid);
|
Draw.alpha(smoothLiquid);
|
||||||
Draw.rect(botRegions[blendbits], x, y, rotation);
|
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);
|
||||||
Draw.color();
|
Draw.color();
|
||||||
|
|
||||||
Draw.rect(topRegions[blendbits], x, y, rotation);
|
Draw.rect(sliced(topRegions[bits], slice), x, y, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProximityUpdate(){
|
public void onProximityUpdate(){
|
||||||
super.onProximityUpdate();
|
super.onProximityUpdate();
|
||||||
|
|
||||||
blendbits = buildBlending(tile, rotation(), null, true)[0];
|
int[] bits = buildBlending(tile, rotation(), null, true);
|
||||||
|
blendbits = bits[0];
|
||||||
|
xscl = bits[1];
|
||||||
|
yscl = bits[2];
|
||||||
|
blending = bits[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=fc5fd01cd2bfc1a95171f212e601ac030ee3e58f
|
archash=f9cc0eb5711f3e2f640c59d63e3a50da29bca49d
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ public class Generators{
|
|||||||
scaled.save("../ui/block-" + block.name + "-" + icon.name());
|
scaled.save("../ui/block-" + block.name + "-" + icon.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean hasEmpty = false;
|
||||||
Color average = new Color();
|
Color average = new Color();
|
||||||
for(int x = 0; x < image.width; x++){
|
for(int x = 0; x < image.width; x++){
|
||||||
for(int y = 0; y < image.height; y++){
|
for(int y = 0; y < image.height; y++){
|
||||||
@@ -180,6 +181,9 @@ public class Generators{
|
|||||||
average.r += color.r;
|
average.r += color.r;
|
||||||
average.g += color.g;
|
average.g += color.g;
|
||||||
average.b += color.b;
|
average.b += color.b;
|
||||||
|
if(color.a < 0.9f){
|
||||||
|
hasEmpty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
average.mul(1f / (image.width * image.height));
|
average.mul(1f / (image.width * image.height));
|
||||||
@@ -188,7 +192,8 @@ public class Generators{
|
|||||||
}else{
|
}else{
|
||||||
average.mul(1.1f);
|
average.mul(1.1f);
|
||||||
}
|
}
|
||||||
average.a = 1f;
|
//encode square sprite in alpha channel
|
||||||
|
average.a = hasEmpty ? 0.1f : 1f;
|
||||||
colors.draw(block.id, 0, average);
|
colors.draw(block.id, 0, average);
|
||||||
}catch(IllegalArgumentException e){
|
}catch(IllegalArgumentException e){
|
||||||
Log.info("Skipping &ly'@'", block.name);
|
Log.info("Skipping &ly'@'", block.name);
|
||||||
|
|||||||