Unit wreck visuals

This commit is contained in:
Anuken
2020-07-08 23:48:12 -04:00
parent b0f69263c7
commit 29e9d064df
17 changed files with 2982 additions and 2035 deletions

View File

@@ -183,6 +183,27 @@ public class Fx{
Fill.circle(e.x, e.y, (7f - e.fin() * 7f)/2f);
}),
fallSmoke = new Effect(110, e -> {
color(Color.gray, Color.darkGray, e.rotation);
Fill.circle(e.x, e.y, e.fout() * 3.5f);
}),
unitWreck = new Effect(200f, e -> {
if(!(e.data instanceof TextureRegion)) return;
Draw.mixcol(Pal.rubble, 1f);
TextureRegion reg = e.data();
float vel = e.fin(Interp.pow5Out) * 2f * Mathf.randomSeed(e.id, 1f);
float totalRot = Mathf.randomSeed(e.id + 1, 10f);
Tmp.v1.trns(Mathf.randomSeed(e.id + 2, 360f), vel);
Draw.z(Mathf.lerp(Layer.flyingUnitLow, Layer.debris, e.fin()));
Draw.alpha(e.fout(Interp.pow5Out));
Draw.rect(reg, e.x + Tmp.v1.x, e.y + Tmp.v1.y, e.rotation - 90 + totalRot * e.fin(Interp.pow5Out));
}),
rocketSmoke = new Effect(120, e -> {
color(Color.gray);
alpha(Mathf.clamp(e.fout()*1.6f - Interp.pow3In.apply(e.rotation)*1.2f));

View File

@@ -377,6 +377,7 @@ public class UnitTypes implements ContentList{
engineOffset = 38;
engineSize = 7.3f;
hitsize = 58f;
destructibleWreck = false;
weapons.add(new Weapon(){{
y = 1.5f;

View File

@@ -55,6 +55,10 @@ public class Effects{
}
}
public static void decal(TextureRegion region, float x, float y, float rotation){
decal(region, x, y, rotation, 3600f, Pal.rubble);
}
public static void decal(TextureRegion region, float x, float y, float rotation, float lifetime, Color color){
if(headless || region == null || !Core.atlas.isFound(region)) return;

View File

@@ -11,7 +11,7 @@ import static mindustry.Vars.*;
/** Utility class for unit and team interactions.*/
public class Units{
private static Rect hitrect = new Rect();
private static final Rect hitrect = new Rect();
private static Unit result;
private static float cdist;
private static boolean boolResult;

View File

@@ -19,10 +19,10 @@ abstract class DecalComp implements Drawc, Timedc, Rotc, Posc{
public void draw(){
Draw.z(Layer.scorch);
Draw.color(color);
Draw.mixcol(color, 1f);
Draw.alpha(1f - Mathf.curve(fin(), 0.98f));
Draw.rect(region, x, y, rotation);
Draw.color();
Draw.reset();
}
@Replace

View File

@@ -164,7 +164,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
public void update(){
type.update(base());
drag(type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f));
drag = type.drag * (isGrounded() ? (floorOn().dragMultiplier) : 1f);
//apply knockback based on spawns
if(team != state.rules.waveTeam){
@@ -176,6 +176,36 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
}
}
//simulate falling down
if(dead){
//less drag when dead
drag = 0.01f;
//standard fall smoke
if(Mathf.chanceDelta(0.1)){
Tmp.v1.setToRandomDirection().scl(hitSize);
type.fallEffect.at(x + Tmp.v1.x, y + Tmp.v1.y);
}
//thruster fall trail
if(Mathf.chanceDelta(0.2)){
float offset = type.engineOffset/2f + type.engineOffset/2f*elevation;
float range = Mathf.range(type.engineSize);
type.fallThrusterEffect.at(
x + Angles.trnsx(rotation + 180, offset) + Mathf.range(range),
y + Angles.trnsy(rotation + 180, offset) + Mathf.range(range),
Mathf.random()
);
}
//move down
elevation -= type.fallSpeed * Time.delta();
if(isGrounded()){
destroy();
}
}
Tile tile = tileOn();
Floor floor = floorOn();
@@ -197,7 +227,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
}
//AI only updates on the server
if(!net.client()){
if(!net.client() && !dead){
controller.updateUnit();
}
@@ -208,6 +238,43 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
}
}
/** Actually destroys the unit, removing it and creating explosions. **/
public void destroy(){
float explosiveness = 2f + item().explosiveness * stack().amount;
float flammability = item().flammability * stack().amount;
Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, Pal.darkFlame);
float shake = hitSize / 3f;
Effects.scorch(x, y, (int)(hitSize / 5));
Fx.explosion.at(this);
Effects.shake(shake, shake, this);
type.deathSound.at(this);
Events.fire(new UnitDestroyEvent(base()));
if(explosiveness > 7f && isLocal()){
Events.fire(Trigger.suicideBomb);
}
//if this unit crash landed (was flying), damage stuff in a radius
if(type.flying){
Damage.damage(team,x, y, hitSize * 1.1f, hitSize * type.crashDamageMultiplier, true, false, true);
}
if(!headless){
for(int i = 0; i < type.wreckRegions.length; i++){
if(type.wreckRegions[i].found()){
float range = type.hitsize/4f;
Tmp.v1.rnd(range);
Effects.decal(type.wreckRegions[i], x + Tmp.v1.x, y + Tmp.v1.y, rotation - 90);
}
}
}
remove();
}
@Override
public void display(Table table){
type.display(base(), table);
@@ -238,22 +305,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
health = 0;
dead = true;
float explosiveness = 2f + item().explosiveness * stack().amount;
float flammability = item().flammability * stack().amount;
Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, Pal.darkFlame);
Effects.scorch(x, y, (int)(hitSize / 5));
Fx.explosion.at(this);
Effects.shake(2f, 2f, this);
type.deathSound.at(this);
Events.fire(new UnitDestroyEvent(base()));
if(explosiveness > 7f && isLocal()){
Events.fire(Trigger.suicideBomb);
//don't waste time when the unit is already on the ground, just destroy it
if(isGrounded()){
destroy();
}
remove();
}
@Override

View File

@@ -35,15 +35,21 @@ public class UnitType extends UnlockableContent{
public @NonNull Prov<? extends Unit> constructor;
public @NonNull Prov<? extends UnitController> defaultController = () -> !flying ? new GroundAI() : new FlyingAI();
public float speed = 1.1f, boostMultiplier = 1f, rotateSpeed = 5f, baseRotateSpeed = 5f;
public float drag = 0.3f, accel = 0.5f, landShake = 0f, rippleScale = 1f;
public float drag = 0.3f, accel = 0.5f, landShake = 0f, rippleScale = 1f, fallSpeed = 0.018f;
public float health = 200f, range = -1, armor = 0f;
public float crashDamageMultiplier = 4f;
public boolean targetAir = true, targetGround = true;
public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false;
public boolean canBoost = false;
public boolean destructibleWreck = true;
public float wreckHealth = 15f;
public float sway = 1f;
public int payloadCapacity = 1;
public int commandLimit = 24;
public float baseElevation = 0f;
public float deathShake = 2f;
public Effect fallEffect = Fx.fallSmoke;
public Effect fallThrusterEffect = Fx.fallSmoke;
//TODO document
public int legCount = 4, legGroupSize = 2;
@@ -72,8 +78,7 @@ public class UnitType extends UnlockableContent{
public Seq<Weapon> weapons = new Seq<>();
public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion,
occlusionRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion;
public TextureRegion[] partRegions;
public TextureRegion[] partCellRegions;
public TextureRegion[] partRegions, partCellRegions, wreckRegions;
public UnitType(String name){
super(name);
@@ -186,6 +191,11 @@ public class UnitType extends UnlockableContent{
partRegions[i] = Core.atlas.find(name + "-part" + i);
partCellRegions[i] = Core.atlas.find(name + "-cell" + i);
}
wreckRegions = new TextureRegion[3];
for(int i = 0; i < wreckRegions.length; i++){
wreckRegions[i] = Core.atlas.find(name + "-wreck" + i);
}
}
@Override