diff --git a/core/assets-raw/sprites/blocks/defense/barrier-projector-team.png b/core/assets-raw/sprites/blocks/defense/barrier-projector-team.png new file mode 100644 index 0000000000..4eba1ac6a8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/defense/barrier-projector-team.png differ diff --git a/core/assets-raw/sprites/blocks/defense/barrier-projector.png b/core/assets-raw/sprites/blocks/defense/barrier-projector.png new file mode 100644 index 0000000000..edac72c033 Binary files /dev/null and b/core/assets-raw/sprites/blocks/defense/barrier-projector.png differ diff --git a/core/assets-raw/sprites/blocks/turrets/lancer-heat.png b/core/assets-raw/sprites/blocks/turrets/lancer-heat.png index d1494ebefb..e2a5442ebd 100644 Binary files a/core/assets-raw/sprites/blocks/turrets/lancer-heat.png and b/core/assets-raw/sprites/blocks/turrets/lancer-heat.png differ diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties index 61b222cbed..a41bca283a 100755 --- a/core/assets/icons/icons.properties +++ b/core/assets/icons/icons.properties @@ -476,3 +476,4 @@ 63230=titan|block-titan-ui 63229=horde|block-horde-ui 63228=small-deconstructor|block-small-deconstructor-ui +63227=barrier-projector|block-barrier-projector-ui diff --git a/core/assets/logicids.dat b/core/assets/logicids.dat index 55fa2bf2f0..9f8fb3668a 100644 Binary files a/core/assets/logicids.dat and b/core/assets/logicids.dat differ diff --git a/core/assets/shaders/shield.frag b/core/assets/shaders/shield.frag index d4fdd10998..ae0d8fab72 100644 --- a/core/assets/shaders/shield.frag +++ b/core/assets/shaders/shield.frag @@ -18,24 +18,32 @@ void main(){ T += vec2(sin(coords.y / 3.0 + u_time / 20.0), sin(coords.x / 3.0 + u_time / 20.0)) / u_texsize; - vec4 color = texture2D(u_texture, T); - vec2 v = u_invsize; + vec4 color = texture2D(u_texture, T); + vec2 v = u_invsize; - vec4 maxed = max(max(max(texture2D(u_texture, T + vec2(0, step) * v), texture2D(u_texture, T + vec2(0, -step) * v)), texture2D(u_texture, T + vec2(step, 0) * v)), texture2D(u_texture, T + vec2(-step, 0) * v)); + vec4 maxed = max(max(max(max(max(max(max( + texture2D(u_texture, T + vec2(0, step) * v), + texture2D(u_texture, T + vec2(0, -step) * v)), + texture2D(u_texture, T + vec2(step, 0) * v)), + texture2D(u_texture, T + vec2(-step, 0) * v)), - if(texture2D(u_texture, T).a < 0.9 && maxed.a > 0.9){ + texture2D(u_texture, T + vec2(-step, -step) * v)), + texture2D(u_texture, T + vec2(-step, step) * v)), + texture2D(u_texture, T + vec2(step, -step) * v)), + texture2D(u_texture, T + vec2(step, step) * v)); - gl_FragColor = vec4(maxed.rgb, maxed.a * 100.0); - }else{ + if(texture2D(u_texture, T).a < 0.9 && maxed.a > 0.9){ + gl_FragColor = vec4(maxed.rgb, maxed.a * 100.0); + }else{ - if(color.a > 0.0){ - if(mod(coords.x / u_dp + coords.y / u_dp + sin(coords.x / u_dp / 5.0) * 3.0 + sin(coords.y / u_dp / 5.0) * 3.0 + u_time / 4.0, 10.0) < 2.0){ - color *= 1.65; - } - - color.a = ALPHA; - } - - gl_FragColor = color; - } + if(color.a > 0.0){ + if(mod(coords.x / u_dp + coords.y / u_dp + sin(coords.x / u_dp / 5.0) * 3.0 + sin(coords.y / u_dp / 5.0) * 3.0 + u_time / 4.0, 10.0) < 2.0){ + color *= 1.65; + } + + color.a = ALPHA; + } + + gl_FragColor = color; + } } diff --git a/core/src/mindustry/ai/types/MissileAI.java b/core/src/mindustry/ai/types/MissileAI.java index 9c58922beb..89630dc36d 100644 --- a/core/src/mindustry/ai/types/MissileAI.java +++ b/core/src/mindustry/ai/types/MissileAI.java @@ -3,6 +3,7 @@ package mindustry.ai.types; import mindustry.entities.units.*; public class MissileAI extends AIController{ + //TODO store 'main' target and use that as a fallback //TODO UNPREDICTABLE TARGETING @Override diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index e8eccd5c46..409235fd28 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -79,7 +79,7 @@ public class Blocks{ //defense - erekir buildTower, //TODO name - regenProjector, + regenProjector, barrierProjector, //transport conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router, @@ -1509,6 +1509,18 @@ public class Blocks{ }}); }}; + barrierProjector = new DirectionalForceProjector("barrier-projector"){{ + //TODO + requirements(Category.effect, with(Items.surgeAlloy, 100, Items.silicon, 125)); + size = 3; + radius = 50f; + shieldHealth = 2000f; + cooldownNormal = 3f; + cooldownBrokenBase = 0.35f; + + consumes.power(4f); + }}; + //endregion //region distribution diff --git a/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java b/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java index 3626b68ec6..4525c9102c 100644 --- a/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/DirectionalForceProjector.java @@ -1,18 +1,125 @@ package mindustry.world.blocks.defense; +import arc.func.*; +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.math.geom.*; +import arc.util.*; +import mindustry.gen.*; +import mindustry.graphics.*; + +import static mindustry.Vars.*; + public class DirectionalForceProjector extends ForceProjector{ + protected static final Vec2 intersectOut = new Vec2(), p1 = new Vec2(), p2 = new Vec2(); + protected static final Cons dirShieldConsumer = b -> { + if(b.team != paramEntity.team && b.type.absorbable){ + //just in case + float deltaAdd = 1.1f; + + if(Intersector.intersectSegments(b.x, b.y, b.x + b.vel.x * (Time.delta + deltaAdd), b.y + b.vel.y * (Time.delta + deltaAdd), p1.x, p1.y, p2.x, p2.y, intersectOut)){ + b.set(intersectOut); + b.absorb(); + paramEffect.at(b); + paramEntity.hit = 1f; + paramEntity.buildup += b.damage(); + } + } + }; + + //TODO proper length? + public float length = 40f; + public float padSize = 40f; public DirectionalForceProjector(String name){ super(name); + radius = 30f; consumeCoolant = false; + rotate = true; + rotateDraw = false; + } + + @Override + public void init(){ + super.init(); + if(length < 0){ + length = size * tilesize/2f; + } + } + + @Override + public void drawPlace(int x, int y, int rotation, boolean valid){ + drawPotentialLinks(x, y); + + //TODO } public class DirectionalForceProjectorBuild extends ForceBuild{ @Override public void deflectBullets(){ - //TODO + float realRadius = realRadius(); + + if(realRadius > 0 && !broken){ + paramEntity = this; + paramEffect = absorbEffect; + + //top + p1.set(length, realRadius).rotate(rotdeg()); + //bot + p2.set(length, -realRadius).rotate(rotdeg()); + + //"check" radius is grown to catch bullets moving at high velocity + Tmp.r1.set(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y).normalize().grow(padSize); + + p1.add(x, y); + p2.add(x, y); + + Groups.bullet.intersect(x + Tmp.r1.x, y + Tmp.r1.y, Tmp.r1.width, Tmp.r1.height, dirShieldConsumer); + } + } + + @Override + public void drawShield(){ + if(!broken && realRadius() > 0){ + float realRadius = realRadius(), rot = rotdeg(); + + p1.set(length, realRadius).rotate(rot).add(this); + p2.set(length, -realRadius).rotate(rot).add(this); + float size = 3f; + Tmp.r1.set(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y).normalize().grow(size); + + Draw.z(Layer.shields); + + Draw.color(team.color, Color.white, Mathf.clamp(hit)); + + if(renderer.animateShields){ + Fill.rect(Tmp.r1); + + Tmp.v1.set(length - size/2f - size * 2, (realRadius + size/2f)).rotate(rot).add(this); + Tmp.v2.set(length - size/2f - size * 2, -(realRadius + size/2f)).rotate(rot).add(this); + + Fill.tri(x, y, Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y); + + for(int i : Mathf.signs){ + Tmp.v1.set(length - size/2f, (realRadius + size/2f) * i).rotate(rot).add(this); + Tmp.v3.set(length + size/2f, (realRadius + size/2f) * i).rotate(rot).add(this); + Tmp.v2.set(length, (realRadius + size) * i).rotate(rot).add(this); + Fill.tri(Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y, Tmp.v3.x, Tmp.v3.y); + } + }else{ + Lines.stroke(1.5f); + Draw.alpha(0.09f + Mathf.clamp(0.08f * hit)); + Fill.rect(Tmp.r1); + Draw.alpha(1f); + Lines.rect(Tmp.r1); + Draw.reset(); + } + + Draw.reset(); + } } } } diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index bd50bf7b0d..488d366cc3 100644 --- a/core/src/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/ForceProjector.java @@ -1,6 +1,5 @@ package mindustry.world.blocks.defense; -import arc.*; import arc.func.*; import arc.graphics.*; import arc.graphics.g2d.*; @@ -229,7 +228,7 @@ public class ForceProjector extends Block{ Draw.color(team.color, Color.white, Mathf.clamp(hit)); - if(Core.settings.getBool("animatedshields")){ + if(renderer.animateShields){ Fill.poly(x, y, 6, radius); }else{ Lines.stroke(1.5f);