Tank animations & FX

This commit is contained in:
Anuken 2021-12-12 20:05:37 -05:00
parent 0d33768f58
commit 53b55a9f0e
11 changed files with 119 additions and 19 deletions

View File

@ -800,12 +800,12 @@ public class EntityProcess extends BaseProcessor{
} }
} }
write(def.builder, imports.asArray()); write(def.builder, imports.toSeq());
} }
//write base classes last //write base classes last
for(TypeSpec.Builder b : baseClasses){ for(TypeSpec.Builder b : baseClasses){
write(b, imports.asArray()); write(b, imports.toSeq());
} }
//TODO nulls were an awful idea //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()); 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); write(nullsBuilder);
@ -934,7 +934,7 @@ public class EntityProcess extends BaseProcessor{
out.addAll(getDependencies(comp)); out.addAll(getDependencies(comp));
} }
defComponents.put(type, out.asArray()); defComponents.put(type, out.toSeq());
} }
return defComponents.get(type); return defComponents.get(type);
@ -961,7 +961,7 @@ public class EntityProcess extends BaseProcessor{
//remove it again just in case //remove it again just in case
out.remove(component); out.remove(component);
componentDependencies.put(component, result.asArray()); componentDependencies.put(component, result.toSeq());
} }
return componentDependencies.get(component); return componentDependencies.get(component);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -21,8 +21,8 @@ import static arc.math.Angles.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class Fx{ public class Fx{
private static final Rand rand = new Rand(); public static final Rand rand = new Rand();
private static final Vec2 v = new Vec2(); public static final Vec2 v = new Vec2();
public static final Effect public static final Effect
@ -310,11 +310,19 @@ public class Fx{
unitLand = new Effect(30, e -> { unitLand = new Effect(30, e -> {
color(Tmp.c1.set(e.color).mul(1.1f)); color(Tmp.c1.set(e.color).mul(1.1f));
//TODO doesn't respect rotation / size
randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> { randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f); Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f);
}); });
}).layer(Layer.debris), }).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 -> { unitLandSmall = new Effect(30, e -> {
color(Tmp.c1.set(e.color).mul(1.1f)); color(Tmp.c1.set(e.color).mul(1.1f));
randLenVectors(e.id, (int)(6 * e.rotation), 12f * e.finpow() * e.rotation, (x, y) -> { randLenVectors(e.id, (int)(6 * e.rotation), 12f * e.finpow() * e.rotation, (x, y) -> {

View File

@ -2429,6 +2429,10 @@ public class UnitTypes{
vanquish = new TankUnitType("vanquish"){{ vanquish = new TankUnitType("vanquish"){{
hitSize = 28f; hitSize = 28f;
speed = 0.6f;
health = 10000;
armor = 20f;
treadRect = new Rect(22f, 16f, 28f, 130f);
}}; }};
//endregion //endregion

View File

@ -166,6 +166,22 @@ public class Effect{
shake(intensity, duration, loc.getX(), loc.getY()); 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){ 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; if(headless || effect == Fx.none || !Core.settings.getBool("effects")) return;

View File

@ -119,7 +119,7 @@ public class EntityCollisions{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Hitboxc> void updatePhysics(EntityGroup<T> group){ public <T extends Hitboxc> void updatePhysics(EntityGroup<T> group){
QuadTree tree = group.tree(); var tree = group.tree();
tree.clear(); tree.clear();
group.each(s -> { group.each(s -> {

View File

@ -1,15 +1,12 @@
package mindustry.entities.comp; package mindustry.entities.comp;
import arc.graphics.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*; import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@ -52,11 +49,7 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
} }
if(type.mechStepParticles){ if(type.mechStepParticles){
Tile tile = world.tileWorld(cx, cy); Effect.floorDust(cx, cy, hitSize/8f);
if(tile != null){
Color color = tile.floor().mapColor;
Fx.unitLand.at(cx, cy, hitSize/8f, color);
}
} }
} }

View File

@ -1,8 +1,10 @@
package mindustry.entities.comp; package mindustry.entities.comp;
import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.entities.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.blocks.environment.*; import mindustry.world.blocks.environment.*;
@ -11,14 +13,36 @@ import static mindustry.Vars.*;
@Component @Component
abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{ abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{
@Import float x, y, hitSize; @Import float x, y, hitSize, rotation;
@Import UnitType type; @Import UnitType type;
transient private float treadEffectTime;
transient float treadTime; transient float treadTime;
transient boolean walked; transient boolean walked;
@Override @Override
public void update(){ 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 //trigger animation only when walking manually
if(walked || net.client()){ if(walked || net.client()){
float len = deltaLen(); float len = deltaLen();

View File

@ -34,6 +34,7 @@ import mindustry.world.blocks.units.*;
import mindustry.world.consumers.*; import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static arc.graphics.g2d.Draw.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
//TODO document //TODO document
@ -92,6 +93,7 @@ public class UnitType extends UnlockableContent{
public Effect fallEffect = Fx.fallSmoke; public Effect fallEffect = Fx.fallSmoke;
public Effect fallThrusterEffect = Fx.fallSmoke; public Effect fallThrusterEffect = Fx.fallSmoke;
public Effect deathExplosionEffect = Fx.dynamicExplosion; public Effect deathExplosionEffect = Fx.dynamicExplosion;
public @Nullable Effect treadEffect;
/** Additional sprites that are drawn with the unit. */ /** Additional sprites that are drawn with the unit. */
public Seq<UnitDecal> decals = new Seq<>(); public Seq<UnitDecal> decals = new Seq<>();
public Seq<Ability> abilities = new Seq<>(); public Seq<Ability> abilities = new Seq<>();
@ -117,6 +119,9 @@ public class UnitType extends UnlockableContent{
public boolean mechStepParticles = false; public boolean mechStepParticles = false;
public Color mechLegColor = Pal.darkMetal; public Color mechLegColor = Pal.darkMetal;
public Rect treadRect = new Rect();
public int treadFrames = 18;
public int itemCapacity = -1; public int itemCapacity = -1;
public int ammoCapacity = -1; public int ammoCapacity = -1;
public AmmoType ammoType = new ItemAmmoType(Items.copper); public AmmoType ammoType = new ItemAmmoType(Items.copper);
@ -166,8 +171,7 @@ public class UnitType extends UnlockableContent{
public Seq<Weapon> weapons = new Seq<>(); public Seq<Weapon> weapons = new Seq<>();
public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion, public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion,
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion; softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion;
public TextureRegion[] wreckRegions; public TextureRegion[] wreckRegions, segmentRegions, segmentOutlineRegions, treadRegions;
public TextureRegion[] segmentRegions, segmentOutlineRegions;
protected float buildTime = -1f; protected float buildTime = -1f;
protected @Nullable ItemStack[] totalRequirements, cachedRequirements, firstRequirements; protected @Nullable ItemStack[] totalRequirements, cachedRequirements, firstRequirements;
@ -437,6 +441,17 @@ public class UnitType extends UnlockableContent{
mechStepParticles = hitSize > 15f; 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); canHeal = weapons.contains(w -> w.bullet.healPercent > 0f);
//add mirrored weapon variants //add mirrored weapon variants
@ -498,6 +513,12 @@ public class UnitType extends UnlockableContent{
baseJointRegion = Core.atlas.find(name + "-joint-base"); baseJointRegion = Core.atlas.find(name + "-joint-base");
footRegion = Core.atlas.find(name + "-foot"); footRegion = Core.atlas.find(name + "-foot");
treadRegion = Core.atlas.find(name + "-treads"); 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"); legBaseRegion = Core.atlas.find(name + "-leg-base", name + "-leg");
baseRegion = Core.atlas.find(name + "-base"); baseRegion = Core.atlas.find(name + "-base");
cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell")); cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell"));
@ -963,6 +984,18 @@ public class UnitType extends UnlockableContent{
public <T extends Unit & Tankc> void drawTank(T unit){ public <T extends Unit & Tankc> void drawTank(T unit){
Draw.rect(treadRegion, unit.x, unit.y, unit.rotation - 90); 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 <T extends Unit & Legsc> void drawLegs(T unit){ public <T extends Unit & Legsc> void drawLegs(T unit){

View File

@ -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.jointRegion);
outliner.get(type.footRegion); outliner.get(type.footRegion);
outliner.get(type.legBaseRegion); outliner.get(type.legBaseRegion);