From 53b55a9f0e795d04ac1c5a4c990b0e18506164fb Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 12 Dec 2021 20:05:37 -0500 Subject: [PATCH] Tank animations & FX --- .../annotations/entity/EntityProcess.java | 10 ++--- .../sprites/units/vanquish-treads.png | Bin 555 -> 555 bytes core/assets-raw/sprites/units/vanquish.png | Bin 4452 -> 4432 bytes core/src/mindustry/content/Fx.java | 12 +++++- core/src/mindustry/content/UnitTypes.java | 4 ++ core/src/mindustry/entities/Effect.java | 16 ++++++++ .../mindustry/entities/EntityCollisions.java | 2 +- .../src/mindustry/entities/comp/MechComp.java | 9 +---- .../src/mindustry/entities/comp/TankComp.java | 26 +++++++++++- core/src/mindustry/type/UnitType.java | 37 +++++++++++++++++- tools/src/mindustry/tools/Generators.java | 22 +++++++++++ 11 files changed, 119 insertions(+), 19 deletions(-) diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java index 3f8d56c249..a9ada9f45c 100644 --- a/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java +++ b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java @@ -800,12 +800,12 @@ public class EntityProcess extends BaseProcessor{ } } - write(def.builder, imports.asArray()); + write(def.builder, imports.toSeq()); } //write base classes last for(TypeSpec.Builder b : baseClasses){ - write(b, imports.asArray()); + write(b, imports.toSeq()); } //TODO nulls were an awful idea @@ -878,7 +878,7 @@ public class EntityProcess extends BaseProcessor{ nullsBuilder.addField(FieldSpec.builder(type, Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build()); - write(nullBuilder, imports.asArray()); + write(nullBuilder, imports.toSeq()); } write(nullsBuilder); @@ -934,7 +934,7 @@ public class EntityProcess extends BaseProcessor{ out.addAll(getDependencies(comp)); } - defComponents.put(type, out.asArray()); + defComponents.put(type, out.toSeq()); } return defComponents.get(type); @@ -961,7 +961,7 @@ public class EntityProcess extends BaseProcessor{ //remove it again just in case out.remove(component); - componentDependencies.put(component, result.asArray()); + componentDependencies.put(component, result.toSeq()); } return componentDependencies.get(component); diff --git a/core/assets-raw/sprites/units/vanquish-treads.png b/core/assets-raw/sprites/units/vanquish-treads.png index dea46d155ed91bb3a1ddf56286930edca0a11f63..a8cbe1e0cd4a5726fef8e21aa358c0b2c637887d 100644 GIT binary patch delta 95 zcmZ3@vYKVW6yqaj1NrCM-|MUT6@SynUAnjBf(HjGA@l9vw{P$Mtyr#aRljff{_vZV na~Ky-wq;x@!^^v_9zsW6Plh&h)n?PJoS3j3^P6P1 delta 106 zcmZ3@vYKVW6swjC9vrVNS%RA4zYbL0nH)KbLh*2~7Yo`Y`4I diff --git a/core/assets-raw/sprites/units/vanquish.png b/core/assets-raw/sprites/units/vanquish.png index 118b862018f3d8d833db9453a0b762ee0d2b17c8..a1b5c2d58b111067dae55ec5b9645141c281b67a 100644 GIT binary patch literal 4432 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çk z8GRSx(*mA$k>34T7mdi`H_xIbi zjQafYhsEAEf}Y>Hf4jAO|K6io&C%lg_Ejr{FC5|up88x)e3i(8par@K+H)7DG_!2F zvVZIG%2O;RogeQ=mc2{Ye9AO6d)K4uJl770{Wts0b$E`h)CnEC$x{{wex2JGu(UH; zd+|=;BM#%+O>BT+lBgn{~iTOnoh_J5niA6-75IiCjJRRY<|p=4QFQF(&^at zb?xJPS?|wwQTG!jJ1xs}+j%zC?-ut#Z#l!5nJ;^%EP2nv-mrN3ZTI=9=O_QtEA5+P zvQ2ODnfXnRyl!3b`0f3>diUbu=lYIWQqGId_P*5EcCg6m$%Siyul|Os?p8S-o%>op zRDD5io{#(UbMa9><}@jZW_YdqeEro0wm;i{{#wEIvKK-aKd9t9FCg(=R5@6m#9B&9FGaJm0>EjrrYW zY18n-$LH6q`ulQ$oaf<&RWEaq?ctp9&`d*s`F zHu^%l;|(%Kans7feT<}}E;auy z_2!j4V0hd5tLm{!r>5&oJ(((VzVn!z!#kz(yQ+?7VjX%g`pa+nFWWuva-c5*0|SGn LtDnm{r-UW|Xqbkq literal 4452 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 diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index 9496ccab85..ae84c353ee 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -21,8 +21,8 @@ import static arc.math.Angles.*; import static mindustry.Vars.*; public class Fx{ - private static final Rand rand = new Rand(); - private static final Vec2 v = new Vec2(); + public static final Rand rand = new Rand(); + public static final Vec2 v = new Vec2(); public static final Effect @@ -310,11 +310,19 @@ public class Fx{ unitLand = new Effect(30, e -> { color(Tmp.c1.set(e.color).mul(1.1f)); + //TODO doesn't respect rotation / size randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> { Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f); }); }).layer(Layer.debris), + unitDust = new Effect(30, e -> { + color(Tmp.c1.set(e.color).mul(1.3f)); + randLenVectors(e.id, 3, 8f * e.finpow(), e.rotation, 30f, (x, y) -> { + Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.3f); + }); + }).layer(Layer.debris), + unitLandSmall = new Effect(30, e -> { color(Tmp.c1.set(e.color).mul(1.1f)); randLenVectors(e.id, (int)(6 * e.rotation), 12f * e.finpow() * e.rotation, (x, y) -> { diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index ebdd90c805..9c961396bc 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2429,6 +2429,10 @@ public class UnitTypes{ vanquish = new TankUnitType("vanquish"){{ hitSize = 28f; + speed = 0.6f; + health = 10000; + armor = 20f; + treadRect = new Rect(22f, 16f, 28f, 130f); }}; //endregion diff --git a/core/src/mindustry/entities/Effect.java b/core/src/mindustry/entities/Effect.java index aa32ed60db..6b164a3f98 100644 --- a/core/src/mindustry/entities/Effect.java +++ b/core/src/mindustry/entities/Effect.java @@ -166,6 +166,22 @@ public class Effect{ shake(intensity, duration, loc.getX(), loc.getY()); } + public static void floorDust(float x, float y, float size){ + Tile tile = world.tileWorld(x, y); + if(tile != null){ + Color color = tile.floor().mapColor; + Fx.unitLand.at(x, y, size, color); + } + } + + public static void floorDustAngle(Effect effect, float x, float y, float angle){ + Tile tile = world.tileWorld(x, y); + if(tile != null){ + Color color = tile.floor().mapColor; + effect.at(x, y, angle, color); + } + } + public static void create(Effect effect, float x, float y, float rotation, Color color, Object data){ if(headless || effect == Fx.none || !Core.settings.getBool("effects")) return; diff --git a/core/src/mindustry/entities/EntityCollisions.java b/core/src/mindustry/entities/EntityCollisions.java index 1a94f29fd6..f29a2c67f3 100644 --- a/core/src/mindustry/entities/EntityCollisions.java +++ b/core/src/mindustry/entities/EntityCollisions.java @@ -119,7 +119,7 @@ public class EntityCollisions{ @SuppressWarnings("unchecked") public void updatePhysics(EntityGroup group){ - QuadTree tree = group.tree(); + var tree = group.tree(); tree.clear(); group.each(s -> { diff --git a/core/src/mindustry/entities/comp/MechComp.java b/core/src/mindustry/entities/comp/MechComp.java index 18ffc784a7..ff4970e108 100644 --- a/core/src/mindustry/entities/comp/MechComp.java +++ b/core/src/mindustry/entities/comp/MechComp.java @@ -1,15 +1,12 @@ package mindustry.entities.comp; -import arc.graphics.*; import arc.math.*; import arc.math.geom.*; import arc.util.*; import mindustry.annotations.Annotations.*; -import mindustry.content.*; import mindustry.entities.*; import mindustry.gen.*; import mindustry.type.*; -import mindustry.world.*; import mindustry.world.blocks.environment.*; import static mindustry.Vars.*; @@ -52,11 +49,7 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati } if(type.mechStepParticles){ - Tile tile = world.tileWorld(cx, cy); - if(tile != null){ - Color color = tile.floor().mapColor; - Fx.unitLand.at(cx, cy, hitSize/8f, color); - } + Effect.floorDust(cx, cy, hitSize/8f); } } diff --git a/core/src/mindustry/entities/comp/TankComp.java b/core/src/mindustry/entities/comp/TankComp.java index f721b13bb3..320ddcf555 100644 --- a/core/src/mindustry/entities/comp/TankComp.java +++ b/core/src/mindustry/entities/comp/TankComp.java @@ -1,8 +1,10 @@ package mindustry.entities.comp; +import arc.math.*; import arc.math.geom.*; import arc.util.*; import mindustry.annotations.Annotations.*; +import mindustry.entities.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.blocks.environment.*; @@ -11,14 +13,36 @@ import static mindustry.Vars.*; @Component abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{ - @Import float x, y, hitSize; + @Import float x, y, hitSize, rotation; @Import UnitType type; + transient private float treadEffectTime; + transient float treadTime; transient boolean walked; @Override public void update(){ + //dust + if(walked && !headless){ + treadEffectTime += Time.delta; + if(treadEffectTime >= 6f){ + var treadRegion = type.treadRegion; + var treadRect = type.treadRect; + + float xOffset = (treadRegion.width/2f - (treadRect.x + treadRect.width/2f)) / 4f; + float yOffset = (treadRegion.height/2f - (treadRect.y + treadRect.height/2f)) / 4f; + + for(int i : Mathf.signs){ + Tmp.v1.set(xOffset * i, yOffset - treadRect.height / 2f / 4f).rotate(rotation - 90); + + Effect.floorDustAngle(type.treadEffect, Tmp.v1.x + x, Tmp.v1.y + y, rotation + 180f); + } + + treadEffectTime = 0f; + } + } + //trigger animation only when walking manually if(walked || net.client()){ float len = deltaLen(); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index b0dc05cc95..6e2a00ad57 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -34,6 +34,7 @@ import mindustry.world.blocks.units.*; import mindustry.world.consumers.*; import mindustry.world.meta.*; +import static arc.graphics.g2d.Draw.*; import static mindustry.Vars.*; //TODO document @@ -92,6 +93,7 @@ public class UnitType extends UnlockableContent{ public Effect fallEffect = Fx.fallSmoke; public Effect fallThrusterEffect = Fx.fallSmoke; public Effect deathExplosionEffect = Fx.dynamicExplosion; + public @Nullable Effect treadEffect; /** Additional sprites that are drawn with the unit. */ public Seq decals = new Seq<>(); public Seq abilities = new Seq<>(); @@ -117,6 +119,9 @@ public class UnitType extends UnlockableContent{ public boolean mechStepParticles = false; public Color mechLegColor = Pal.darkMetal; + public Rect treadRect = new Rect(); + public int treadFrames = 18; + public int itemCapacity = -1; public int ammoCapacity = -1; public AmmoType ammoType = new ItemAmmoType(Items.copper); @@ -166,8 +171,7 @@ public class UnitType extends UnlockableContent{ public Seq weapons = new Seq<>(); public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion, softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion; - public TextureRegion[] wreckRegions; - public TextureRegion[] segmentRegions, segmentOutlineRegions; + public TextureRegion[] wreckRegions, segmentRegions, segmentOutlineRegions, treadRegions; protected float buildTime = -1f; protected @Nullable ItemStack[] totalRequirements, cachedRequirements, firstRequirements; @@ -437,6 +441,17 @@ public class UnitType extends UnlockableContent{ mechStepParticles = hitSize > 15f; } + if(treadEffect == null){ + treadEffect = new Effect(45, e -> { + color(Tmp.c1.set(e.color).mul(1.5f)); + Fx.rand.setSeed(e.id); + for(int i = 0; i < 3; i++){ + Fx.v.trns(e.rotation + Fx.rand.range(40f), Fx.rand.random(6f * e.finpow())); + Fill.circle(e.x + Fx.v.x + Fx.rand.range(3f), e.y + Fx.v.y + Fx.rand.range(3f), e.fout() * hitSize / 28f * 3f * Fx.rand.random(0.8f, 1.1f) + 0.3f); + } + }).layer(Layer.debris); + } + canHeal = weapons.contains(w -> w.bullet.healPercent > 0f); //add mirrored weapon variants @@ -498,6 +513,12 @@ public class UnitType extends UnlockableContent{ baseJointRegion = Core.atlas.find(name + "-joint-base"); footRegion = Core.atlas.find(name + "-foot"); treadRegion = Core.atlas.find(name + "-treads"); + if(treadRegion.found()){ + treadRegions = new TextureRegion[treadFrames]; + for(int i = 0; i < treadFrames; i++){ + treadRegions[i] = Core.atlas.find(name + "-treads" + i); + } + } legBaseRegion = Core.atlas.find(name + "-leg-base", name + "-leg"); baseRegion = Core.atlas.find(name + "-base"); cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell")); @@ -963,6 +984,18 @@ public class UnitType extends UnlockableContent{ public void drawTank(T unit){ Draw.rect(treadRegion, unit.x, unit.y, unit.rotation - 90); + + if(treadRegion.found()){ + int frame = (int)(unit.treadTime()) % treadFrames; + var region = treadRegions[frame]; + float xOffset = treadRegion.width/2f - (treadRect.x + treadRect.width/2f); + float yOffset = treadRegion.height/2f - (treadRect.y + treadRect.height/2f); + + for(int i : Mathf.signs){ + Tmp.v1.set(xOffset * i, yOffset).rotate(unit.rotation - 90); + Draw.rect(region, unit.x + Tmp.v1.x / 4f, unit.y + Tmp.v1.y / 4f, treadRect.width / 4f, region.height / 4f, unit.rotation - 90); + } + } } public void drawLegs(T unit){ diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 4ffc842f12..6eededbe91 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -509,6 +509,28 @@ public class Generators{ } } + //generate tank animation + if(sample instanceof Tankc){ + Pixmap pix = get(type.treadRegion); + //slice is always 1 pixel wide + Pixmap slice = pix.crop((int)type.treadRect.x, (int)type.treadRect.y, 1, (int)type.treadRect.height); + int frames = type.treadFrames; + for(int i = 0; i < frames; i++){ + int pullOffset = 4; + Pixmap frame = new Pixmap(slice.width, slice.height); + for(int y = 0; y < slice.height; y++){ + int idx = y + i; + if(idx >= slice.height){ + idx -= slice.height; + idx += pullOffset; + } + + frame.setRaw(0, y, slice.getRaw(0, idx)); + } + save(frame, type.name + "-treads" + i); + } + } + outliner.get(type.jointRegion); outliner.get(type.footRegion); outliner.get(type.legBaseRegion);