diff --git a/core/assets-raw/sprites/blocks/liquid/conduits/conduit-liquid.png b/core/assets-raw/sprites/blocks/liquid/fluid.png similarity index 100% rename from core/assets-raw/sprites/blocks/liquid/conduits/conduit-liquid.png rename to core/assets-raw/sprites/blocks/liquid/fluid.png diff --git a/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit-bottom.png b/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit-bottom.png new file mode 100644 index 0000000000..d621cd520b Binary files /dev/null and b/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit-bottom.png differ diff --git a/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit.png b/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit.png index 248410f914..88b34c2f6e 100644 Binary files a/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit.png and b/core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit.png differ diff --git a/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png b/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png index 99eca2c1ac..2bc1dcf21d 100644 Binary files a/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png and b/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png differ diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 79f5ddfc4a..09f8e1c73c 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -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 envRenderers = new Seq<>(); public ObjectMap 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); diff --git a/core/src/mindustry/type/Liquid.java b/core/src/mindustry/type/Liquid.java index 68288f9c22..a6903bd9ac 100644 --- a/core/src/mindustry/type/Liquid.java +++ b/core/src/mindustry/type/Liquid.java @@ -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; diff --git a/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java b/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java index 288802b11a..f9b62d0a7c 100644 --- a/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java +++ b/core/src/mindustry/world/blocks/distribution/DirectionLiquidBridge.java @@ -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){ diff --git a/core/src/mindustry/world/blocks/liquid/Conduit.java b/core/src/mindustry/world/blocks/liquid/Conduit.java index c3e3a5edd9..62d42885f0 100644 --- a/core/src/mindustry/world/blocks/liquid/Conduit.java +++ b/core/src/mindustry/world/blocks/liquid/Conduit.java @@ -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; diff --git a/core/src/mindustry/world/blocks/liquid/LiquidBlock.java b/core/src/mindustry/world/blocks/liquid/LiquidBlock.java index 7d6ca5d31b..1f84ba73c9 100644 --- a/core/src/mindustry/world/blocks/liquid/LiquidBlock.java +++ b/core/src/mindustry/world/blocks/liquid/LiquidBlock.java @@ -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); } } } diff --git a/core/src/mindustry/world/blocks/liquid/LiquidRouter.java b/core/src/mindustry/world/blocks/liquid/LiquidRouter.java index 81e12d35d3..507602a987 100644 --- a/core/src/mindustry/world/blocks/liquid/LiquidRouter.java +++ b/core/src/mindustry/world/blocks/liquid/LiquidRouter.java @@ -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); diff --git a/gradle.properties b/gradle.properties index 4b58915e44..5bcccfa980 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 76d6a0372b..b8c21fe13f 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -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 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); } } });