From 438661e23961d1fbac4d40e8545577e4ae3a6e68 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 22 Dec 2021 16:43:22 -0500 Subject: [PATCH] Regen projector 'done' --- .../blocks/defense/regen-projector-mid.png | Bin 0 -> 791 bytes .../defense/regen-projector-side-glow.png | Bin 7155 -> 0 bytes .../blocks/defense/regen-projector-top1.png | Bin 760 -> 0 bytes .../blocks/defense/regen-projector-top2.png | Bin 756 -> 0 bytes .../blocks/defense/regen-projector.png | Bin 2052 -> 2989 bytes core/src/mindustry/ai/BlockIndexer.java | 23 +++++ core/src/mindustry/content/Blocks.java | 22 +++-- .../src/mindustry/content/ErekirTechTree.java | 8 +- core/src/mindustry/game/SpawnGroup.java | 5 + .../maps/planet/ErekirPlanetGenerator.java | 3 +- core/src/mindustry/type/Liquid.java | 2 +- .../world/blocks/defense/RegenProjector.java | 90 ++++-------------- .../mindustry/world/draw/DrawGlowRegion.java | 5 + .../src/mindustry/world/draw/DrawPartial.java | 11 +++ .../mindustry/world/draw/DrawPulseShape.java | 55 +++++++++++ core/src/mindustry/world/draw/DrawShape.java | 25 +++++ 16 files changed, 165 insertions(+), 84 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/defense/regen-projector-mid.png delete mode 100644 core/assets-raw/sprites/blocks/defense/regen-projector-side-glow.png delete mode 100644 core/assets-raw/sprites/blocks/defense/regen-projector-top1.png delete mode 100644 core/assets-raw/sprites/blocks/defense/regen-projector-top2.png create mode 100644 core/src/mindustry/world/draw/DrawPartial.java create mode 100644 core/src/mindustry/world/draw/DrawPulseShape.java create mode 100644 core/src/mindustry/world/draw/DrawShape.java diff --git a/core/assets-raw/sprites/blocks/defense/regen-projector-mid.png b/core/assets-raw/sprites/blocks/defense/regen-projector-mid.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f5c37581b61d9b1c83d29181b145af79ba71da GIT binary patch literal 791 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGojKx9jP7LeL$-HD>V7ln(;uumf z=k2X*f8juZV;}!di_#9L2sB+VsiE$Fe~OCZlo_8End|I*^YQ4J!s%j83K!2!dOkfz zZp+pVuErKU3Q*Kprpy!B6V0n4-l zTpF{dbR1JT(7d0yq~W@Qc*WD@;sr`%~C@{>(_~ zj4)H=e4A_jz%cvZd&b%awjac9d_S#rfZ>O0=rj+_R)41#ENfW*GjRW6f52kF#`pJ< z;s;@Ef894{<$fAFsVn9%$#MKse;{JPY*%E?Xq)4caaB&(j#E)MK)Rs#=E;Nh%=>e@3$h^Ah&{k*{X+d^N0mvlj*-6iC z)%RTeqrB$%_dhjx^|g-M80wN!GhZBMnLjIN>QaG4Y71JwzS1+hYV&1r`_#F7<>7~N z|KDC0KY9KA@`@ZrJB5oal7l)f2v{6^Ka2yXc2e1Jv7bz+d0cFqNv z#M|7mIv>7P)_I!p?mgJ_U-rkddHWx{b9%$Y{U`i^ z%#TLZ)K}-V{s-Tluad%a?H<#On7ivXtW2xbekA05!19|K&xRu{Z~qFIFn%!S^!{HO zVm+1ph2iYkh2jzC&u_K=v#sO?%YnU~CybX^ihcRLZSne*Rdp{OIDcR{;3l--)^*8G zO#3EqZa1pw*f)vCA^sHm$4UQmU0ra3S+DtT?dLzR^lsQfU`l83boFyt=akR{00=N@ A1^@s6 literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/blocks/defense/regen-projector-side-glow.png b/core/assets-raw/sprites/blocks/defense/regen-projector-side-glow.png deleted file mode 100644 index b8288fe7c461c3d439856af0c68a59089195396f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7155 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 m0JJ{z0{{R30002s|KK<44zeRFHvj4X0000 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 S*fIhPx+zDYzuRCt{2T|I9jHxPX?{1Z|*z1%2q zYrueiK@RZYlGe4)K!6}skn++6u7XsGYPENQ4fuXR00U`#r$*|X;{JnD94K%pe!L-v z-1SAT@>;t~?t7deIh43ah7Ww~kP@Dw?uv-6~{CsSH9Z%B1q5BUFw~2Y*BZPoXt`XgkG^S}Gwzl~ng zpuud1s9Otg$p?Uzmf(_a@bTTJ?D9g_hROn(S?iYT1HezdK?@OLgaCOWq^|Lm+1OQX z0ATdpiyx>Cmvu)WvD|BoJBpEib9&S{X5EoXzUzW)7=L%TD6Z-t+a;;(sA`39EEkW8EhDg4Fv~C)fkRWKV>_aFly2juzklqwAXfwl`35l&`XHaZcdTx9oGMoYU*cDE z>dh7u@_RYcbGje&vHm{BV{tGpRtd>;eZ6|57W!kqv&2fQEOsv2Kx3%B9>9oT zpQD-l6$2YWsf{KJGBFW+zxhOvCVw$V1rb|d^x?N3gM9##44cYqw&C^(DeEw~sDHWf zoZLP^LOzo=6XP)|K;w7` zL4$k)Z4tD{2LzpPOA$25H_#G6lYF4UD5z9~8sr<4icp%T>O+-bXs!q~$v4Oqp$7Rt z&xu)k>;>o@djWdJUVxsl7ocZU5q}^zG|}Q6vfR)_$(uScs0&aU7pf^jXD!nTB1Dt9Uix#prwF8M$=>pO>h!2jOB zVAIpJEun;b8`|mV$-E#N&wo{fA(8Jw)Cseu$9{64g*$3ZzBFN%7Qjq6T8mH*)V%gQ^(l%j(-682rVQ+G#o7f z8^WE==9}0&p=Kx|71nkei0^wxK>qNU3PqHl)Dl``MTE)-)ycI4?NEvOH{*c3k9kPG z;2WB0N>=CWcopLswO(y?QDr?qY6%+Tr+#x`%53$azz}EwYJEFXLI6XsL@(xj;&ZDD0_ce|*P z{FQ>*L`<4AH6#)2x@abUF%a(~7DFu9Shp7OwyR002ovPDHLkV1jqd%Nqay diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java index 19c3d0f206..f39358d853 100644 --- a/core/src/mindustry/ai/BlockIndexer.java +++ b/core/src/mindustry/ai/BlockIndexer.java @@ -236,6 +236,29 @@ public class BlockIndexer{ return size > 0; } + /** Does not work with null teams. */ + public boolean eachBlock(Team team, Rect rect, Boolf pred, Cons cons){ + breturnArray.clear(); + + var buildings = team.data().buildings; + if(buildings == null) return false; + buildings.intersect(rect, b -> { + if(pred.get(b)){ + breturnArray.add(b); + } + }); + + int size = breturnArray.size; + var items = breturnArray.items; + for(int i = 0; i < size; i++){ + cons.get(items[i]); + items[i] = null; + } + breturnArray.size = 0; + + return size > 0; + } + /** Get all enemy blocks with a flag. */ public Seq getEnemy(Team team, BlockFlag type){ breturnArray.clear(); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 7ec6f65382..aab855be8c 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1527,7 +1527,7 @@ public class Blocks{ }}; buildTower = new BuildTurret("build-tower"){{ - requirements(Category.effect, with(Items.silicon, 60, Items.tungsten, 60, Items.oxide, 40)); + requirements(Category.effect, with(Items.silicon, 80, Items.carbide, 30, Items.oxide, 40, Items.thorium, 30)); outlineColor = Pal.darkOutline; consumes.power(3f); range = 150f; @@ -1538,21 +1538,25 @@ public class Blocks{ //TODO green looks bad switch to orange //TODO orange also looks bad hhhh regenProjector = new RegenProjector("regen-projector"){{ - requirements(Category.effect, with(Items.silicon, 60, Items.tungsten, 60, Items.oxide, 40)); + requirements(Category.effect, with(Items.silicon, 60, Items.tungsten, 60, Items.oxide, 30)); size = 3; consumes.power(1f); - rangeWidth = 6; - rangeLength = 22; + range = 28; consumes.liquid(Liquids.hydrogen, 1f / 60f); healPercent = 4f / 60f; - drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.hydrogen, 9f / 4f), new DrawSideRegion(true), new DrawGlowRegion(){{ - //color = Color.valueOf("1eff21"); - }}, new DrawGlowRegion(true){{ - suffix = "-side-glow"; - alpha = 1f; + drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.hydrogen, 9f / 4f), new DrawBlock(), new DrawGlowRegion(){{ + color = Color.orange;//Color.valueOf("1eff21"); + }}, new DrawPulseShape(false){{ + //radiusScl = 0.95f; + layer = Layer.effect; + }}, new DrawShape(){{ + layer = Layer.effect; + radius = 3.5f; + useWarmupRadius = true; + timeScl = 2f; }}); }}; diff --git a/core/src/mindustry/content/ErekirTechTree.java b/core/src/mindustry/content/ErekirTechTree.java index 7caac5a5b9..40f7702036 100644 --- a/core/src/mindustry/content/ErekirTechTree.java +++ b/core/src/mindustry/content/ErekirTechTree.java @@ -69,10 +69,12 @@ public class ErekirTechTree{ }); - //TODO more tiers of build tower or "support" structures like overdrive projectors - //TODO method of repairing blocks of damage - node(buildTower, () -> { + node(regenProjector, () -> { + //TODO more tiers of build tower or "support" structures like overdrive projectors + node(buildTower, () -> { + + }); }); }); }); diff --git a/core/src/mindustry/game/SpawnGroup.java b/core/src/mindustry/game/SpawnGroup.java index 1d70384a47..cc5879ca13 100644 --- a/core/src/mindustry/game/SpawnGroup.java +++ b/core/src/mindustry/game/SpawnGroup.java @@ -42,6 +42,8 @@ public class SpawnGroup implements JsonSerializable, Cloneable{ public int unitAmount = 1; /** If not -1, the unit will only spawn in spawnpoints with these packed coordinates. */ public int spawn = -1; + /** Fraction of health that unit is spawned with. */ + public float healthFraction = 1f; /** Seq of payloads that this unit will spawn with. */ public @Nullable Seq payloads; /** Status effect applied to the spawned unit. Null to disable. */ @@ -91,6 +93,7 @@ public class SpawnGroup implements JsonSerializable, Cloneable{ } unit.shield = getShield(wave); + unit.health = unit.maxHealth * healthFraction; //load up spawn payloads if(payloads != null && unit instanceof Payloadc pay){ @@ -118,6 +121,7 @@ public class SpawnGroup implements JsonSerializable, Cloneable{ if(unitAmount != 1) json.writeValue("amount", unitAmount); if(effect != null) json.writeValue("effect", effect.name); if(spawn != -1) json.writeValue("spawn", spawn); + if(healthFraction != 1f) json.writeValue("healthFraction", healthFraction); if(payloads != null && payloads.size > 0){ json.writeValue("payloads", payloads.map(u -> u.name).toArray(String.class)); } @@ -138,6 +142,7 @@ public class SpawnGroup implements JsonSerializable, Cloneable{ shieldScaling = data.getFloat("shieldScaling", 0); unitAmount = data.getInt("amount", 1); spawn = data.getInt("spawn", -1); + healthFraction = data.getFloat("healthFraction", 1f); if(data.has("payloads")){ payloads = Seq.with(json.readValue(String[].class, data.get("payloads"))).map(s -> content.getByName(ContentType.unit, s)); } diff --git a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java index ec30788a27..261ed2b7b5 100644 --- a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java @@ -255,12 +255,13 @@ public class ErekirPlanetGenerator extends PlanetGenerator{ state.rules.waves = true; state.rules.showSpawns = true; state.rules.waveTimer = true; - state.rules.waveSpacing = 60f * 60f * 15f; + state.rules.waveSpacing = 60f * 60f * 7.5f; state.rules.spawns = Seq.with(new SpawnGroup(){{ type = UnitTypes.vanquish; spacing = 1; shieldScaling = 60; unitScaling = 2f; + healthFraction = 0.2f; }}); } } diff --git a/core/src/mindustry/type/Liquid.java b/core/src/mindustry/type/Liquid.java index d6a4e2a380..15e6a81be4 100644 --- a/core/src/mindustry/type/Liquid.java +++ b/core/src/mindustry/type/Liquid.java @@ -22,7 +22,7 @@ public class Liquid extends UnlockableContent{ protected static final Rand rand = new Rand(); - /** TODO If true, this fluid is treated as a gas (and does not create puddles) */ + /** If true, this fluid is treated as a gas (and does not create puddles) */ public boolean gas = false; /** Color used in pipes and on the ground. */ public Color color; diff --git a/core/src/mindustry/world/blocks/defense/RegenProjector.java b/core/src/mindustry/world/blocks/defense/RegenProjector.java index 28064eb393..5292c6d104 100644 --- a/core/src/mindustry/world/blocks/defense/RegenProjector.java +++ b/core/src/mindustry/world/blocks/defense/RegenProjector.java @@ -3,7 +3,6 @@ package mindustry.world.blocks.defense; import arc.*; import arc.graphics.g2d.*; import arc.math.*; -import arc.math.geom.*; import arc.struct.*; import arc.util.*; import mindustry.content.*; @@ -23,27 +22,19 @@ public class RegenProjector extends Block{ private static final IntFloatMap mendMap = new IntFloatMap(); private static long lastUpdateFrame = -1; - //cached points per-block for drawing convenience - protected @Nullable Vec2[] drawPoints; - - public int rangeLength = 14, rangeWidth = 5; + public int range = 14; //per frame public float healPercent = 12f / 60f; public DrawBlock drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawSideRegion(true)); - public float effectChance = 0.011f; + public float effectChance = 0.013f; public Effect effect = Fx.regenParticle; - public float beamSpacing = 60f * 7f, beamWidening = 5f, beamLenScl = 1.2f, beamStroke = 2f; - public Interp beamInterp = Interp.pow2Out; - public int beams = 6; - public RegenProjector(String name){ super(name); solid = true; update = true; - rotate = true; group = BlockGroup.projectors; hasPower = true; hasItems = true; @@ -56,28 +47,7 @@ public class RegenProjector extends Block{ public void drawPlace(int x, int y, int rotation, boolean valid){ super.drawPlace(x, y, rotation, valid); - drawBounds(x * tilesize + offset, y * tilesize + offset, rotation); - } - - public void drawBounds(float x, float y, int rotation){ - if(drawPoints == null){ - drawPoints = new Vec2[]{ - new Vec2(1f, -rangeWidth), - new Vec2(1f + rangeLength, -rangeWidth), - new Vec2(1f + rangeLength, rangeWidth), - new Vec2(1f + 0f, rangeWidth), - }; - for(var v : drawPoints){ - v.scl(tilesize); - } - } - - for(int i = 0; i < 4; i++){ - Tmp.v1.set(drawPoints[i]).rotate(rotation * 90).add(x, y); - Tmp.v2.set(drawPoints[(i + 1) % 4]).rotate(rotation * 90).add(x, y); - - Drawf.dashLine(Pal.accent, Tmp.v1.x, Tmp.v1.y, Tmp.v2.x, Tmp.v2.y); - } + Drawf.dashSquare(Pal.accent, x, y, range * tilesize); } @Override @@ -105,25 +75,12 @@ public class RegenProjector extends Block{ public Seq targets = new Seq<>(); public int lastChange = -2; public float warmup, totalTime; + public boolean didRegen = false; public void updateTargets(){ targets.clear(); taken.clear(); - float rot = rotation * 90; - - for(int cy = -rangeWidth; cy <= rangeWidth; cy++){ - for(int cx = 1; cx <= rangeLength + 1; cx++){ - - //TODO handle offset - float wx = x/tilesize + Angles.trnsx(rot, cx, cy), wy = y/tilesize + Angles.trnsy(rot, cx, cy); - - Building build = world.build((int)wx, (int)wy); - - if(build != null && build.team == team && taken.add(build.id)){ - targets.add(build); - } - } - } + indexer.eachBlock(team, Tmp.r1.setCentered(x, y, range * tilesize), b -> true, targets::add); } @Override @@ -133,14 +90,18 @@ public class RegenProjector extends Block{ updateTargets(); } - warmup = Mathf.approachDelta(warmup, consValid() ? 1f : 0f, 1f / 70f); + //TODO should warmup depend on didRegen? + warmup = Mathf.approachDelta(warmup, consValid() && didRegen ? 1f : 0f, 1f / 70f); totalTime += warmup * Time.delta; + didRegen = false; if(consValid()){ //use Math.max to prevent stacking for(Building build : targets){ if(!build.damaged()) continue; + didRegen = true; + int pos = build.pos(); //TODO periodic effect float value = mendMap.get(pos); @@ -165,10 +126,19 @@ public class RegenProjector extends Block{ } } + @Override + public boolean productionValid(){ + return didRegen; + } + @Override public void drawSelect(){ super.drawSelect(); - drawBounds(x, y, rotation); + + Drawf.dashSquare(Pal.accent, x, y, range * tilesize); + for(var target : targets){ + Drawf.selected(target, Pal.accent); + } } @Override @@ -184,26 +154,6 @@ public class RegenProjector extends Block{ @Override public void draw(){ drawer.drawBase(this); - - for(int i = 0; i < beams; i++){ - float life = beamInterp.apply((totalTime / beamSpacing + i / (float)beams) % 1f); - float len = life * rangeLength*beamLenScl * tilesize + size * tilesize/2f; - float width = Math.min(life * rangeWidth * 2f * tilesize * beamWidening, rangeWidth * 2f * tilesize); - float stroke = (0.5f + beamStroke * life) * warmup; - Draw.z(Layer.effect); - - Lines.stroke(stroke, Pal.accent); - Draw.alpha(1f - Mathf.curve(life, 0.5f)); - Lines.lineAngleCenter( - x + Angles.trnsx(rotdeg(), len), - y + Angles.trnsy(rotdeg(), len), - rotdeg() + 90f, - width - ); - - Draw.reset(); - } - } @Override diff --git a/core/src/mindustry/world/draw/DrawGlowRegion.java b/core/src/mindustry/world/draw/DrawGlowRegion.java index 3bcf71cf02..445183b4d1 100644 --- a/core/src/mindustry/world/draw/DrawGlowRegion.java +++ b/core/src/mindustry/world/draw/DrawGlowRegion.java @@ -32,6 +32,11 @@ public class DrawGlowRegion extends DrawBlock{ this.rotate = rotate; } + + public DrawGlowRegion(String suffix){ + this.suffix = suffix; + } + @Override public void drawBase(Building build){ if(build.warmup() <= 0.001f) return; diff --git a/core/src/mindustry/world/draw/DrawPartial.java b/core/src/mindustry/world/draw/DrawPartial.java new file mode 100644 index 0000000000..96ef7fccc7 --- /dev/null +++ b/core/src/mindustry/world/draw/DrawPartial.java @@ -0,0 +1,11 @@ +package mindustry.world.draw; + +import arc.util.*; +import mindustry.entities.units.*; +import mindustry.world.*; + +public abstract class DrawPartial extends DrawBlock{ + + @Override + public void drawPlan(Block block, BuildPlan plan, Eachable list){} +} diff --git a/core/src/mindustry/world/draw/DrawPulseShape.java b/core/src/mindustry/world/draw/DrawPulseShape.java new file mode 100644 index 0000000000..2535e7ef31 --- /dev/null +++ b/core/src/mindustry/world/draw/DrawPulseShape.java @@ -0,0 +1,55 @@ +package mindustry.world.draw; + +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 DrawPulseShape extends DrawPartial{ + public Color color = Pal.accent.cpy(); + public float stroke = 2f, timeScl = 100f, minStroke = 0.2f; + public float radiusScl = 1f; + public float layer = -1f; + public boolean square = true; + + public DrawPulseShape(boolean square){ + this.square = square; + } + + public DrawPulseShape(){ + } + + @Override + public void drawBase(Building build){ + float pz = Draw.z(); + if(layer > 0) Draw.z(layer); + + float f = 1f - (Time.time / timeScl) % 1f; + float rad = build.block.size * tilesize / 2f * radiusScl; + + Draw.color(color); + Lines.stroke((stroke * f + minStroke) * build.warmup()); + + if(square){ + Lines.square(build.x, build.y, Math.min(1f + (1f - f) * rad, rad)); + }else{ + float r = Math.max(0f, Mathf.clamp(2f - f * 2f) * rad - f - 0.2f), w = Mathf.clamp(0.5f - f) * rad * 2f; + Lines.beginLine(); + for(int i = 0; i < 4; i++){ + Lines.linePoint(build.x + Geometry.d4(i).x * r + Geometry.d4(i).y * w, build.y + Geometry.d4(i).y * r - Geometry.d4(i).x * w); + if(f < 0.5f) Lines.linePoint(build.x + Geometry.d4(i).x * r - Geometry.d4(i).y * w, build.y + Geometry.d4(i).y * r + Geometry.d4(i).x * w); + } + Lines.endLine(true); + } + + + + Draw.reset(); + Draw.z(pz); + } +} diff --git a/core/src/mindustry/world/draw/DrawShape.java b/core/src/mindustry/world/draw/DrawShape.java new file mode 100644 index 0000000000..f7a5299116 --- /dev/null +++ b/core/src/mindustry/world/draw/DrawShape.java @@ -0,0 +1,25 @@ +package mindustry.world.draw; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import mindustry.gen.*; +import mindustry.graphics.*; + +public class DrawShape extends DrawPartial{ + public Color color = Pal.accent.cpy(); + public int sides = 4; + public float radius = 2f, timeScl = 1f, layer = -1f, x, y; + public boolean useWarmupRadius = false; + + @Override + public void drawBase(Building build){ + float pz = Draw.z(); + if(layer > 0) Draw.z(layer); + + Draw.color(color); + Fill.poly(build.x + x, build.y + y, sides, useWarmupRadius ? radius * build.warmup() : radius, build.totalProgress() * timeScl); + + Draw.reset(); + Draw.z(pz); + } +}