Shield and shockwave tower sounds

This commit is contained in:
Anuken
2025-11-29 17:43:36 -05:00
parent 3e0eb4a875
commit 43d4deb801
12 changed files with 51 additions and 13 deletions

View File

@@ -59,6 +59,8 @@ public class SoundPriority{
walkerStep.setMinConcurrentInterrupt(0.6f);
mechStepHeavy.setMinConcurrentInterrupt(0.6f);
shieldHit.setMaxConcurrent(4);
max(4, mechStep, mechStepHeavy, walkerStep);
}

View File

@@ -1514,7 +1514,9 @@ public class UnitTypes{
buildBeamOffset = 43;
ammoCapacity = 1;
abilities.add(new ForceFieldAbility(140f, 4f, 7000f, 60f * 8, 8, 0f), new RepairFieldAbility(130f, 60f * 2, 140f));
abilities.add(new ForceFieldAbility(140f, 4f, 7000f, 60f * 8, 8, 0f){{
breakSound = Sounds.shieldBreak;
}}, new RepairFieldAbility(130f, 60f * 2, 140f));
}};
//endregion

View File

@@ -1,6 +1,7 @@
package mindustry.entities.abilities;
import arc.*;
import arc.audio.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
@@ -30,6 +31,10 @@ public class ForceFieldAbility extends Ability{
/** Rotation of shield. */
public float rotation = 0f;
public Sound breakSound = Sounds.shieldBreakSmall;
public Sound hitSound = Sounds.shieldHit;
public float hitSoundVolume = 0.12f;
/** State. */
protected float radiusScale, alpha;
protected boolean wasBroken = true;
@@ -37,11 +42,12 @@ public class ForceFieldAbility extends Ability{
private static float realRad;
private static Unit paramUnit;
private static ForceFieldAbility paramField;
private static final Cons<Bullet> shieldConsumer = trait -> {
if(trait.team != paramUnit.team && trait.type.absorbable && Intersector.isInRegularPolygon(paramField.sides, paramUnit.x, paramUnit.y, realRad, paramField.rotation, trait.x(), trait.y()) && paramUnit.shield > 0){
trait.absorb();
Fx.absorb.at(trait);
paramUnit.shield -= trait.type().shieldDamage(trait);
private static final Cons<Bullet> shieldConsumer = b -> {
if(b.team != paramUnit.team && b.type.absorbable && Intersector.isInRegularPolygon(paramField.sides, paramUnit.x, paramUnit.y, realRad, paramField.rotation, b.x(), b.y()) && paramUnit.shield > 0){
b.absorb();
Fx.absorb.at(b);
paramField.hitSound.at(b.x, b.y, 1f + Mathf.range(0.1f), paramField.hitSoundVolume);
paramUnit.shield -= b.type().shieldDamage(b);
paramField.alpha = 1f;
}
};
@@ -82,6 +88,7 @@ public class ForceFieldAbility extends Ability{
unit.shield -= cooldown * regen;
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this);
breakSound.at(unit.x, unit.y);
}
wasBroken = unit.shield <= 0f;
@@ -110,6 +117,7 @@ public class ForceFieldAbility extends Ability{
//self-destructing units can have a shield on death
if(unit.shield > 0f && !wasBroken){
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this);
breakSound.at(unit.x, unit.y);
}
}

View File

@@ -16,6 +16,7 @@ import mindustry.graphics.*;
import mindustry.ui.*;
public class ShieldArcAbility extends Ability{
private static Unit paramUnit;
private static ShieldArcAbility paramField;
private static Vec2 paramPos = new Vec2();
@@ -48,6 +49,8 @@ public class ShieldArcAbility extends Ability{
}else{
b.absorb();
Fx.absorb.at(b);
paramField.hitSound.at(b.x, b.y, 1f + Mathf.range(0.1f), paramField.hitSoundVolume);
}
// break shield
@@ -55,6 +58,8 @@ public class ShieldArcAbility extends Ability{
paramField.data -= paramField.cooldown * paramField.regen;
Fx.arcShieldBreak.at(paramPos.x, paramPos.y, 0, paramField.color == null ? paramUnit.type.shieldColor(paramUnit) : paramField.color, paramUnit);
paramField.breakSound.at(paramPos.x, paramPos.y);
}
// shieldDamage for consistency
@@ -121,6 +126,9 @@ public class ShieldArcAbility extends Ability{
public float chanceDeflect = -1f;
/** Deflection sound. */
public Sound deflectSound = Sounds.none;
public Sound breakSound = Sounds.shieldBreakSmall;
public Sound hitSound = Sounds.shieldHit;
public float hitSoundVolume = 0.12f;
/** Multiplier for shield damage taken from missile units. */
public float missileUnitMultiplier = 2f;

View File

@@ -376,6 +376,13 @@ public class BulletType extends Content implements Cloneable{
}
}
@Override
public void afterPatch(){
super.afterPatch();
range = calculateRange();
}
@Override
public void load(){
for(var part : parts){

View File

@@ -137,6 +137,8 @@ public class DataPatcher{
weapon.load();
weapon.init();
}else if(object instanceof Content cont){
cont.init();
cont.postInit();
cont.load();
}
}else{

View File

@@ -1,6 +1,7 @@
package mindustry.world.blocks.defense;
import arc.*;
import arc.audio.*;
import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
@@ -42,6 +43,9 @@ public class ForceProjector extends Block{
public float coolantConsumption = 0.1f;
public boolean consumeCoolant = true;
public float crashDamageMultiplier = 2f;
public Sound breakSound = Sounds.shieldBreak;
public Sound hitSound = Sounds.shieldHit;
public float hitSoundVolume = 0.12f;
public Effect absorbEffect = Fx.absorb;
public Effect shieldBreakEffect = Fx.shieldBreak;
public @Load("@-top") TextureRegion topRegion;
@@ -49,12 +53,16 @@ public class ForceProjector extends Block{
//TODO json support
public @Nullable Consume itemConsumer, coolantConsumer;
//lambdas need to be static to prevent GC
protected static ForceProjector paramBlock;
protected static ForceBuild paramEntity;
protected static Effect paramEffect;
protected static final Cons<Bullet> shieldConsumer = bullet -> {
if(bullet.team != paramEntity.team && bullet.type.absorbable && !bullet.absorbed && Intersector.isInRegularPolygon(((ForceProjector)(paramEntity.block)).sides, paramEntity.x, paramEntity.y, paramEntity.realRadius(), ((ForceProjector)(paramEntity.block)).shieldRotation, bullet.x, bullet.y)){
if(bullet.team != paramEntity.team && bullet.type.absorbable && !bullet.absorbed &&
Intersector.isInRegularPolygon(paramBlock.sides, paramEntity.x, paramEntity.y, paramEntity.realRadius(), paramBlock.shieldRotation, bullet.x, bullet.y)){
bullet.absorb();
paramEffect.at(bullet);
paramBlock.hitSound.at(bullet.x, bullet.y, 1f + Mathf.range(0.1f), paramBlock.hitSoundVolume);
paramBlock.absorbEffect.at(bullet);
paramEntity.hit = 1f;
paramEntity.buildup += bullet.type.shieldDamage(bullet);
}
@@ -233,6 +241,7 @@ public class ForceProjector extends Block{
broken = true;
buildup = shieldHealth;
shieldBreakEffect.at(x, y, realRadius(), team.color);
breakSound.at(x, y);
if(team != state.rules.defaultTeam){
Events.fire(Trigger.forceProjectorBreak);
}
@@ -249,8 +258,8 @@ public class ForceProjector extends Block{
float realRadius = realRadius();
if(realRadius > 0 && !broken){
paramBlock = ForceProjector.this;
paramEntity = this;
paramEffect = absorbEffect;
Groups.bullet.intersect(x - realRadius, y - realRadius, realRadius * 2f, realRadius * 2f, shieldConsumer);
}
}

View File

@@ -29,7 +29,7 @@ public class ShockwaveTower extends Block{
public float shake = 2f;
//checking for bullets every frame is costly, so only do it at intervals even when ready.
public float checkInterval = 8f;
public Sound shootSound = Sounds.bang;
public Sound shootSound = Sounds.shockwaveTower;
public Color waveColor = Pal.accent, heatColor = Pal.turretHeat, shapeColor = Color.valueOf("f29c83");
public float cooldownMultiplier = 1f;
public Effect hitEffect = Fx.hitSquaresColor;
@@ -62,7 +62,7 @@ public class ShockwaveTower extends Block{
Drawf.dashCircle(x * tilesize + offset, y * tilesize + offset, range, waveColor);
}
public class ShockwaveTowerBuild extends Building{
public float reloadCounter = Mathf.random(reload);
public float heat = 0f;
@@ -82,7 +82,7 @@ public class ShockwaveTower extends Block{
heat = 1f;
reloadCounter = 0f;
waveEffect.at(x, y, range, waveColor);
shootSound.at(this);
shootSound.at(x, y, 1f + Mathf.range(0.15f), 1f);
Effect.shake(shake, shake, this);
float waveDamage = Math.min(bulletDamage, bulletDamage * falloffCount / targets.size);