From ee23886666f9bd21bbc5c269c3a05340808484c4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 28 Apr 2022 10:49:29 -0400 Subject: [PATCH] Better bullet aiming --- .../mindustry/entities/bullet/BulletType.java | 49 ++++++++++++++----- .../mindustry/entities/comp/BulletComp.java | 1 + core/src/mindustry/mod/Mods.java | 5 +- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index d30861886b..dc02bb94a8 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -304,13 +304,7 @@ public class BulletType extends Content implements Cloneable{ Effect.shake(hitShake, hitShake, b); - if(fragBullet != null){ - for(int i = 0; i < fragBullets; i++){ - float len = Mathf.random(1f, 7f); - float a = b.rotation() + Mathf.range(fragCone/2) + fragAngle; - fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax), Mathf.random(fragLifeMin, fragLifeMax)); - } - } + createFrags(b, x, y); if(puddleLiquid != null && puddles > 0){ for(int i = 0; i < puddles; i++){ @@ -328,6 +322,14 @@ public class BulletType extends Content implements Cloneable{ Damage.applySuppression(b.team, b.x, b.y, suppressionRange, suppressionDuration, 0f, suppressionEffectChance, new Vec2(b.x, b.y)); } + createSplashDamage(b, x, y); + + for(int i = 0; i < lightning; i++){ + Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, b.rotation() + Mathf.range(lightningCone/2) + lightningAngle, lightningLength + Mathf.random(lightningLengthRand)); + } + } + + public void createSplashDamage(Bullet b, float x, float y){ if(splashDamageRadius > 0 && !b.absorbed){ Damage.damage(b.team, x, y, splashDamageRadius, splashDamage * b.damageMultiplier(), false, collidesAir, collidesGround, scaledSplashDamage, b); @@ -346,12 +348,19 @@ public class BulletType extends Content implements Cloneable{ indexer.eachBlock(null, x, y, splashDamageRadius, other -> other.team != b.team, other -> Fires.create(other.tile)); } } + } - for(int i = 0; i < lightning; i++){ - Lightning.create(b, lightningColor, lightningDamage < 0 ? damage : lightningDamage, b.x, b.y, b.rotation() + Mathf.range(lightningCone/2) + lightningAngle, lightningLength + Mathf.random(lightningLengthRand)); + public void createFrags(Bullet b, float x, float y){ + if(fragBullet != null){ + for(int i = 0; i < fragBullets; i++){ + float len = Mathf.random(1f, 7f); + float a = b.rotation() + Mathf.range(fragCone / 2) + fragAngle; + fragBullet.create(b, x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a, Mathf.random(fragVelocityMin, fragVelocityMax), Mathf.random(fragLifeMin, fragLifeMax)); + } } } + /** Called when the bullet reaches the end of its lifetime or is destroyed by something external. */ public void despawned(Bullet b){ if(despawnHit){ @@ -408,28 +417,40 @@ public class BulletType extends Content implements Cloneable{ public void update(Bullet b){ updateTrail(b); + updateHoming(b); + updateWeaving(b); + updateTrailEffects(b); + } + public void updateHoming(Bullet b){ if(homingPower > 0.0001f && b.time >= homingDelay){ + float realAimX = b.aimX < 0 ? b.x : b.aimX; + float realAimY = b.aimY < 0 ? b.y : b.aimY; + Teamc target; //home in on allies if possible if(heals()){ - target = Units.closestTarget(null, b.x, b.y, homingRange, - e -> e.checkTarget(collidesAir, collidesGround) && e.team != b.team && !b.hasCollided(e.id), - t -> collidesGround && (t.team != b.team || t.damaged()) && !b.hasCollided(t.id) + target = Units.closestTarget(null, realAimX, realAimY, homingRange, + e -> e.checkTarget(collidesAir, collidesGround) && e.team != b.team && !b.hasCollided(e.id), + t -> collidesGround && (t.team != b.team || t.damaged()) && !b.hasCollided(t.id) ); }else{ - target = Units.closestTarget(b.team, b.x, b.y, homingRange, e -> e.checkTarget(collidesAir, collidesGround) && !b.hasCollided(e.id), t -> collidesGround && !b.hasCollided(t.id)); + target = Units.closestTarget(b.team, realAimX, realAimY, homingRange, e -> e.checkTarget(collidesAir, collidesGround) && !b.hasCollided(e.id), t -> collidesGround && !b.hasCollided(t.id)); } if(target != null){ b.vel.setAngle(Angles.moveToward(b.rotation(), b.angleTo(target), homingPower * Time.delta * 50f)); } } + } + public void updateWeaving(Bullet b){ if(weaveMag != 0){ b.vel.rotateRadExact((float)Math.sin((b.time + Math.PI * weaveScale/2f) / weaveScale) * weaveMag * (weaveRandom ? (Mathf.randomSeed(b.id, 0, 1) == 1 ? -1 : 1) : 1f) * Time.delta * Mathf.degRad); } + } + public void updateTrailEffects(Bullet b){ if(trailChance > 0){ if(Mathf.chanceDelta(trailChance)){ trailEffect.at(b.x, b.y, trailRotation ? b.rotation() : trailParam, trailColor); @@ -562,6 +583,8 @@ public class BulletType extends Content implements Cloneable{ bullet.originX = x; bullet.originY = y; bullet.aimTile = world.tileWorld(aimX, aimY); + bullet.aimX = aimX; + bullet.aimY = aimY; bullet.initVel(angle, speed * velocityScl); if(backMove){ bullet.set(x - bullet.vel.x * Time.delta, y - bullet.vel.y * Time.delta); diff --git a/core/src/mindustry/entities/comp/BulletComp.java b/core/src/mindustry/entities/comp/BulletComp.java index bc0fe962a9..52948d9c70 100644 --- a/core/src/mindustry/entities/comp/BulletComp.java +++ b/core/src/mindustry/entities/comp/BulletComp.java @@ -40,6 +40,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw //setting this variable to true prevents lifetime from decreasing for a frame. transient boolean keepAlive; transient @Nullable Tile aimTile; + transient float aimX, aimY; transient float originX, originY; transient @Nullable Mover mover; transient boolean absorbed, hit; diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index aa0ddf9ead..3af4656afa 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -1136,7 +1136,8 @@ public class Mods implements Loadable{ /** Mod metadata information.*/ public static class ModMeta{ - public String name, displayName, author, description, subtitle, version, main, minGameVersion = "0", repo; + public String name, minGameVersion = "0"; + public @Nullable String displayName, author, description, subtitle, version, main, repo; public Seq dependencies = Seq.with(); /** Hidden mods are only server-side or client-side, and do not support adding new content. */ public boolean hidden; @@ -1166,7 +1167,7 @@ public class Mods implements Loadable{ } @Override - public String toString() { + public String toString(){ return "ModMeta{" + "name='" + name + '\'' + ", author='" + author + '\'' +