Better weapon shooting implementation
This commit is contained in:
@@ -3354,14 +3354,14 @@ public class Blocks{
|
||||
targetAir = false;
|
||||
shootShake = 4f;
|
||||
recoilAmount = 1f;
|
||||
reloadTime = 60f * 2f;
|
||||
reloadTime = 60f * 2.3f;
|
||||
shootLength = 7f;
|
||||
rotateSpeed = 1.4f;
|
||||
minWarmup = 0.85f;
|
||||
shootWarmupSpeed = 0.07f;
|
||||
|
||||
coolant = consume(new ConsumeLiquid(Liquids.water, 30f / 60f));
|
||||
coolantMultiplier = 2.5f;
|
||||
coolantMultiplier = 1.5f;
|
||||
|
||||
draw = new DrawTurret("reinforced-"){{
|
||||
parts.addAll(
|
||||
|
||||
@@ -1515,7 +1515,7 @@ public class Fx{
|
||||
color(Color.white, e.color, e.fin());
|
||||
|
||||
rand.setSeed(e.id);
|
||||
for(int i = 0; i < 10; i++){
|
||||
for(int i = 0; i < 8; i++){
|
||||
float rot = e.rotation + rand.range(22f);
|
||||
v.trns(rot, rand.random(e.finpow() * 24f));
|
||||
Fill.poly(e.x + v.x, e.y + v.y, 4, e.fout() * 3.8f + 0.2f, rand.random(360f));
|
||||
|
||||
@@ -479,7 +479,7 @@ public class UnitTypes{
|
||||
despawnEffect = Fx.smokeCloud;
|
||||
smokeEffect = Fx.none;
|
||||
|
||||
shootEffect = Fx.greenLaserChargeSmall;
|
||||
chargeEffect = Fx.greenLaserChargeSmall;
|
||||
|
||||
incendChance = 0.1f;
|
||||
incendSpread = 5f;
|
||||
@@ -566,7 +566,7 @@ public class UnitTypes{
|
||||
largeHit = true;
|
||||
lightColor = lightningColor = Pal.heal;
|
||||
|
||||
shootEffect = Fx.greenLaserCharge;
|
||||
chargeEffect = Fx.greenLaserCharge;
|
||||
|
||||
healPercent = 25f;
|
||||
collidesTeam = true;
|
||||
@@ -1209,7 +1209,7 @@ public class UnitTypes{
|
||||
shadow = 7f;
|
||||
rotate = true;
|
||||
recoil = 0.5f;
|
||||
|
||||
shootY = 7.25f;
|
||||
bullet = fragBullet;
|
||||
}},
|
||||
new Weapon("large-artillery"){{
|
||||
@@ -1222,6 +1222,7 @@ public class UnitTypes{
|
||||
shootSound = Sounds.shoot;
|
||||
rotate = true;
|
||||
shadow = 12f;
|
||||
shootY = 7.25f;
|
||||
bullet = fragBullet;
|
||||
}});
|
||||
}};
|
||||
@@ -2481,6 +2482,8 @@ public class UnitTypes{
|
||||
heatColor = Color.valueOf("f9350f");
|
||||
cooldownTime = 30f;
|
||||
|
||||
shots = 2;
|
||||
|
||||
bullet = new BasicBulletType(5f, 50){{
|
||||
sprite = "missile-large";
|
||||
smokeEffect = Fx.shootBigSmoke;
|
||||
@@ -2887,11 +2890,11 @@ public class UnitTypes{
|
||||
|
||||
x = 43 / 4f;
|
||||
y = -20f / 4f;
|
||||
shootY = 39 / 4f;
|
||||
shootY = 37 / 4f;
|
||||
shootX = -5f / 4f;
|
||||
recoil = 3f;
|
||||
reload = 30f;
|
||||
shake = 3f;
|
||||
shake = 2f;
|
||||
cooldownTime = 20f;
|
||||
layerOffset = 0.02f;
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ public class BulletType extends Content implements Cloneable{
|
||||
public Effect despawnEffect = Fx.hitBulletSmall;
|
||||
/** Effect created when shooting. */
|
||||
public Effect shootEffect = Fx.shootSmall;
|
||||
/** Effect created when charging completes; only usable in single-shot weapons with a firstShotDelay / shotDelay. */
|
||||
public Effect chargeShootEffect = Fx.none;
|
||||
/** Effect created when charging starts; only usable in single-shot weapons with a firstShotDelay / shotDelay. */
|
||||
public Effect chargeEffect = Fx.none;
|
||||
/** Extra smoke effect created when shooting. */
|
||||
public Effect smokeEffect = Fx.shootSmallSmoke;
|
||||
/** Sound made when hitting something or getting removed.*/
|
||||
|
||||
@@ -24,9 +24,6 @@ import mindustry.world.meta.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class Weapon implements Cloneable{
|
||||
/** temporary weapon sequence number */
|
||||
static int sequenceNum = 0;
|
||||
|
||||
/** displayed weapon region */
|
||||
public String name;
|
||||
/** bullet shot */
|
||||
@@ -276,7 +273,7 @@ public class Weapon implements Cloneable{
|
||||
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 = rotate ? unit.rotation + mount.rotation : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY));
|
||||
shootAngle = bulletRotation(unit, mount, bulletX, bulletY);
|
||||
|
||||
//find a new target
|
||||
if(!controllable && autoTarget){
|
||||
@@ -370,86 +367,62 @@ public class Weapon implements Cloneable{
|
||||
return Units.invalidateTarget(target, unit.team, x, y, range + Math.abs(shootY));
|
||||
}
|
||||
|
||||
protected Vec2 getShootPos(Unit unit, WeaponMount mount, Vec2 out){
|
||||
float weaponRot = unit.rotation - 90 + (rotate ? mount.rotation : 0);
|
||||
return out.set(unit.x, unit.y)
|
||||
.add(Angles.trnsx(unit.rotation - 90, x, y), Angles.trnsy(unit.rotation - 90, x, y))
|
||||
.add(Angles.trnsx(weaponRot, this.shootX, this.shootY), Angles.trnsx(weaponRot, this.shootX, this.shootY));
|
||||
protected float bulletRotation(Unit unit, WeaponMount mount, float bulletX, float bulletY){
|
||||
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){
|
||||
Vec2 offset = getShootPos(unit, mount, Tmp.v1);
|
||||
float baseX = offset.x, baseY = offset.y, baseRot = unit.rotation + mount.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 far too complicated and similar to Turret
|
||||
//TODO merge with Turret behavior
|
||||
|
||||
//UnitTypes.eclipse.weapons.get(2).shotDelay = 4
|
||||
|
||||
sequenceNum = 0;
|
||||
if(delay){
|
||||
Angles.shotgun(shots, spacing, rotation, f -> {
|
||||
Time.run(sequenceNum * shotDelay + firstShotDelay, () -> {
|
||||
if(!unit.isAdded()) return;
|
||||
chargeSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
bullet.chargeEffect.at(shootX, shootY, rotation, parent);
|
||||
|
||||
//TODO this is a flawed system, recalculate everything instead.
|
||||
getShootPos(unit, mount, offset).sub(baseX, baseY);
|
||||
for(int i = 0; i < shots; i++){
|
||||
float angleOffset = i * spacing - (shots - 1) * spacing / 2f;
|
||||
|
||||
float rotOffset = unit.rotation + mount.rotation - baseRot;
|
||||
mount.bullet = bullet(unit, shootX + offset.x, shootY + offset.y, f + Mathf.range(inaccuracy) + rotOffset, lifeScl);
|
||||
if(!continuous){
|
||||
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
}
|
||||
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);
|
||||
});
|
||||
sequenceNum++;
|
||||
});
|
||||
}
|
||||
}else{
|
||||
Angles.shotgun(shots, spacing, rotation, f -> mount.bullet = bullet(unit, shootX, shootY, f + Mathf.range(inaccuracy), lifeScl));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(delay){
|
||||
Time.run(firstShotDelay, () -> {
|
||||
if(!unit.isAdded()) return;
|
||||
|
||||
unit.vel.add(Tmp.v1.trns(rotation + 180f, bullet.recoil));
|
||||
Effect.shake(shake, shake, shootX, shootY);
|
||||
mount.recoil = recoil;
|
||||
mount.heat = 1f;
|
||||
if(!continuous){
|
||||
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
}
|
||||
|
||||
getShootPos(unit, mount, offset).sub(baseX, baseY);
|
||||
|
||||
bullet.chargeShootEffect.at(shootX + offset.x, shootY + offset.y, rotation, parent);
|
||||
});
|
||||
}else{
|
||||
unit.vel.add(Tmp.v1.trns(rotation + 180f, bullet.recoil));
|
||||
Effect.shake(shake, shake, shootX, shootY);
|
||||
mount.recoil = recoil;
|
||||
mount.heat = 1f;
|
||||
}
|
||||
|
||||
(delay ? chargeSound : continuous ? Sounds.none : shootSound).at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
effects(parent, mountX, mountY, shootX, shootY, rotation, side);
|
||||
unit.apply(shootStatus, shootStatusDuration);
|
||||
}
|
||||
|
||||
protected void effects(Unit parent, float mountX, float mountY, float shootX, float shootY, float rotation, int side){
|
||||
ejectEffect.at(mountX, mountY, rotation * side);
|
||||
bullet.shootEffect.at(shootX, shootY, rotation, bullet.hitColor, parent);
|
||||
bullet.smokeEffect.at(shootX, shootY, rotation, bullet.hitColor, parent);
|
||||
}
|
||||
protected @Nullable Bullet bullet(WeaponMount mount, Unit unit, float shootX, float shootY, float angle, float lifescl, int side, float mountRotation, float mountX, float mountY){
|
||||
if(!unit.isAdded()) return null;
|
||||
|
||||
protected @Nullable Bullet bullet(Unit unit, float shootX, float shootY, float angle, float lifescl){
|
||||
float
|
||||
xr = Mathf.range(xRand),
|
||||
x = shootX + Angles.trnsx(angle, 0, xr),
|
||||
y = shootY + Angles.trnsy(angle, 0, xr);
|
||||
|
||||
Bullet result = null;
|
||||
|
||||
if(unitSpawned == null){
|
||||
return bullet.create(unit, unit.team, x, y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl);
|
||||
result = bullet.create(unit, unit.team, x, y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd), lifescl);
|
||||
}else{
|
||||
//don't spawn units clientside!
|
||||
if(!net.client()){
|
||||
@@ -463,9 +436,23 @@ public class Weapon implements Cloneable{
|
||||
}
|
||||
spawned.add();
|
||||
}
|
||||
//TODO assign AI target here?
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!continuous){
|
||||
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
}
|
||||
|
||||
//TODO mount pos is wrong
|
||||
ejectEffect.at(mountX, mountY, angle * side);
|
||||
bullet.shootEffect.at(shootX, shootY, angle, bullet.hitColor, unit);
|
||||
bullet.smokeEffect.at(shootX, shootY, angle, bullet.hitColor, unit);
|
||||
|
||||
unit.vel.add(Tmp.v1.trns(mountRotation + 180f, bullet.recoil));
|
||||
Effect.shake(shake, shake, shootX, shootY);
|
||||
mount.recoil = recoil;
|
||||
mount.heat = 1f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Weapon copy(){
|
||||
|
||||
Reference in New Issue
Block a user