From 0aa85163d26190d726b289a14175549d53840df5 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 26 Nov 2021 22:48:51 -0500 Subject: [PATCH] weird liquid animations --- .../conduit-liquid.png => fluid.png} | Bin .../reinforced-bridge-conduit-bottom.png | Bin 0 -> 170 bytes .../liquid/reinforced-bridge-conduit.png | Bin 507 -> 489 bytes .../production/atmospheric-concentrator.png | Bin 425 -> 478 bytes core/src/mindustry/core/Renderer.java | 11 ++++ core/src/mindustry/type/Liquid.java | 8 ++- .../distribution/DirectionLiquidBridge.java | 16 ++++- .../world/blocks/liquid/Conduit.java | 13 ++-- .../world/blocks/liquid/LiquidBlock.java | 7 +- .../world/blocks/liquid/LiquidRouter.java | 13 +--- gradle.properties | 2 +- tools/src/mindustry/tools/Generators.java | 60 ++++++++++++------ 12 files changed, 83 insertions(+), 47 deletions(-) rename core/assets-raw/sprites/blocks/liquid/{conduits/conduit-liquid.png => fluid.png} (100%) create mode 100644 core/assets-raw/sprites/blocks/liquid/reinforced-bridge-conduit-bottom.png 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 0000000000000000000000000000000000000000..d621cd520b34bb5cb14f2eb3f0e034ae7e7a58f5 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>U`X+F zaSVxQeS2L|=zs!`%f%(%6Iborzv5ki!m1YzYMWF<>qQT~*}OWbXxgo}_owf?z4Y^5 zncb&tkNob?+RkxSW4_?5P`jd(Y0L}=;P8b1aEi>z%Q{jI`z~v=%ze&Z)}eTYtF_hw Oq{h?L&t;ucLK6VNay>Et literal 0 HcmV?d00001 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 248410f91425576057153ac437722e6f9c117cb7..88b34c2f6e9f39e545aaac72a408b50962606cf5 100644 GIT binary patch delta 450 zcmey({E~TsVf|uH7srr@*0+qBvjyAMD$JTNvz9qVJA3u)S$e-&yzLKN znz?LOSy6FK^Q>i@O-9kN!Oabw&+_z-Gd?{f)8EAX-R}I~W_dA@wdS{Da+w=UI!ez@ z-Q?_l+it$EZdLq_m#6mla;WLW#Z8|(>-yKF%&80pQvRQwR5;X&s2)qpRdtG3{Bemv z(Ys#~e3lFfT|#gCe(&y?CqF;McCOr&wkH)Dan|KOPgjL1&e%3Jqad?p$;SMy&$z@xkxc!QWP{K41T8nHg`Aav`FOJ8NQV8zm0f#!IP|2Z!G zRdm_#FJVT+&bu!c-rmZ{;3$x^F?OCy$<198ewJ7SGe1n5nq%(wX!_4hE(N($7VOlQ z39>NHuMQSn5UrqQ{#|DGv4b6Ro-tmUI)RC$@vW>tBJb&Pp=SHP{Y6Z-*1FVRw@BC+ zd+1w|+{dmWFF(ilg`1u*e5n7s)ptVr)8~~-d+%%&v=j}Ta{o_DXiJoX?gFs@?iH*b z_Wa-b)Otph@#81Y--fN5zoABbT|=Hg=@vDmW%qc>mbWkZbBW*M`=-TPwZd{JUxU|{fc^>bP0l+XkK52N5W diff --git a/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png b/core/assets-raw/sprites/blocks/production/atmospheric-concentrator.png index 99eca2c1acf8c156a361b4c4fd757d95b4062f5f..2bc1dcf21d24a313cd17a8a5f748a61a10192022 100644 GIT binary patch delta 439 zcmZ3JL8sx$(!K0SO^g#3O<0zhw0zt3e=jPN>)%~?^y}F-?_=4?cN^@oi;6;0qzx=B zwN8|<|ND?45pZmBq=Trx8)IpOgzxgt3w8frtJrh($1f!t?y?8r4Ea0B! z!nEsAqRITd?2b9P?@NBg$lEZMFF4)&qFeogV3ev7%RCO_3u;Ot^E{mIhzJV#ABkR} zr(`nk#PtkIB{n%X!+l%!JgeVa-p^ki_`%>+RsH3>gycsrD_f==J$_6$flbVnr&0Za zK)7<-A>j{Vzq%!a{2yeOWY{n=C*A#gI&4Bi=|fI|4SqJZ%-4FCyE|}ISg|c>TJG%N zRT0MH!F!&IQS(vaVSTcvi(^Pe#?9k(?+9f+on|s3Q6tg z7HeZEyt&_acm6Wf3GcUWejln6cmLjg(VBP9*m^8)pREeaIZ(DaF5m_4oR1- zWZ|i(yjOZmSZ9I$JO@VS4=kJ#UG1+*?x;KJyq9OI&F7idVs7xnvFGUIAEK{>Co=iB zNxl%8$mPFGF|W&`Q~j~ns&0>7_0Lj!drmaAYaQ>8n|HbJ{p-)l+;XcH{+^x3JX`qu ziSQM=cINX~j0?1rxNJJxs(x4{Y1wdYzhIfUV*>@Qd5nw`KYZcoXj|^?;9?`oyy($O0Rc&WZ-){aUPjdiI|T!{=FMuD s^dW|IO51a#1uixfHMd0nmd}mdKI;Vst0QI7$$N&HU 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); } } });