From 57bcea56b5490b413333a1753a8972c14bc24f32 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 15 May 2018 20:03:03 -0700 Subject: [PATCH] Implemented block build animation and shaders --- build.gradle | 2 +- core/assets/shaders/inline-blocks.fragment | 96 +++++++++ core/assets/shaders/inline-contour.fragment | 63 ++++++ core/assets/shaders/inline-lines.fragment | 63 ++++++ core/assets/shaders/inline-noise.fragment | 111 +++++++++++ core/assets/shaders/inline.fragment | 184 ++++++++++++++++++ .../mindustry/content/blocks/Blocks.java | 12 ++ .../src/io/anuke/mindustry/core/Renderer.java | 39 ++-- .../entities/units/GroundUnitType.java | 4 +- .../mindustry/graphics/BlockRenderer.java | 4 +- .../anuke/mindustry/graphics/CacheLayer.java | 6 +- .../io/anuke/mindustry/graphics/Layer.java | 2 + .../io/anuke/mindustry/graphics/Shaders.java | 20 ++ .../anuke/mindustry/input/InputHandler.java | 5 +- .../ui/dialogs/SettingsMenuDialog.java | 6 +- core/src/io/anuke/mindustry/world/Block.java | 4 + .../io/anuke/mindustry/world/Placement.java | 6 +- .../world/blocks/types/BuildBlock.java | 73 +++++++ .../world/blocks/types/defense/Turret.java | 11 +- 19 files changed, 674 insertions(+), 37 deletions(-) create mode 100644 core/assets/shaders/inline-blocks.fragment create mode 100644 core/assets/shaders/inline-contour.fragment create mode 100644 core/assets/shaders/inline-lines.fragment create mode 100644 core/assets/shaders/inline-noise.fragment create mode 100644 core/assets/shaders/inline.fragment create mode 100644 core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java diff --git a/build.gradle b/build.gradle index 656a821829..bcb0f36006 100644 --- a/build.gradle +++ b/build.gradle @@ -164,7 +164,7 @@ project(":core") { compile "com.github.anuken:ucore:$uCoreVersion" } - if(new File('../GDXGifRecorder').exists() && comp) { + if(new File(projectDir.parent, '../GDXGifRecorder').exists() && comp) { compile project(":GDXGifRecorder") } diff --git a/core/assets/shaders/inline-blocks.fragment b/core/assets/shaders/inline-blocks.fragment new file mode 100644 index 0000000000..e6b3c94b21 --- /dev/null +++ b/core/assets/shaders/inline-blocks.fragment @@ -0,0 +1,96 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform vec2 u_uv; +uniform vec2 u_uv2; +uniform float u_progress; +uniform float u_time; + +varying vec4 v_color; +varying vec2 v_texCoord; + +const float chunk = 4.0; +const float start = 0.7; +const float end = 0.9; + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +float round(float f){ + return float(int(f / chunk)) * chunk; +} + +bool id(vec2 coords, vec4 base, float basediff){ + vec4 target = texture2D(u_texture, coords); + return target.a < 0.1 || (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y); +} + +bool cont(vec2 T, vec2 v, float basediff){ + float step = 1.0; + vec4 base = texture2D(u_texture, T); + return base.a > 0.1 && + (id(T + vec2(0, step) * v, base, basediff) || id(T + vec2(0, -step) * v, base, basediff) || + id(T + vec2(step, 0) * v, base, basediff) || id(T + vec2(-step, 0) * v, base, basediff)); +} + +bool complete(vec2 coords){ + vec2 rc = vec2(round(coords.x), round(coords.y)); + float r = clamp(rand(rc) + u_progress, 0.0, 1.0); + float fr = (r-start)*(1.0/(end-start)); + + vec2 next = rc + chunk/2.0; + float rdst = max(abs(coords.x - next.x), abs(coords.y - next.y)); + return rdst / (chunk/2.0) < fr; +} + +void main() { + + vec2 t = v_texCoord.xy; + + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + + bool any = false; + + vec2 coords = (v_texCoord-u_uv) / v; + + + float value = coords.x + coords.y; + + vec4 color = texture2D(u_texture, t); + vec2 rc = vec2(round(coords.x), round(coords.y)); + vec2 center = ((u_uv + u_uv2)/2.0 - u_uv) /v; + + float r = clamp(rand(rc) + u_progress, 0.0, 1.0); + + const float scl = 10.0; + float dst = (abs(center.x - coords.x) + abs(center.y - coords.y)) / 2.0; + + if(dst - 1.0 < u_progress * (center.x) && dst> u_progress * (center.x) && color.a > 0.1){ + gl_FragColor = u_color; + }else if(r > end){ + gl_FragColor = color; + }else if((cont(t, v, 100.0) && mod(u_time / 1.5 + value, 20.0) < 5.0 && color.a > 0.1) || + (complete(coords) && (!complete(coords + vec2(1.0, 0.0)) || !complete(coords + vec2(-1.0, 0.0)) || !complete(coords + vec2(0.0, 1.0)) + || !complete(coords + vec2(0.0, -1.0))))){ + gl_FragColor = u_color; + }else if(r > start && color.a > 0.1){ + float fr = (r-start)*(1.0/(end-start)); + + vec2 next = rc + chunk/2.0; + float rdst = max(abs(coords.x - next.x), abs(coords.y - next.y)); + if(rdst / (chunk/2.0) < fr){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + } + }else{ + gl_FragColor = vec4(0.0); + } +} diff --git a/core/assets/shaders/inline-contour.fragment b/core/assets/shaders/inline-contour.fragment new file mode 100644 index 0000000000..b7b201d373 --- /dev/null +++ b/core/assets/shaders/inline-contour.fragment @@ -0,0 +1,63 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform vec2 u_uv; +uniform vec2 u_uv2; +uniform float u_progress; +uniform float u_time; + +varying vec4 v_color; +varying vec2 v_texCoord; + +float diff(vec4 target, vec4 base){ + return (max(target.a / base.a, max(target.r / base.r, max(target.g / base.g, target.b / base.b))) - + min (target.a / base.a, min(target.r / base.r, min(target.g / base.g, target.b / base.b)))) * 4.0; +} + +bool id(vec2 coords, vec4 base, float basediff){ + vec4 target = texture2D(u_texture, coords); + return (diff(target, base)) > basediff - basediff*u_progress + || (basediff < 5.0 && (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y)); +} + +bool cont(vec2 T, vec2 v, float basediff){ + float step = 1.0; + vec4 base = texture2D(u_texture, T); + return base.a > 0.1 && + (id(T + vec2(0, step) * v, base, basediff) || id(T + vec2(0, -step) * v, base, basediff) || + id(T + vec2(step, 0) * v, base, basediff) || id(T + vec2(-step, 0) * v, base, basediff)); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + + vec2 t = v_texCoord.xy; + + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + vec2 coords = (v_texCoord-u_uv) / v; + float value = coords.x + coords.y; + + vec4 color = texture2D(u_texture, t); + + vec2 center = ((u_uv + u_uv2)/2.0 - u_uv) /v; + float dst = (abs(center.x - coords.x) + abs(center.y - coords.y)) / 2.0; + + if(dst - 1.0 < u_progress * (center.x) && dst> u_progress * (center.x) && color.a > 0.1){ + gl_FragColor = u_color; + }else if(cont(t, v, 6.0)){ + gl_FragColor = color; + }else if(cont(t, v, 3.0) && color.a > 0.1){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + } +} diff --git a/core/assets/shaders/inline-lines.fragment b/core/assets/shaders/inline-lines.fragment new file mode 100644 index 0000000000..8e55f03000 --- /dev/null +++ b/core/assets/shaders/inline-lines.fragment @@ -0,0 +1,63 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform vec2 u_uv; +uniform vec2 u_uv2; +uniform float u_progress; +uniform float u_time; + +varying vec4 v_color; +varying vec2 v_texCoord; + + +bool id(vec2 coords, vec4 base, float basediff){ + vec4 target = texture2D(u_texture, coords); + return target.a < 0.1 || (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y); +} + +bool cont(vec2 T, vec2 v, float basediff){ + float step = 1.0; + vec4 base = texture2D(u_texture, T); + return base.a > 0.1 && + (id(T + vec2(0, step) * v, base, basediff) || id(T + vec2(0, -step) * v, base, basediff) || + id(T + vec2(step, 0) * v, base, basediff) || id(T + vec2(-step, 0) * v, base, basediff)); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + + vec2 t = v_texCoord.xy; + + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + vec2 coords = (v_texCoord-u_uv) / v; + float value = coords.x + coords.y; + + vec4 color = texture2D(u_texture, t); + + vec2 center = ((u_uv + u_uv2)/2.0 - u_uv) /v; + float dst = (abs(center.x - coords.x) + abs(center.y - coords.y))/2.0; + float chance = 1.0; + + if(u_progress > 0.8){ + chance = 1.0-(u_progress-0.8)*5.0; + } + + if((mod(u_time / 1.5 + value, 20.0) < 5.0 && cont(t, v, 0.0)) && rand(coords) < chance){ + gl_FragColor = u_color; + }else if(dst > (1.0-u_progress) * (center.x)){ + gl_FragColor = color; + }else if((dst + 1.0 > (1.0-u_progress) * (center.x)) && color.a > 0.1 && rand(coords) < chance){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + } +} diff --git a/core/assets/shaders/inline-noise.fragment b/core/assets/shaders/inline-noise.fragment new file mode 100644 index 0000000000..f7167d1dcf --- /dev/null +++ b/core/assets/shaders/inline-noise.fragment @@ -0,0 +1,111 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform vec2 u_uv; +uniform vec2 u_uv2; +uniform float u_progress; +uniform float u_time; + +varying vec4 v_color; +varying vec2 v_texCoord; + +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} + +float snoise(vec3 v){ + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + +// First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + +// Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + + // x0 = x0 - 0. + 0.0 * C + vec3 x1 = x0 - i1 + 1.0 * C.xxx; + vec3 x2 = x0 - i2 + 2.0 * C.xxx; + vec3 x3 = x0 - 1. + 3.0 * C.xxx; + +// Permutations + i = mod(i, 289.0 ); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + +// Gradients +// ( N*N points uniformly over a square, mapped onto an octahedron.) + float n_ = 1.0/7.0; // N=7 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + +//Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + +// Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} + +void main() { + + vec2 t = v_texCoord.xy; + + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + + vec2 coords = (v_texCoord-u_uv) / v; + + const float scl = 10.0; + float result = (snoise(vec3(coords.x / scl, coords.y / scl, u_time/400000.0)) + 1.0)/2.0; + + vec4 color = texture2D(u_texture, t); + + if(result < u_progress){ + gl_FragColor = color; + }else if(result < u_progress*2.0 && color.a > 0.1){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + } + +} diff --git a/core/assets/shaders/inline.fragment b/core/assets/shaders/inline.fragment new file mode 100644 index 0000000000..d5d2f06f5b --- /dev/null +++ b/core/assets/shaders/inline.fragment @@ -0,0 +1,184 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform vec2 u_uv; +uniform vec2 u_uv2; +uniform float u_progress; +uniform float u_time; + +varying vec4 v_color; +varying vec2 v_texCoord; + +const float chunk = 4.0; + +bool id(vec2 coords, vec4 base, float basediff){ + vec4 target = texture2D(u_texture, coords); + return target.a < 0.1 || (coords.x < u_uv.x || coords.y < u_uv.y || coords.x > u_uv2.x || coords.y > u_uv2.y); +} + +bool cont(vec2 T, vec2 v, float basediff){ + float step = 1.0; + vec4 base = texture2D(u_texture, T); + return base.a > 0.1 && + (id(T + vec2(0, step) * v, base, basediff) || id(T + vec2(0, -step) * v, base, basediff) || + id(T + vec2(step, 0) * v, base, basediff) || id(T + vec2(-step, 0) * v, base, basediff)); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +float round(float f){ + return float(int(f / chunk)) * chunk; +} + +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} + +float snoise(vec3 v){ + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + +// First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + +// Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + + // x0 = x0 - 0. + 0.0 * C + vec3 x1 = x0 - i1 + 1.0 * C.xxx; + vec3 x2 = x0 - i2 + 2.0 * C.xxx; + vec3 x3 = x0 - 1. + 3.0 * C.xxx; + +// Permutations + i = mod(i, 289.0 ); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + +// Gradients +// ( N*N points uniformly over a square, mapped onto an octahedron.) + float n_ = 1.0/7.0; // N=7 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + +//Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + +// Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} + +void main() { + + vec2 t = v_texCoord.xy; + + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + + bool any = false; + + vec2 coords = (v_texCoord-u_uv) / v; + + /* + const float scl = 10.0; + float result = (snoise(vec3(coords.x / scl, coords.y / scl, u_time/400000.0)) + 1.0)/2.0; + + vec4 color = texture2D(u_texture, t); + + if(result < u_progress){ + gl_FragColor = color; + }else if(result < u_progress*2.0 && color.a > 0.1){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + }*/ + + + float value = coords.x + coords.y; + + vec4 color = texture2D(u_texture, t); + vec2 rc = vec2(round(coords.x), round(coords.y)); + vec2 center = ((u_uv + u_uv2)/2.0 - u_uv) /v; + + float r = clamp(rand(rc) + u_progress, 0.0, 1.0); + + const float start = 0.7; + const float end = 0.9; + + const float scl = 10.0; + float result = snoise(vec3(coords.x / scl, coords.y / scl, u_time/400.0))*2.0; + float dst = (abs(center.x - coords.x) + abs(center.y - coords.y)) / 2.0; + + if(dst - 1.0 < u_progress * (center.x) && dst> u_progress * (center.x) && color.a > 0.1){ + gl_FragColor = u_color; + }else if(r > end){ + gl_FragColor = color; + }else if(cont(t, v, 100.0) && mod(u_time / 1.5 + value, 20.0) < 5.0 && color.a > 0.1){ + gl_FragColor = u_color; + }else if(r > start && color.a > 0.1){ + float fr = (r-start)*(1.0/(end-start)); + + vec2 next = rc + chunk/2.0; + float rdst = max(abs(coords.x - next.x), abs(coords.y - next.y)) + result; + if(rdst / (chunk/2.0) < fr){ + gl_FragColor = u_color; + }else{ + gl_FragColor = vec4(0.0); + } + }else{ + gl_FragColor = vec4(0.0); + } +/* + if(mod(u_time / 1.5 + value, 30.0) < 15.0 && color.a > 0.1){ + gl_FragColor = u_color; + }else if(cont(t, v, 3.0)){ + gl_FragColor = color; + }else if(cont(t, v, 1.5)){ + gl_FragColor = u_color; + //}else if(mix(rand(vec2(dst)) * u_progress, 1.0, u_progress) > 0.5){ + // gl_FragColor = texture2D(u_texture, T); + }else{ + gl_FragColor = vec4(0.0); + }*/ +} diff --git a/core/src/io/anuke/mindustry/content/blocks/Blocks.java b/core/src/io/anuke/mindustry/content/blocks/Blocks.java index 61a1a5d426..da39825cef 100644 --- a/core/src/io/anuke/mindustry/content/blocks/Blocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/Blocks.java @@ -23,6 +23,18 @@ public class Blocks { blockpart = new BlockPart(), + build1 = new BuildBlock("build1"), + + build2 = new BuildBlock("build2"), + + build3 = new BuildBlock("build3"), + + build4 = new BuildBlock("build4"), + + build5 = new BuildBlock("build5"), + + build6 = new BuildBlock("build6"), + defaultFloor = new Floor("defaultfloor") {{ }}, diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 793d6a1f5c..5648caf72f 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -2,17 +2,14 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureWrap; import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.Pools; -import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; @@ -22,21 +19,18 @@ import io.anuke.mindustry.entities.effect.GroundEffectEntity; import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.game.TeamInfo.TeamData; import io.anuke.mindustry.graphics.*; -import io.anuke.mindustry.input.InputHandler; -import io.anuke.mindustry.input.PlaceMode; -import io.anuke.mindustry.ui.fragments.ToolFragment; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.BlockBar; -import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.*; import io.anuke.ucore.entities.EffectEntity; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.function.Callable; -import io.anuke.ucore.graphics.*; +import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Hue; +import io.anuke.ucore.graphics.Lines; +import io.anuke.ucore.graphics.Surface; import io.anuke.ucore.modules.RendererModule; import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.util.Mathf; @@ -49,7 +43,7 @@ import static io.anuke.ucore.core.Core.camera; public class Renderer extends RendererModule{ private final static float shieldHitDuration = 18f; - public Surface shadowSurface, shieldSurface, waterSurface; + public Surface effectSurface; private int targetscale = baseCameraScale; private Texture background = new Texture("sprites/background.png"); @@ -117,11 +111,9 @@ public class Renderer extends RendererModule{ public void init(){ pixelate = Settings.getBool("pixelate"); int scale = Settings.getBool("pixelate") ? Core.cameraScale : 1; - - shadowSurface = Graphics.createSurface(scale); - shieldSurface = Graphics.createSurface(scale); + + effectSurface = Graphics.createSurface(scale); pixelSurface = Graphics.createSurface(scale); - waterSurface = Graphics.createSurface(scale); } public void setPixelate(boolean pixelate){ @@ -165,7 +157,6 @@ public class Renderer extends RendererModule{ float prex = camera.position.x, prey = camera.position.y; updateShake(0.75f); - float prevx = camera.position.x, prevy = camera.position.y; clampCamera(-tilesize / 2f, -tilesize / 2f + 1, world.width() * tilesize - tilesize / 2f, world.height() * tilesize - tilesize / 2f); float deltax = camera.position.x - prex, deltay = camera.position.y - prey; @@ -212,9 +203,17 @@ public class Renderer extends RendererModule{ Entities.draw(groundEffectGroup, e -> !(e instanceof BelowLiquidEffect)); blocks.processBlocks(); - blocks.drawBlocks(Layer.overlay); + blocks.drawBlocks(Layer.block); - drawAllTeams(false); + Graphics.surface(effectSurface, true); + Graphics.shader(Shaders.inline, false); + blocks.drawBlocks(Layer.placement); + Graphics.shader(); + Graphics.flushSurface(); + + blocks.drawBlocks(Layer.overlay); + + drawAllTeams(false); blocks.skipLayer(Layer.turret); blocks.drawBlocks(Layer.laser); @@ -361,7 +360,7 @@ public class Renderer extends RendererModule{ void drawShield(){ if(shieldGroup.size() == 0 && shieldDraws.size == 0) return; - Graphics.surface(renderer.shieldSurface, false); + Graphics.surface(renderer.effectSurface, false); Draw.color(Color.ROYAL); Entities.draw(shieldGroup); for(Callable c : shieldDraws){ @@ -382,7 +381,7 @@ public class Renderer extends RendererModule{ } } - Texture texture = shieldSurface.texture(); + Texture texture = effectSurface.texture(); Shaders.shield.color.set(Color.SKY); Tmp.tr2.setRegion(texture); diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnitType.java b/core/src/io/anuke/mindustry/entities/units/GroundUnitType.java index da34b94480..00e9dd77c7 100644 --- a/core/src/io/anuke/mindustry/entities/units/GroundUnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/GroundUnitType.java @@ -132,7 +132,7 @@ public abstract class GroundUnitType extends UnitType{ } public void update(BaseUnit unit) { - //TODO move toward resupply point? + //TODO move toward resupply point if(unit.inventory.totalAmmo() + 10 >= unit.inventory.ammoCapacity()){ unit.state.set(unit, attack); } @@ -158,7 +158,7 @@ public abstract class GroundUnitType extends UnitType{ if(closest != null){ unit.target = closest; }else { - Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getEnemy(unit.team, BlockFlag.resupplyPoint)); + Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getEnemy(unit.team, BlockFlag.target)); if (target != null) unit.target = target.entity; } } diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 676d3c232d..4acd3ab5ff 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.graphics; -import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.game.Team; @@ -8,7 +7,6 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.types.StaticBlock; import io.anuke.ucore.core.Graphics; -import io.anuke.ucore.core.Settings; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; @@ -60,7 +58,7 @@ public class BlockRenderer{ int expandr = 4; - Graphics.surface(renderer.shadowSurface); + Graphics.surface(renderer.effectSurface); for(int x = -rangex - expandr; x <= rangex + expandr; x++){ for(int y = -rangey - expandr; y <= rangey + expandr; y++){ diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index a9ace6ecc4..623497e912 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -66,20 +66,20 @@ public enum CacheLayer { protected void beginShader(){ //renderer.getBlocks().endFloor(); - renderer.waterSurface.getBuffer().begin(); + renderer.effectSurface.getBuffer().begin(); Graphics.clear(Color.CLEAR); //renderer.getBlocks().beginFloor(); } public void endShader(Shader shader){ renderer.getBlocks().endFloor(); - renderer.waterSurface.getBuffer().end(); + renderer.effectSurface.getBuffer().end(); renderer.pixelSurface.getBuffer().begin(); Graphics.shader(shader); Graphics.begin(); - Draw.rect(renderer.waterSurface.texture(), Core.camera.position.x, Core.camera.position.y, + Draw.rect(renderer.effectSurface.texture(), Core.camera.position.x, Core.camera.position.y, Core.camera.viewportWidth * Core.camera.zoom, -Core.camera.viewportHeight * Core.camera.zoom); Graphics.end(); Graphics.shader(); diff --git a/core/src/io/anuke/mindustry/graphics/Layer.java b/core/src/io/anuke/mindustry/graphics/Layer.java index d4ef0ef4a3..623bc8cd9f 100644 --- a/core/src/io/anuke/mindustry/graphics/Layer.java +++ b/core/src/io/anuke/mindustry/graphics/Layer.java @@ -3,6 +3,8 @@ package io.anuke.mindustry.graphics; public enum Layer{ /**Base block layer.*/ block, + /**for placement*/ + placement, /**First overlay. Stuff like conveyor items.*/ overlay, /**"High" blocks, like turrets.*/ diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 88ed68d938..e8973a9ccc 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -15,6 +15,7 @@ import static io.anuke.mindustry.Vars.world; public class Shaders{ public static final Outline outline = new Outline(); + public static final Inline inline = new Inline(); public static final Shield shield = new Shield(); public static final SurfaceShader water = new SurfaceShader("water"); public static final SurfaceShader lava = new SurfaceShader("lava"); @@ -71,6 +72,25 @@ public class Shaders{ shader.setUniformf("u_texsize", vec.set(region.getTexture().getWidth(), region.getTexture().getHeight())); } } + + public static class Inline extends Shader{ + public Color color = new Color(); + public float progress; + + public Inline(){ + super("inline-lines", "default"); + } + + @Override + public void apply(){ + shader.setUniformf("u_progress", progress); + shader.setUniformf("u_color", color); + shader.setUniformf("u_uv", region.getU(), region.getV()); + shader.setUniformf("u_uv2", region.getU2(), region.getV2()); + shader.setUniformf("u_time", Timers.time()); + shader.setUniformf("u_texsize", vec.set(region.getTexture().getWidth(), region.getTexture().getHeight())); + } + } public static class Shield extends Shader{ public static final int MAX_HITS = 3*64; diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index b156ef948d..3c31d54ea7 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -203,9 +203,10 @@ public abstract class InputHandler extends InputAdapter{ NetEvents.handlePlace(player, x, y, result, rotation); } + //todo fix this, call placed() if(!Net.client()){ - Tile tile = world.tile(x, y); - if(tile != null) threads.run(() -> result.placed(tile)); + //Tile tile = world.tile(x, y); + //if(tile != null) threads.run(() -> result.placed(tile)); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index 9b1c077250..c3a881843d 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -166,13 +166,11 @@ public class SettingsMenuDialog extends SettingsDialog{ graphics.checkPref("pixelate", true, b -> { if(b){ renderer.pixelSurface.setScale(Core.cameraScale); - renderer.shadowSurface.setScale(Core.cameraScale); - renderer.shieldSurface.setScale(Core.cameraScale); + renderer.effectSurface.setScale(Core.cameraScale); //Graphics.getEffects1().setScale(Core.cameraScale); //Graphics.getEffects2().setScale(Core.cameraScale); }else{ - renderer.shadowSurface.setScale(1); - renderer.shieldSurface.setScale(1); + renderer.effectSurface.setScale(1); //Graphics.getEffects1().setScale(1); //Graphics.getEffects2().setScale(1); } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 08155567b6..e5144fc46b 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -304,6 +304,10 @@ public class Block extends BaseBlock { } } + public TextureRegion[] getBlockIcon(){ + return getIcon(); + } + public TextureRegion[] getCompactIcon(){ TextureRegion[] out = getIcon(); for(int i = 0; i < out.length; i ++){ diff --git a/core/src/io/anuke/mindustry/world/Placement.java b/core/src/io/anuke/mindustry/world/Placement.java index a7e05c1ac3..5e52f3f036 100644 --- a/core/src/io/anuke/mindustry/world/Placement.java +++ b/core/src/io/anuke/mindustry/world/Placement.java @@ -10,6 +10,7 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Recipe; +import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; import io.anuke.ucore.core.Effects; import io.anuke.ucore.entities.Entities; @@ -62,7 +63,10 @@ public class Placement { //just in case if(tile == null) return; - tile.setBlock(result, rotation); + Block sub = Block.getByName("build" + result.size); + + tile.setBlock(sub, rotation); + tile.entity().result = result; tile.setTeam(team); if(result.isMultiblock()){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java new file mode 100644 index 0000000000..3a5d5fed80 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java @@ -0,0 +1,73 @@ +package io.anuke.mindustry.world.blocks.types; + +import com.badlogic.gdx.graphics.Colors; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.graphics.Layer; +import io.anuke.mindustry.graphics.Shaders; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Graphics; +import io.anuke.ucore.graphics.Draw; + +public class BuildBlock extends Block { + private static final float buildTime = 120f; + + public BuildBlock(String name) { + super(name); + solid = true; + update = true; + size = Integer.parseInt(name.charAt(name.length()-1) + ""); + health = 1; + layer = Layer.placement; + } + + @Override + public void draw(Tile tile){ + + } + + @Override + public void drawLayer(Tile tile) { + BuildEntity entity = tile.entity(); + + Shaders.inline.color = Colors.get("accent"); + + for(TextureRegion region : entity.result.getBlockIcon()){ + Shaders.inline.region = region; + Shaders.inline.progress = entity.progress; + Shaders.inline.apply(); + Draw.rect(region, tile.drawx(), tile.drawy()); + Graphics.flush(); + } + } + + @Override + public void drawShadow(Tile tile) { + BuildEntity entity = tile.entity(); + + entity.result.drawShadow(tile); + } + + @Override + public void update(Tile tile) { + BuildEntity entity = tile.entity(); + entity.progress += 1f/buildTime; + if(entity.progress > 1f){ + Team team = tile.getTeam(); + tile.setBlock(entity.result); + tile.setTeam(team); + } + } + + @Override + public TileEntity getEntity() { + return new BuildEntity(); + } + + public class BuildEntity extends TileEntity{ + public Block result; + public float progress; + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java index a9c50a903f..81b58a6881 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/defense/Turret.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.world.blocks.types.defense; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.entities.*; @@ -18,7 +19,10 @@ import io.anuke.ucore.core.Timers; import io.anuke.ucore.function.BiConsumer; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; -import io.anuke.ucore.util.*; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.Strings; +import io.anuke.ucore.util.Translator; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -111,6 +115,11 @@ public abstract class Turret extends Block{ Draw.color(); } + + @Override + public TextureRegion[] getBlockIcon(){ + return new TextureRegion[]{Draw.region("block-" + size), Draw.region(name)}; + } @Override public void drawSelect(Tile tile){