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