weird liquid animations
Before Width: | Height: | Size: 98 B After Width: | Height: | Size: 98 B |
After Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 507 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 478 B |
@ -19,6 +19,7 @@ import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.graphics.g3d.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.blocks.storage.*;
|
||||
import mindustry.world.blocks.storage.CoreBlock.*;
|
||||
|
||||
@ -52,6 +53,7 @@ public class Renderer implements ApplicationListener{
|
||||
public Seq<EnvRenderer> envRenderers = new Seq<>();
|
||||
public ObjectMap<String, Runnable> customBackgrounds = new ObjectMap<>();
|
||||
public TextureRegion[] bubbles = new TextureRegion[16], splashes = new TextureRegion[12];
|
||||
public TextureRegion[][] fluidFrames = new TextureRegion[2][Liquid.animationFrames];
|
||||
|
||||
private @Nullable CoreBuild landCore;
|
||||
private @Nullable CoreBlock launchCoreType;
|
||||
@ -111,6 +113,15 @@ public class Renderer implements ApplicationListener{
|
||||
for(int i = 0; i < bubbles.length; i++) bubbles[i] = atlas.find("bubble-" + i);
|
||||
for(int i = 0; i < splashes.length; i++) splashes[i] = atlas.find("splash-" + i);
|
||||
|
||||
String[] fluidTypes = {"liquid", "gas"};
|
||||
|
||||
for(int i = 0; i < fluidTypes.length; i++){
|
||||
|
||||
for(int j = 0; j < Liquid.animationFrames; j++){
|
||||
fluidFrames[i][j] = atlas.find("fluid-" + fluidTypes[i] + "-" + j);
|
||||
}
|
||||
}
|
||||
|
||||
assets.load("sprites/clouds.png", Texture.class).loaded = t -> {
|
||||
t.setWrap(TextureWrap.repeat);
|
||||
t.setFilter(TextureFilter.linear);
|
||||
|
@ -17,8 +17,8 @@ import static mindustry.entities.Puddles.*;
|
||||
/** A better name for this class would be "fluid", but it's too late for that. */
|
||||
public class Liquid extends UnlockableContent{
|
||||
//must be static and global so conduits don't conflict - DO NOT INTERACT WITH THESE IN MODS OR I WILL PERSONALLY YELL AT YOU
|
||||
public static final int animationFrames = 40;
|
||||
public static float animationScale = 190f;
|
||||
public static final int animationFrames = 50;
|
||||
public static float animationScaleGas = 190f, animationScaleLiquid = 230f;
|
||||
|
||||
protected static final Rand rand = new Rand();
|
||||
|
||||
@ -84,6 +84,10 @@ public class Liquid extends UnlockableContent{
|
||||
}
|
||||
}
|
||||
|
||||
public int getAnimationFrame(){
|
||||
return (int)(Time.time / (gas ? animationScaleGas : animationScaleLiquid) * animationFrames + id*5) % animationFrames;
|
||||
}
|
||||
|
||||
/** @return true if this liquid will boil in this global environment. */
|
||||
public boolean willBoil(){
|
||||
return Attribute.heat.env() >= boilPoint;
|
||||
|
@ -6,14 +6,16 @@ import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.blocks.liquid.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
public class DirectionLiquidBridge extends DirectionBridge{
|
||||
public final int timerFlow = timers++;
|
||||
|
||||
public float speed = 5f;
|
||||
public float liquidPadding = 1f;
|
||||
|
||||
public @Load("@-liquid") TextureRegion liquidRegion;
|
||||
public @Load("@-bottom") TextureRegion bottomRegion;
|
||||
|
||||
public DirectionLiquidBridge(String name){
|
||||
super(name);
|
||||
@ -25,16 +27,24 @@ public class DirectionLiquidBridge extends DirectionBridge{
|
||||
hasLiquids = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TextureRegion[] icons(){
|
||||
return new TextureRegion[]{bottomRegion, region, dirRegion};
|
||||
}
|
||||
|
||||
public class DuctBridgeBuild extends DirectionBridgeBuild{
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
Draw.rect(block.region, x, y);
|
||||
Draw.rect(bottomRegion, x, y);
|
||||
|
||||
if(liquids.currentAmount() > 0.001f){
|
||||
Drawf.liquid(liquidRegion, x, y, liquids.currentAmount() / liquidCapacity, liquids.current().color);
|
||||
LiquidBlock.drawTiledFrames(size, x, y, liquidPadding, liquids.current(), liquids.currentAmount() / liquidCapacity);
|
||||
}
|
||||
|
||||
Draw.rect(block.region, x, y);
|
||||
|
||||
Draw.rect(dirRegion, x, y, rotdeg());
|
||||
var link = findLink();
|
||||
if(link != null){
|
||||
|
@ -29,12 +29,10 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
|
||||
public @Load(value = "@-top-#", length = 5) TextureRegion[] topRegions;
|
||||
public @Load(value = "@-bottom-#", length = 5, fallback = "conduit-bottom-#") TextureRegion[] botRegions;
|
||||
public @Load(value = "@-liquid-r#", length = 4, fallback = "conduit-liquid-r#") TextureRegion[] liquidRotateRegions;
|
||||
public @Load(value = "@-liquid", fallback = "conduit-liquid") TextureRegion liquidBaseRegion;
|
||||
public @Load("@-cap") TextureRegion capRegion;
|
||||
|
||||
public @Load(value = "conduit-liquid-#", length = animationFrames) TextureRegion[] gasRegions;
|
||||
public @Load(value = "conduit-liquid-r#1-#2", lengths = {4, animationFrames}) TextureRegion[][] rotateGasRegions;
|
||||
public @Load(value = "conduit-liquid-r#1-gas-#2", lengths = {4, animationFrames}) TextureRegion[][] rotateGasRegions;
|
||||
public @Load(value = "conduit-liquid-r#1-liquid-#2", lengths = {4, animationFrames}) TextureRegion[][] rotateLiquidRegions;
|
||||
|
||||
public boolean leaks = true;
|
||||
public @Nullable Block junctionReplacement, bridgeReplacement, rotBridgeReplacement;
|
||||
@ -139,12 +137,13 @@ public class Conduit extends LiquidBlock implements Autotiler{
|
||||
Draw.rect(sliced(botRegions[bits], slice), x, y, angle);
|
||||
|
||||
int offset = yscl == -1 ? 3 : 0;
|
||||
|
||||
//TODO move out of conduit
|
||||
int frame = (int)(Time.time / animationScale * animationFrames) % animationFrames;
|
||||
int frame = liquids.current().getAnimationFrame();
|
||||
TextureRegion liquidr =
|
||||
liquids.current().gas ?
|
||||
(bits == 1 ? rotateGasRegions[(rotation + offset) % 4][frame] : gasRegions[frame]) :
|
||||
(bits == 1 ? liquidRotateRegions[(rotation + offset) % 4] : liquidBaseRegion);
|
||||
(bits == 1 ? rotateGasRegions[(rotation + offset) % 4][frame] : renderer.fluidFrames[1][frame]) :
|
||||
(bits == 1 ? rotateLiquidRegions[(rotation + offset) % 4][frame] : renderer.fluidFrames[0][frame]);
|
||||
|
||||
//the drawing state machine sure was a great design choice with no downsides or hidden behavior!!!
|
||||
float xscl = Draw.xscl, yscl = Draw.yscl;
|
||||
|
@ -32,11 +32,12 @@ public class LiquidBlock extends Block{
|
||||
return new TextureRegion[]{bottomRegion, topRegion};
|
||||
}
|
||||
|
||||
public static void drawTiledGas(TextureRegion[] gasRegions, int size, float x, float y, float padding, Color color, float alpha){
|
||||
TextureRegion region = gasRegions[(int)(Time.time / Liquid.animationScale * Liquid.animationFrames) % Liquid.animationFrames];
|
||||
public static void drawTiledFrames(int size, float x, float y, float padding, Liquid liquid, float alpha){
|
||||
TextureRegion region = renderer.fluidFrames[liquid.gas ? 1 : 0][liquid.getAnimationFrame()];
|
||||
TextureRegion toDraw = Tmp.tr1;
|
||||
|
||||
float bounds = size/2f * tilesize - padding;
|
||||
Color color = Tmp.c1.set(liquid.color).mul(liquid.gas ? 1f : 1f).a(1f);
|
||||
|
||||
for(int sx = 0; sx < size; sx++){
|
||||
for(int sy = 0; sy < size; sy++){
|
||||
@ -60,7 +61,7 @@ public class LiquidBlock extends Block{
|
||||
oy = -squishY/2f;
|
||||
}
|
||||
|
||||
Drawf.liquid(toDraw, x + rightBorder + ox, y + topBorder + oy, alpha, Tmp.c1.set(color).a(1f));
|
||||
Drawf.liquid(toDraw, x + rightBorder + ox, y + topBorder + oy, alpha, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
package mindustry.world.blocks.liquid;
|
||||
|
||||
import arc.graphics.g2d.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class LiquidRouter extends LiquidBlock{
|
||||
/** kept only for mod compatibility reasons; all vanilla blocks have this as true */
|
||||
public boolean newDrawing = false;
|
||||
public float liquidPadding = 0f;
|
||||
|
||||
public @Load(value = "conduit-liquid-#", length = Liquid.animationFrames) TextureRegion[] gasRegions;
|
||||
|
||||
public LiquidRouter(String name){
|
||||
super(name);
|
||||
|
||||
@ -40,13 +35,7 @@ public class LiquidRouter extends LiquidBlock{
|
||||
Draw.rect(bottomRegion, x, y);
|
||||
|
||||
if(liquids.currentAmount() > 0.001f){
|
||||
if(liquids.current().gas){
|
||||
drawTiledGas(gasRegions, size, x, y, liquidPadding, liquids.current().color, liquids.currentAmount() / liquidCapacity);
|
||||
}else{
|
||||
Draw.color(liquids.current().color, liquids.currentAmount() / liquidCapacity);
|
||||
Fill.square(x, y, size * tilesize/2f - liquidPadding);
|
||||
Draw.color();
|
||||
}
|
||||
drawTiledFrames(size, x, y, liquidPadding, liquids.current(), liquids.currentAmount() / liquidCapacity);
|
||||
}
|
||||
|
||||
Draw.rect(region, x, y);
|
||||
|
@ -24,4 +24,4 @@ android.useAndroidX=true
|
||||
#used for slow jitpack builds; TODO see if this actually works
|
||||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
archash=ee4906c1
|
||||
archash=8ca996ed
|
||||
|
@ -30,14 +30,27 @@ import static mindustry.tools.ImagePacker.*;
|
||||
public class Generators{
|
||||
static final int logicIconSize = (int)iconMed, maxUiIcon = 128;
|
||||
|
||||
private static final int keyframes = 4;
|
||||
private static float fluid(boolean gas, double x, double y, float frame){
|
||||
int keyframes = gas ? 4 : 3;
|
||||
|
||||
private static float gas(double x, double y, float frame){
|
||||
//interpolate between the current two keyframes
|
||||
int curFrame = (int)(frame * keyframes);
|
||||
int nextFrame = (curFrame + 1) % keyframes;
|
||||
float progress = (frame * keyframes) % 1f;
|
||||
//interpolate between the current two keyframes
|
||||
return Mathf.lerp((float)gasFrame(x, y, curFrame), (float)gasFrame(x, y, nextFrame), progress);
|
||||
|
||||
if(gas){
|
||||
float min = 0.56f;
|
||||
float interpolated = Mathf.lerp((float)gasFrame(x, y, curFrame), (float)gasFrame(x, y, nextFrame), progress);
|
||||
return min + (1f - min) * interpolated;
|
||||
}else{ //liquids
|
||||
float min = 0.84f;
|
||||
double rx = (x + frame*32) % 32, ry = (y + frame*32) % 32;
|
||||
//rx = x; ry = y;
|
||||
//(float)liquidFrame(rx, ry, 0)
|
||||
float interpolated = (float)liquidFrame(rx, ry, 2);//Mathf.lerp((float)liquidFrame(rx, ry, curFrame), (float)liquidFrame(rx, ry, nextFrame), progress);
|
||||
//only two colors here
|
||||
return min + (interpolated >= 0.3f ? 1f - min : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private static double gasFrame(double x, double y, int frame){
|
||||
@ -48,6 +61,14 @@ public class Generators{
|
||||
return (Simplex.rawTiled(x, y, ox, oy, s, s, scale) + Simplex.rawTiled(x, y, ox, oy, s, s, scale / 1.5) * second) / (1.0 + second);
|
||||
}
|
||||
|
||||
private static double liquidFrame(double x, double y, int frame){
|
||||
int s = 31;
|
||||
//calculate random space offsets for the frame cutout
|
||||
double ox = Mathf.randomSeed(frame, 1), oy = Mathf.randomSeed(frame, 1);
|
||||
double scale = 26, second = 0.5;
|
||||
return (Simplex.rawTiled(x, y, ox, oy, s, s, scale) + Simplex.rawTiled(x, y, ox, oy, s, s, scale / 1.5) * second) / (1.0 + second);
|
||||
}
|
||||
|
||||
public static void run(){
|
||||
ObjectMap<Block, Pixmap> gens = new ObjectMap<>();
|
||||
|
||||
@ -107,27 +128,28 @@ public class Generators{
|
||||
|
||||
generate("gas-frames", () -> {
|
||||
int frames = Liquid.animationFrames;
|
||||
String[] stencils = {"conduit-liquid", "conduit-liquid-r0", "conduit-liquid-r1", "conduit-liquid-r2", "conduit-liquid-r3"};
|
||||
for(String region : stencils){
|
||||
Pixmap base = get(region);
|
||||
float min = 0.56f, imin = 1f - min;
|
||||
String[] stencils = {"fluid", "conduit-liquid-r0", "conduit-liquid-r1", "conduit-liquid-r2", "conduit-liquid-r3"};
|
||||
String[] types = {"liquid", "gas"};
|
||||
int typeIndex = 0;
|
||||
|
||||
for(int i = 0; i < frames; i++){
|
||||
float frame = i / (float)frames;
|
||||
for(String type : types){
|
||||
boolean gas = typeIndex++ == 1;
|
||||
for(String region : stencils){
|
||||
Pixmap base = get(region);
|
||||
|
||||
Pixmap copy = base.copy();
|
||||
for(int x = 0; x < copy.width; x++){
|
||||
for(int y = 0; y < copy.height; y++){
|
||||
if(copy.getA(x, y) > 128){
|
||||
for(int i = 0; i < frames; i++){
|
||||
float frame = i / (float)frames;
|
||||
|
||||
double value = gas(x, y, frame);
|
||||
float va = min + imin*(float)(value);
|
||||
|
||||
copy.setRaw(x, y, Color.rgba8888(1f, 1f, 1f, va));
|
||||
Pixmap copy = base.copy();
|
||||
for(int x = 0; x < copy.width; x++){
|
||||
for(int y = 0; y < copy.height; y++){
|
||||
if(copy.getA(x, y) > 128){
|
||||
copy.setRaw(x, y, Color.rgba8888(1f, 1f, 1f, fluid(gas, x, y, frame)));
|
||||
}
|
||||
}
|
||||
}
|
||||
save(copy, region + "-" + type + "-" + i);
|
||||
}
|
||||
save(copy, region + "-" + i);
|
||||
}
|
||||
}
|
||||
});
|
||||
|