From 9251ba6008f8ceea855784ca7990a21b49e94209 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 Apr 2022 22:49:36 -0400 Subject: [PATCH] Better continuous laser bullet visuals --- .../assets-raw/sprites/units/obviate-heat.png | Bin 0 -> 2666 bytes core/src/mindustry/content/UnitTypes.java | 43 +++++++++++++++++- core/src/mindustry/entities/Damage.java | 5 -- .../bullet/ContinuousFlameBulletType.java | 19 ++++---- .../bullet/ContinuousLaserBulletType.java | 32 ++++++++----- .../entities/bullet/LaserBulletType.java | 2 +- core/src/mindustry/graphics/Drawf.java | 27 +++++++++-- 7 files changed, 93 insertions(+), 35 deletions(-) create mode 100644 core/assets-raw/sprites/units/obviate-heat.png diff --git a/core/assets-raw/sprites/units/obviate-heat.png b/core/assets-raw/sprites/units/obviate-heat.png new file mode 100644 index 0000000000000000000000000000000000000000..410a97bd0d9ac736dcee5787582dc9d9cd7b3eb7 GIT binary patch literal 2666 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 literal 0 HcmV?d00001 diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index ce05ab12da..c7eb83b361 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -473,7 +473,7 @@ public class UnitTypes{ mirror = false; top = false; shake = 4f; - shootY = 13f; + shootY = 14f; x = y = 0f; shoot.firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f; @@ -3339,7 +3339,6 @@ public class UnitTypes{ }}; obviate = new ErekirUnitType("obviate"){{ - lowAltitude = false; flying = true; drag = 0.08f; speed = 1.9f; @@ -3352,10 +3351,50 @@ public class UnitTypes{ engineOffset = 54f / 4f; fogRadius = 25; itemCapacity = 0; + lowAltitude = true; setEnginesMirror( new UnitEngine(59 / 4f, -25 / 4f, 3.1f, 315f) ); + + parts.add(new RegionPart("-heat"){{ + blending = Blending.additive; + progress = PartProgress.heat; + outline = false; + colorTo = new Color(1f, 0.5f, 0.5f, 0.7f); + color = colorTo.cpy().a(0f); + layerOffset = 0.01f; + }}); + + //TODO this is really dumb. + weapons.add(new Weapon(){{ + y = 2f; + shootY = 0f; + x = 0f; + reload = 140f; + mirror = false; + continuous = true; + // minWarmup = 0.5f; + + bullet = new ContinuousLaserBulletType(140){{ + shake = 0f; + lifetime = 120f; + colors = new Color[]{Color.valueOf("bf92f9").a(0.4f), Color.valueOf("bf92f9"), Color.white}; + //TODO merge + chargeEffect = new MultiEffect(Fx.lancerLaserCharge, Fx.lancerLaserChargeBegin); + width = 20f; + largeHit = false; + + buildingDamageMultiplier = 0.25f; + hitEffect = Fx.hitLancer; + hitSize = 4; + drawSize = 400f; + length = 173f; + ammoMultiplier = 1f; + pierceCap = 4; + hitColor = colors[1]; + }}; + }}); }}; quell = new ErekirUnitType("quell"){{ diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index e3da3e2d2e..5f167a94cd 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -30,7 +30,6 @@ public class Damage{ private static Tile furthest; private static float maxDst = 0f; - private static int pierceCount = 0; private static Building tmpBuilding; private static Unit tmpUnit; @@ -149,7 +148,6 @@ public class Damage{ vec.trnsExact(b.rotation(), length); rect.setPosition(b.x, b.y).setSize(vec.x, vec.y).normalize().grow(3f); - pierceCount = 0; maxDst = Float.POSITIVE_INFINITY; distances.clear(); @@ -219,7 +217,6 @@ public class Damage{ * Only enemies of the specified team are damaged. */ public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large, boolean laser, int pierceCap){ - pierceCount = 0; if(laser){ length = findLaserLength(hitter, length); }else if(pierceCap > 0){ @@ -284,8 +281,6 @@ public class Damage{ effect.at(vec.x, vec.y); e.collision(hitter, vec.x, vec.y); hitter.collision(e, vec.x, vec.y); - - pierceCount ++; } }; diff --git a/core/src/mindustry/entities/bullet/ContinuousFlameBulletType.java b/core/src/mindustry/entities/bullet/ContinuousFlameBulletType.java index 8f71956134..470b200323 100644 --- a/core/src/mindustry/entities/bullet/ContinuousFlameBulletType.java +++ b/core/src/mindustry/entities/bullet/ContinuousFlameBulletType.java @@ -23,12 +23,12 @@ public class ContinuousFlameBulletType extends ContinuousBulletType{ public Interp lengthInterp = Interp.slope; /** Lengths, widths, ellipse panning, and offsets, all as fractions of the base width and length. Stored as an 'interleaved' array of values: LWPO1 LWPO2 LWPO3... */ - public float[] lengthWidthPanOffsets = { - 1.12f, 1.3f, 0.32f, 0f, - 1f, 1f, 0.3f, 0f, - 0.8f, 0.9f, 0.2f, 0.01f, - 0.5f, 0.8f, 0.15f, 0.02f, - 0.25f, 0.7f, 0.1f, 0.03f + public float[] lengthWidthPans = { + 1.12f, 1.3f, 0.32f, + 1f, 1f, 0.3f, + 0.8f, 0.9f, 0.2f, + 0.5f, 0.8f, 0.15f, + 0.25f, 0.7f, 0.1f, }; public Color[] colors = {Color.valueOf("eb7abe").a(0.55f), Color.valueOf("e189f5").a(0.7f), Color.valueOf("907ef7").a(0.8f), Color.valueOf("91a4ff"), Color.white.cpy()}; @@ -64,10 +64,9 @@ public class ContinuousFlameBulletType extends ContinuousBulletType{ for(int i = 0; i < colors.length; i++){ Draw.color(colors[i].write(Tmp.c1).mul(0.9f).mul(1f + Mathf.absin(Time.time, 1f, 0.1f))); Drawf.flame(b.x, b.y, divisions, b.rotation(), - realLength * lengthWidthPanOffsets[i * 4] * (1f - sin), - width * lengthWidthPanOffsets[i * 4 + 1] * mult * (1f + sin), - lengthWidthPanOffsets[i * 4 + 2], - realLength * lengthWidthPanOffsets[i * 4 + 3] + realLength * lengthWidthPans[i * 3] * (1f - sin), + width * lengthWidthPans[i * 3 + 1] * mult * (1f + sin), + lengthWidthPans[i * 3 + 2] ); } diff --git a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java index 9809b43255..d6267cec6e 100644 --- a/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java +++ b/core/src/mindustry/entities/bullet/ContinuousLaserBulletType.java @@ -12,11 +12,11 @@ import mindustry.graphics.*; public class ContinuousLaserBulletType extends ContinuousBulletType{ public float fadeTime = 16f; public float lightStroke = 40f; - public float spaceMag = 35f; + public int divisions = 11; public Color[] colors = {Color.valueOf("ec745855"), Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.white}; - public float[] tscales = {1f, 0.7f, 0.5f, 0.2f}; - public float[] strokes = {2f, 1.5f, 1f, 0.3f}; - public float[] lenscales = {1f, 1.12f, 1.15f, 1.17f}; + public float[] strokes = {2f, 1.5f, 1f, 0.5f}; + + public float backLength = 7f, frontLength = 35f; public float width = 9f, oscScl = 0.8f, oscMag = 1.5f; public ContinuousLaserBulletType(float damage){ @@ -45,15 +45,23 @@ public class ContinuousLaserBulletType extends ContinuousBulletType{ float realLength = Damage.findLaserLength(b, length); float fout = Mathf.clamp(b.time > b.lifetime - fadeTime ? 1f - (b.time - (lifetime - fadeTime)) / fadeTime : 1f); float baseLen = realLength * fout; + float rot = b.rotation(); - Lines.lineAngle(b.x, b.y, b.rotation(), baseLen); - for(int s = 0; s < colors.length; s++){ - Draw.color(Tmp.c1.set(colors[s]).mul(1f + Mathf.absin(Time.time, 1f, 0.1f))); - for(int i = 0; i < tscales.length; i++){ - Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * spaceMag); - Lines.stroke((width + Mathf.absin(Time.time, oscScl, oscMag)) * fout * strokes[s] * tscales[i]); - Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], false); - } + for(int i = 0; i < colors.length; i++){ + Draw.color(Tmp.c1.set(colors[i]).mul(1f + Mathf.absin(Time.time, 1f, 0.1f))); + + float stroke = (width + Mathf.absin(Time.time, oscScl, oscMag)) * fout * strokes[i]; + float ellipseLenScl = Mathf.lerp(strokes[i] / 2f, 1f, 0.75f); + Lines.stroke(stroke); + + Lines.lineAngle(b.x, b.y, rot, length - frontLength, false); + + //back ellipse + Drawf.flameFront(b.x, b.y, divisions, rot + 180f, backLength, stroke / 2f); + + //front ellipse + Tmp.v1.trnsExact(rot, length - frontLength); + Drawf.flameFront(b.x + Tmp.v1.x, b.y + Tmp.v1.y, divisions, rot, frontLength * ellipseLenScl, stroke / 2f); } Tmp.v1.trns(b.rotation(), baseLen * 1.1f); diff --git a/core/src/mindustry/entities/bullet/LaserBulletType.java b/core/src/mindustry/entities/bullet/LaserBulletType.java index 21ba483743..22c11e10f8 100644 --- a/core/src/mindustry/entities/bullet/LaserBulletType.java +++ b/core/src/mindustry/entities/bullet/LaserBulletType.java @@ -104,7 +104,7 @@ public class LaserBulletType extends BulletType{ Lines.stroke((cwidth *= lengthFalloff) * b.fout()); Lines.lineAngle(b.x, b.y, b.rotation(), baseLen, false); Tmp.v1.trns(b.rotation(), baseLen); - Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke() * 1.22f, cwidth * 2f + width / 2f, b.rotation()); + Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, Lines.getStroke(), cwidth * 2f + width / 2f, b.rotation()); Fill.circle(b.x, b.y, 1f * cwidth * b.fout()); for(int i : Mathf.signs){ diff --git a/core/src/mindustry/graphics/Drawf.java b/core/src/mindustry/graphics/Drawf.java index 8d52f5403f..bf7a8208fe 100644 --- a/core/src/mindustry/graphics/Drawf.java +++ b/core/src/mindustry/graphics/Drawf.java @@ -18,12 +18,8 @@ public class Drawf{ private static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; private static final FloatSeq points = new FloatSeq(); - public static void flame(float x, float y, int divisions, float rotation, float length, float width, float pan){ - flame(x, y, divisions, rotation, length, width, pan, 0f); - } - //TODO offset unused - public static void flame(float x, float y, int divisions, float rotation, float length, float width, float pan, float offset){ + public static void flame(float x, float y, int divisions, float rotation, float length, float width, float pan){ float len1 = length * pan, len2 = length * (1f - pan); points.clear(); @@ -57,6 +53,27 @@ public class Drawf{ Fill.poly(points); } + public static void flameFront(float x, float y, int divisions, float rotation, float length, float width){ + divisions = Mathf.round(divisions, 2) + 1; + + points.clear(); + + //right side; half arc beginning at -90 (270) and ending at 90 + for(int i = 0; i <= divisions; i++){ + float rot = -90f + 180f * i / (float)divisions; + Tmp.v1.trnsExact(rot, width); + + point( + (Tmp.v1.x) / width * length, //convert to 0..1, then multiply by desired length and offset relative to previous segment + Tmp.v1.y, //Y axis remains unchanged + x, y, + rotation + ); + } + + Fill.poly(points); + } + private static void point(float x, float y, float baseX, float baseY, float rotation){ //TODO test exact and non-exact Tmp.v1.set(x, y).rotateRadExact(rotation * Mathf.degRad);