This commit is contained in:
Anuken
2020-05-31 20:16:32 -04:00
parent 8598b0a23a
commit 5b4a22e219
23 changed files with 3402 additions and 3271 deletions

View File

@@ -136,6 +136,9 @@ public class ContentLoader{
Block block = block(i);
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;
}
}

View File

@@ -17,6 +17,9 @@ public class Layer{
//things such as spent casings or rubble
debris = 20,
//stuff under blocks, like connections of conveyors/conduits
blockUnder = 29.5f,
//base block layer - most blocks go here
block = 30,

View File

@@ -83,6 +83,8 @@ public class Block extends UnlockableContent{
public boolean placeableOn = true;
/** whether this block has insulating properties. */
public boolean insulated = false;
/** whether the sprite is a full square. */
public boolean squareSprite = true;
/** tile entity health */
public int health = -1;
/** base block explosiveness */

View File

@@ -1,5 +1,6 @@
package mindustry.world.blocks;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
@@ -10,12 +11,39 @@ import mindustry.world.*;
import java.util.*;
//TODO documentation
public interface Autotiler{
//holds some static temporary variables, required due to some RoboVM bugs
class AutotilerHolder{
static final int[] blendresult = new int[4];
static final int[] blendresult = new int[5];
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){
if(req.tile() == null) return null;
BuildRequest[] directionals = AutotilerHolder.directionals;
@@ -37,6 +65,19 @@ public interface Autotiler{
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){
int[] blendresult = AutotilerHolder.blendresult;
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;
}

View File

@@ -107,7 +107,7 @@ public class Conveyor extends Block implements Autotiler{
int lastInserted, mid;
float minitem = 1;
int blendbits;
int blendbits, blending;
int blendsclx, blendscly;
float clogHeat = 0f;
@@ -116,10 +116,23 @@ public class Conveyor extends Block implements Autotiler{
public void draw(){
byte rotation = tile.rotation();
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);
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);
Draw.rect(item.icon(Cicon.medium),
(tile.x * tilesize + tr1.x * ys[i] + tr2.x),
(tile.y * tilesize + tr1.y * ys[i] + tr2.y), itemSize, itemSize);
(tile.x * tilesize + tr1.x * ys[i] + tr2.x),
(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];
blendsclx = bits[1];
blendscly = bits[2];
blending = bits[4];
if(tile.front() != null && tile.front() != null){
next = tile.front();

View File

@@ -12,17 +12,20 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.units.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import static mindustry.Vars.tilesize;
public class Conduit extends LiquidBlock implements Autotiler{
public final int timerFlow = timers++;
public Color botColor = Color.valueOf("565656");
public @Load(value = "@-top-#", length = 7) TextureRegion[] topRegions;
public @Load(value = "@-bottom-#", length = 7, fallback = "conduit-bottom-#") TextureRegion[] botRegions;
public @Load(value = "@-top-#", length = 5) TextureRegion[] topRegions;
public @Load(value = "@-bottom-#", length = 5, fallback = "conduit-bottom-#") TextureRegion[] botRegions;
public float leakResistance = 1.5f;
@@ -40,11 +43,13 @@ public class Conduit extends LiquidBlock implements Autotiler{
if(bits == null) return;
Draw.scl(bits[1], bits[2]);
Draw.color(botColor);
Draw.alpha(0.5f);
Draw.rect(botRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.color();
Draw.rect(topRegions[bits[0]], req.drawx(), req.drawy(), req.rotation * 90);
Draw.scl();
}
@Override
@@ -57,11 +62,6 @@ public class Conduit extends LiquidBlock implements Autotiler{
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
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);
@@ -74,28 +74,51 @@ public class Conduit extends LiquidBlock implements Autotiler{
public class ConduitEntity extends LiquidBlockEntity{
public float smoothLiquid;
int blendbits;
public int blendbits, xscl, yscl, blending;
@Override
public void draw(){
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.rect(botRegions[blendbits], x, y, rotation);
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);
Draw.color(liquids.current().color);
Draw.alpha(smoothLiquid);
Draw.rect(botRegions[blendbits], x, y, rotation);
Draw.rect(sliced(botRegions[bits], slice), x, y, rotation);
Draw.color();
Draw.rect(topRegions[blendbits], x, y, rotation);
Draw.rect(sliced(topRegions[bits], slice), x, y, rotation);
}
@Override
public void 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