From 8234aa1b98da80c43df1072f7f0ab85338adf67e Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 23 Feb 2022 17:02:00 -0500 Subject: [PATCH] Bullet/weapon cleanup --- core/src/mindustry/ai/types/SuicideAI.java | 2 +- core/src/mindustry/content/UnitTypes.java | 134 +++++++++--------- .../mindustry/entities/bullet/BulletType.java | 46 ++++-- .../entities/bullet/ContinuousBulletType.java | 2 +- .../entities/bullet/LaserBulletType.java | 2 +- .../entities/bullet/LightningBulletType.java | 2 +- .../entities/bullet/RailBulletType.java | 2 +- .../entities/bullet/SapBulletType.java | 2 +- .../entities/bullet/ShrapnelBulletType.java | 2 +- core/src/mindustry/type/Weapon.java | 87 +++++------- .../defense/turrets/ContinuousTurret.java | 3 +- .../blocks/defense/turrets/LaserTurret.java | 2 +- .../world/blocks/defense/turrets/Turret.java | 7 +- 13 files changed, 149 insertions(+), 144 deletions(-) diff --git a/core/src/mindustry/ai/types/SuicideAI.java b/core/src/mindustry/ai/types/SuicideAI.java index 4f7f9d3ec9..ed2e4ffded 100644 --- a/core/src/mindustry/ai/types/SuicideAI.java +++ b/core/src/mindustry/ai/types/SuicideAI.java @@ -37,7 +37,7 @@ public class SuicideAI extends GroundAI{ if(!Units.invalidateTarget(target, unit, unit.range()) && unit.hasWeapons()){ rotate = true; - shoot = unit.within(target, unit.type.weapons.first().bullet.range() + + shoot = unit.within(target, unit.type.weapons.first().bullet.range + (target instanceof Building b ? b.block.size * Vars.tilesize / 2f : ((Hitboxc)target).hitSize() / 2f)); //do not move toward walls or transport blocks diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 426f4ba18a..546158308b 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -3019,24 +3019,24 @@ public class UnitTypes{ shake = 1f; speed = 0f; keepVelocity = false; - }}; - unitSpawned = new MissileUnitType("quell-missile"){{ - speed = 3.8f; - maxRange = 6f; - lifetime = 60f * 1.2f; - outlineColor = Pal.darkOutline; - health = 45; + spawnUnit = new MissileUnitType("quell-missile"){{ + speed = 3.8f; + maxRange = 6f; + lifetime = 60f * 1.2f; + outlineColor = Pal.darkOutline; + health = 45; - weapons.add(new Weapon(){{ - shootCone = 360f; - mirror = false; - reload = 1f; - shootOnDeath = true; - bullet = new ExplosionBulletType(100f, 22f){{ - shootEffect = Fx.massiveExplosion; - }}; - }}); + weapons.add(new Weapon(){{ + shootCone = 360f; + mirror = false; + reload = 1f; + shootOnDeath = true; + bullet = new ExplosionBulletType(100f, 22f){{ + shootEffect = Fx.massiveExplosion; + }}; + }}); + }}; }}; }}); @@ -3124,62 +3124,62 @@ public class UnitTypes{ shake = 1f; speed = 0f; keepVelocity = false; - }}; - unitSpawned = new MissileUnitType("disrupt-missile"){{ - speed = 4.5f; - maxRange = 5f; - outlineColor = Pal.darkOutline; - health = 70; - homingDelay = 10f; - lowAltitude = true; - engineSize = 3f; - deathExplosionEffect = Fx.none; + spawnUnit = new MissileUnitType("disrupt-missile"){{ + speed = 4.5f; + maxRange = 5f; + outlineColor = Pal.darkOutline; + health = 70; + homingDelay = 10f; + lowAltitude = true; + engineSize = 3f; + deathExplosionEffect = Fx.none; - parts.add(new ShapePart(){{ - layer = Layer.effect; - circle = true; - y = -0.25f; - radius = 1.5f; - color = Pal.suppress; - colorTo = Color.white; - progress = PartProgress.life.curve(Interp.pow5In); - }}); + parts.add(new ShapePart(){{ + layer = Layer.effect; + circle = true; + y = -0.25f; + radius = 1.5f; + color = Pal.suppress; + colorTo = Color.white; + progress = PartProgress.life.curve(Interp.pow5In); + }}); - parts.add(new RegionPart("-fin"){{ - mirror = true; - progress = PartProgress.life.mul(3f).curve(Interp.pow5In); - moveRot = 32f; - rotation = -6f; - moveY = 1.5f; - x = 3f / 4f; - y = -6f / 4f; - }}); + parts.add(new RegionPart("-fin"){{ + mirror = true; + progress = PartProgress.life.mul(3f).curve(Interp.pow5In); + moveRot = 32f; + rotation = -6f; + moveY = 1.5f; + x = 3f / 4f; + y = -6f / 4f; + }}); - weapons.add(new Weapon(){{ - shootCone = 360f; - mirror = false; - reload = 1f; - shootOnDeath = true; - bullet = new ExplosionBulletType(120f, 25f){{ - suppressionRange = 140f; - shootEffect = new ExplosionEffect(){{ - lifetime = 50f; - waveStroke = 5f; - waveLife = 8f; - waveColor = Color.white; - sparkColor = smokeColor = Pal.suppress; - waveRad = 40f; - smokeSize = 4f; - smokes = 7; - smokeSizeBase = 0f; - sparks = 10; - sparkRad = 40f; - sparkLen = 6f; - sparkStroke = 2f; + weapons.add(new Weapon(){{ + shootCone = 360f; + mirror = false; + reload = 1f; + shootOnDeath = true; + bullet = new ExplosionBulletType(120f, 25f){{ + suppressionRange = 140f; + shootEffect = new ExplosionEffect(){{ + lifetime = 50f; + waveStroke = 5f; + waveLife = 8f; + waveColor = Color.white; + sparkColor = smokeColor = Pal.suppress; + waveRad = 40f; + smokeSize = 4f; + smokes = 7; + smokeSizeBase = 0f; + sparks = 10; + sparkRad = 40f; + sparkLen = 6f; + sparkStroke = 2f; + }}; }}; - }}; - }}); + }}); + }}; }}; }}); diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index 3b48d926c8..fd9ac7d9db 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -9,6 +9,7 @@ import arc.math.geom.*; import arc.struct.*; import arc.util.*; import mindustry.*; +import mindustry.ai.types.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.ctype.*; @@ -122,6 +123,8 @@ public class BulletType extends Content implements Cloneable{ public float rangeOverride = -1f; /** When used in a turret with multiple ammo types, this can be set to a non-zero value to influence range. */ public float rangeChange = 0f; + /** Range initialized in init(). */ + public float range = 0f; /** % of block health healed **/ public float healPercent = 0f; /** flat amount of block health healed */ @@ -148,6 +151,8 @@ public class BulletType extends Content implements Cloneable{ public Effect healEffect = Fx.healBlockFull; /** Bullets spawned when this bullet is created. Rarely necessary, used for visuals. */ public Seq spawnBullets = new Seq<>(); + /** Unit spawned _instead of_ this bullet. Useful for missiles. */ + public @Nullable UnitType spawnUnit; public Color trailColor = Pal.missileYellowBack; public float trailChance = -0.0001f; @@ -228,9 +233,10 @@ public class BulletType extends Content implements Cloneable{ return sum; } - /** Returns maximum distance the bullet this bullet type has can travel. */ - public float range(){ + /** @return maximum distance the bullet this bullet type has can travel. */ + protected float calculateRange(){ if(rangeOverride > 0) return rangeOverride; + if(spawnUnit != null) return spawnUnit.lifetime * spawnUnit.speed; return Math.max(Mathf.zero(drag) ? speed * lifetime : speed * (1f - Mathf.pow(1f - drag, lifetime)) / drag, maxRange); } @@ -471,6 +477,7 @@ public class BulletType extends Content implements Cloneable{ } drawSize = Math.max(drawSize, trailLength * speed * 2f); + range = calculateRange(); } @Override @@ -478,35 +485,54 @@ public class BulletType extends Content implements Cloneable{ return ContentType.bullet; } - public Bullet create(Teamc owner, float x, float y, float angle){ + public @Nullable Bullet create(Teamc owner, float x, float y, float angle){ return create(owner, owner.team(), x, y, angle); } - public Bullet create(Entityc owner, Team team, float x, float y, float angle){ + public @Nullable Bullet create(Entityc owner, Team team, float x, float y, float angle){ return create(owner, team, x, y, angle, 1f); } - public Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl){ + public @Nullable Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl){ return create(owner, team, x, y, angle, -1, velocityScl, 1f, null); } - public Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){ + public @Nullable Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){ return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null); } - public Bullet create(Bullet parent, float x, float y, float angle){ + public @Nullable Bullet create(Bullet parent, float x, float y, float angle){ return create(parent.owner, parent.team, x, y, angle); } - public Bullet create(Bullet parent, float x, float y, float angle, float velocityScl, float lifeScale){ + public @Nullable Bullet create(Bullet parent, float x, float y, float angle, float velocityScl, float lifeScale){ return create(parent.owner, parent.team, x, y, angle, velocityScl, lifeScale); } - public Bullet create(Bullet parent, float x, float y, float angle, float velocityScl){ + public @Nullable Bullet create(Bullet parent, float x, float y, float angle, float velocityScl){ return create(parent.owner(), parent.team, x, y, angle, velocityScl); } - public Bullet create(@Nullable Entityc owner, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl, Object data){ + public @Nullable Bullet create(@Nullable Entityc owner, Team team, float x, float y, float angle, float damage, float velocityScl, float lifetimeScl, Object data){ + if(spawnUnit != null){ + //don't spawn units clientside! + if(!net.client()){ + Unit spawned = spawnUnit.create(team); + spawned.set(x, y); + spawned.rotation = angle; + //immediately spawn at top speed, since it was launched + spawned.vel.trns(angle, spawnUnit.speed); + //assign unit owner + if(spawned.controller() instanceof MissileAI ai && owner instanceof Unit unit){ + ai.shooter = unit; + } + spawned.add(); + } + + //no bullet returned + return null; + } + Bullet bullet = Bullet.create(); bullet.type = this; bullet.owner = owner; diff --git a/core/src/mindustry/entities/bullet/ContinuousBulletType.java b/core/src/mindustry/entities/bullet/ContinuousBulletType.java index 9e00cef2c0..5df4619bbd 100644 --- a/core/src/mindustry/entities/bullet/ContinuousBulletType.java +++ b/core/src/mindustry/entities/bullet/ContinuousBulletType.java @@ -43,7 +43,7 @@ public class ContinuousBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return Math.max(length, maxRange); } diff --git a/core/src/mindustry/entities/bullet/LaserBulletType.java b/core/src/mindustry/entities/bullet/LaserBulletType.java index 0ddb733712..67b5966069 100644 --- a/core/src/mindustry/entities/bullet/LaserBulletType.java +++ b/core/src/mindustry/entities/bullet/LaserBulletType.java @@ -57,7 +57,7 @@ public class LaserBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return Math.max(length, maxRange); } diff --git a/core/src/mindustry/entities/bullet/LightningBulletType.java b/core/src/mindustry/entities/bullet/LightningBulletType.java index 0f97bbf132..bbd73a6d58 100644 --- a/core/src/mindustry/entities/bullet/LightningBulletType.java +++ b/core/src/mindustry/entities/bullet/LightningBulletType.java @@ -24,7 +24,7 @@ public class LightningBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return (lightningLength + lightningLengthRand/2f) * 6f; } diff --git a/core/src/mindustry/entities/bullet/RailBulletType.java b/core/src/mindustry/entities/bullet/RailBulletType.java index 07e1e6dddb..13d024e531 100644 --- a/core/src/mindustry/entities/bullet/RailBulletType.java +++ b/core/src/mindustry/entities/bullet/RailBulletType.java @@ -30,7 +30,7 @@ public class RailBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return length; } diff --git a/core/src/mindustry/entities/bullet/SapBulletType.java b/core/src/mindustry/entities/bullet/SapBulletType.java index 8482388071..b0bca23f85 100644 --- a/core/src/mindustry/entities/bullet/SapBulletType.java +++ b/core/src/mindustry/entities/bullet/SapBulletType.java @@ -52,7 +52,7 @@ public class SapBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return Math.max(length, maxRange); } diff --git a/core/src/mindustry/entities/bullet/ShrapnelBulletType.java b/core/src/mindustry/entities/bullet/ShrapnelBulletType.java index 40d9b86bf5..34b42719f7 100644 --- a/core/src/mindustry/entities/bullet/ShrapnelBulletType.java +++ b/core/src/mindustry/entities/bullet/ShrapnelBulletType.java @@ -47,7 +47,7 @@ public class ShrapnelBulletType extends BulletType{ } @Override - public float range(){ + protected float calculateRange(){ return Math.max(length, maxRange); } diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index 00e8e3fee6..829a208c07 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -10,7 +10,6 @@ import arc.math.geom.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; -import mindustry.ai.types.*; import mindustry.audio.*; import mindustry.content.*; import mindustry.entities.*; @@ -28,8 +27,6 @@ public class Weapon implements Cloneable{ public String name; /** bullet shot */ public BulletType bullet = Bullets.standardCopper; - /** unit, to spawn at bullet, e.g. missile. TODO prevent bullet creation */ - public @Nullable UnitType unitSpawned; /** shell ejection effect */ public Effect ejectEffect = Fx.none; /** whether to consume ammo when ammo is enabled in rules */ @@ -238,7 +235,7 @@ public class Weapon implements Cloneable{ } public float range(){ - return unitSpawned != null ? unitSpawned.lifetime * unitSpawned.speed : bullet.range(); + return bullet.range; } public void update(Unit unit, WeaponMount mount){ @@ -278,18 +275,18 @@ public class Weapon implements Cloneable{ //find a new target if(!controllable && autoTarget){ if((mount.retarget -= Time.delta) <= 0f){ - mount.target = findTarget(unit, mountX, mountY, bullet.range(), bullet.collidesAir, bullet.collidesGround); + mount.target = findTarget(unit, mountX, mountY, bullet.range, bullet.collidesAir, bullet.collidesGround); mount.retarget = mount.target == null ? targetInterval : targetSwitchInterval; } - if(mount.target != null && checkTarget(unit, mount.target, mountX, mountY, bullet.range())){ + if(mount.target != null && checkTarget(unit, mount.target, mountX, mountY, bullet.range)){ mount.target = null; } boolean shoot = false; if(mount.target != null){ - shoot = mount.target.within(mountX, mountY, bullet.range() + Math.abs(shootY) + (mount.target instanceof Sized s ? s.hitSize()/2f : 0f)) && can; + shoot = mount.target.within(mountX, mountY, bullet.range + Math.abs(shootY) + (mount.target instanceof Sized s ? s.hitSize()/2f : 0f)) && can; if(predictTarget){ Vec2 to = Predict.intercept(unit, mount.target, bullet.speed); @@ -348,7 +345,7 @@ public class Weapon implements Cloneable{ mount.reload <= 0.0001f && //reload has to be 0 Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, shootCone) //has to be within the cone ){ - shoot(unit, mount, bulletX, bulletY, mount.aimX, mount.aimY, mountX, mountY, shootAngle, Mathf.sign(x)); + shoot(unit, mount, bulletX, bulletY, shootAngle); mount.reload = reload; @@ -371,45 +368,46 @@ public class Weapon implements Cloneable{ return rotate ? unit.rotation + mount.rotation : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY)); } - protected void shoot(Unit unit, WeaponMount mount, float shootX, float shootY, float aimX, float aimY, float mountX, float mountY, float rotation, int side){ + protected void shoot(Unit unit, WeaponMount mount, float shootX, float shootY, float rotation){ boolean delay = firstShotDelay + shotDelay > 0f; - - float lifeScl = bullet.scaleVelocity ? Mathf.clamp(Mathf.dst(shootX, shootY, aimX, aimY) / bullet.range()) : 1f; Unit parent = bullet.keepVelocity || parentizeEffects ? unit : null; - //TODO merge with Turret behavior if possible - - if(delay){ + if(firstShotDelay > 0){ chargeSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); bullet.chargeEffect.at(shootX, shootY, rotation, parent); + } - for(int i = 0; i < shots; i++){ - float angleOffset = i * spacing - (shots - 1) * spacing / 2f; + //shot patterns should be able to customize: + //- the position of a specific bullet index + //- the delay of a specific bullet index - Time.run(i * shotDelay + firstShotDelay, () -> { - //everything needs to be re-calculated again - float - rweaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0), - rmountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y), - rmountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y), - rbulletX = rmountX + Angles.trnsx(rweaponRotation, this.shootX, this.shootY), - rbulletY = rmountY + Angles.trnsy(rweaponRotation, this.shootX, this.shootY), - shootAngle = bulletRotation(unit, mount, rbulletX, rbulletY); - - mount.bullet = bullet(mount, unit, rbulletX, rbulletY, angleOffset + Mathf.range(inaccuracy) + shootAngle, lifeScl, side, rotation, rmountX, rmountY); - }); - } - }else{ - for(int i = 0; i < shots; i++){ - float angleOffset = i * spacing - (shots - 1) * spacing / 2f; - mount.bullet = bullet(mount, unit, shootX, shootY, angleOffset + rotation + Mathf.range(inaccuracy), lifeScl, side, rotation, mountX, mountY); + //TODO merge with Turret behavior if possible + for(int i = 0; i < shots; i++){ + float angleOffset = i * spacing - (shots - 1) * spacing / 2f; + if(delay){ + Time.run(i * shotDelay + firstShotDelay, () -> shoot(unit, mount, angleOffset)); + }else{ + shoot(unit, mount, angleOffset); } } unit.apply(shootStatus, shootStatusDuration); } - protected @Nullable Bullet bullet(WeaponMount mount, Unit unit, float shootX, float shootY, float angle, float lifescl, int side, float mountRotation, float mountX, float mountY){ + protected void shoot(Unit unit, WeaponMount mount, float angleOffset){ + float + weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0), + mountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y), + mountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y), + bulletX = mountX + Angles.trnsx(weaponRotation, this.shootX, this.shootY), + bulletY = mountY + Angles.trnsy(weaponRotation, this.shootX, this.shootY), + shootAngle = bulletRotation(unit, mount, bulletX, bulletY), + lifeScl = bullet.scaleVelocity ? Mathf.clamp(Mathf.dst(shootX, shootY, mount.aimX, mount.aimY) / bullet.range) : 1f; + + mount.bullet = bullet(mount, unit, shootX, shootY, angleOffset + shootAngle + Mathf.range(inaccuracy), lifeScl, shootAngle, mountX, mountY); + } + + protected @Nullable Bullet bullet(WeaponMount mount, Unit unit, float shootX, float shootY, float angle, float lifescl, float mountRotation, float mountX, float mountY){ if(!unit.isAdded()) return null; float @@ -417,30 +415,13 @@ public class Weapon implements Cloneable{ x = shootX + Angles.trnsx(angle, 0, xr), y = shootY + Angles.trnsy(angle, 0, xr); - Bullet result = null; - - if(unitSpawned == null){ - result = bullet.create(unit, unit.team, x, y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl); - }else{ - //don't spawn units clientside! - if(!net.client()){ - Unit spawned = unitSpawned.create(unit.team); - spawned.set(x, y); - spawned.rotation = angle; - //immediately spawn at top speed, since it was launched - spawned.vel.trns(angle, unitSpawned.speed); - if(spawned.controller() instanceof MissileAI ai){ - ai.shooter = unit; - } - spawned.add(); - } - } + Bullet result = bullet.create(unit, unit.team, x, y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl); if(!continuous){ shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax)); } - ejectEffect.at(mountX, mountY, angle * side); + ejectEffect.at(mountX, mountY, angle * Mathf.sign(this.x)); bullet.shootEffect.at(shootX, shootY, angle, bullet.hitColor, unit); bullet.smokeEffect.at(shootX, shootY, angle, bullet.hitColor, unit); diff --git a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java index 8639878484..5cbf080141 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ContinuousTurret.java @@ -2,6 +2,7 @@ package mindustry.world.blocks.defense.turrets; import arc.math.*; import arc.struct.*; +import arc.util.*; import mindustry.content.*; import mindustry.entities.bullet.*; import mindustry.gen.*; @@ -31,7 +32,7 @@ public class ContinuousTurret extends Turret{ } public class ContinuousTurretBuild extends TurretBuild{ - public Bullet bullet; + public @Nullable Bullet bullet; @Override protected void updateCooling(){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java index c60cb6a4d0..81a5981762 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -29,7 +29,7 @@ public class LaserTurret extends PowerTurret{ } public class LaserTurretBuild extends PowerTurretBuild{ - public Bullet bullet; + public @Nullable Bullet bullet; public float bulletLife; @Override diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index d9ac0e5abb..45e464b76f 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -512,7 +512,6 @@ public class Turret extends ReloadTurret{ recoil = recoilAmount; heat = 1f; bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy)); - effects(); charging = false; }); @@ -525,7 +524,6 @@ public class Turret extends ReloadTurret{ bulletOffset.trns(rotation, shootLength, Mathf.range(xRand)); bullet(peekAmmo(), rotation + Mathf.range(inaccuracy + peekAmmo().inaccuracy) + (ii - (int)(shots / 2f)) * spread); - effects(); useAmmo(); recoil = recoilAmount; heat = 1f; @@ -544,7 +542,6 @@ public class Turret extends ReloadTurret{ bulletOffset.trns(rotation - 90, (spread) * i + Mathf.range(xRand), shootLength); bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy)); shotCounter ++; - effects(); } }else{ bulletOffset.trns(rotation, shootLength, Mathf.range(xRand)); @@ -553,7 +550,6 @@ public class Turret extends ReloadTurret{ bullet(type, rotation + Mathf.range(inaccuracy + type.inaccuracy) + (i - (int)(shots / 2f)) * spread); shotCounter ++; } - effects(); } recoil = recoilAmount; @@ -563,9 +559,10 @@ public class Turret extends ReloadTurret{ } protected void bullet(BulletType type, float angle){ - float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x + bulletOffset.x, y + bulletOffset.y, targetPos.x, targetPos.y) / type.range(), minRange / type.range(), range() / type.range()) : 1f; + float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x + bulletOffset.x, y + bulletOffset.y, targetPos.x, targetPos.y) / type.range, minRange / type.range, range() / type.range) : 1f; type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl); + effects(); } protected void effects(){