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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

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

View file

@ -1514,7 +1514,9 @@ public class UnitTypes{
buildBeamOffset = 43; buildBeamOffset = 43;
ammoCapacity = 1; 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 //endregion

View file

@ -1,6 +1,7 @@
package mindustry.entities.abilities; package mindustry.entities.abilities;
import arc.*; import arc.*;
import arc.audio.*;
import arc.func.*; import arc.func.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
@ -30,6 +31,10 @@ public class ForceFieldAbility extends Ability{
/** Rotation of shield. */ /** Rotation of shield. */
public float rotation = 0f; public float rotation = 0f;
public Sound breakSound = Sounds.shieldBreakSmall;
public Sound hitSound = Sounds.shieldHit;
public float hitSoundVolume = 0.12f;
/** State. */ /** State. */
protected float radiusScale, alpha; protected float radiusScale, alpha;
protected boolean wasBroken = true; protected boolean wasBroken = true;
@ -37,11 +42,12 @@ public class ForceFieldAbility extends Ability{
private static float realRad; private static float realRad;
private static Unit paramUnit; private static Unit paramUnit;
private static ForceFieldAbility paramField; private static ForceFieldAbility paramField;
private static final Cons<Bullet> shieldConsumer = trait -> { private static final Cons<Bullet> shieldConsumer = b -> {
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){ 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){
trait.absorb(); b.absorb();
Fx.absorb.at(trait); Fx.absorb.at(b);
paramUnit.shield -= trait.type().shieldDamage(trait); paramField.hitSound.at(b.x, b.y, 1f + Mathf.range(0.1f), paramField.hitSoundVolume);
paramUnit.shield -= b.type().shieldDamage(b);
paramField.alpha = 1f; paramField.alpha = 1f;
} }
}; };
@ -82,6 +88,7 @@ public class ForceFieldAbility extends Ability{
unit.shield -= cooldown * regen; unit.shield -= cooldown * regen;
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this); Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this);
breakSound.at(unit.x, unit.y);
} }
wasBroken = unit.shield <= 0f; wasBroken = unit.shield <= 0f;
@ -110,6 +117,7 @@ public class ForceFieldAbility extends Ability{
//self-destructing units can have a shield on death //self-destructing units can have a shield on death
if(unit.shield > 0f && !wasBroken){ if(unit.shield > 0f && !wasBroken){
Fx.shieldBreak.at(unit.x, unit.y, radius, unit.type.shieldColor(unit), this); 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.*; import mindustry.ui.*;
public class ShieldArcAbility extends Ability{ public class ShieldArcAbility extends Ability{
private static Unit paramUnit; private static Unit paramUnit;
private static ShieldArcAbility paramField; private static ShieldArcAbility paramField;
private static Vec2 paramPos = new Vec2(); private static Vec2 paramPos = new Vec2();
@ -48,6 +49,8 @@ public class ShieldArcAbility extends Ability{
}else{ }else{
b.absorb(); b.absorb();
Fx.absorb.at(b); Fx.absorb.at(b);
paramField.hitSound.at(b.x, b.y, 1f + Mathf.range(0.1f), paramField.hitSoundVolume);
} }
// break shield // break shield
@ -55,6 +58,8 @@ public class ShieldArcAbility extends Ability{
paramField.data -= paramField.cooldown * paramField.regen; paramField.data -= paramField.cooldown * paramField.regen;
Fx.arcShieldBreak.at(paramPos.x, paramPos.y, 0, paramField.color == null ? paramUnit.type.shieldColor(paramUnit) : paramField.color, paramUnit); 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 // shieldDamage for consistency
@ -121,6 +126,9 @@ public class ShieldArcAbility extends Ability{
public float chanceDeflect = -1f; public float chanceDeflect = -1f;
/** Deflection sound. */ /** Deflection sound. */
public Sound deflectSound = Sounds.none; 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. */ /** Multiplier for shield damage taken from missile units. */
public float missileUnitMultiplier = 2f; 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 @Override
public void load(){ public void load(){
for(var part : parts){ for(var part : parts){

View file

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

View file

@ -1,6 +1,7 @@
package mindustry.world.blocks.defense; package mindustry.world.blocks.defense;
import arc.*; import arc.*;
import arc.audio.*;
import arc.func.*; import arc.func.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
@ -42,6 +43,9 @@ public class ForceProjector extends Block{
public float coolantConsumption = 0.1f; public float coolantConsumption = 0.1f;
public boolean consumeCoolant = true; public boolean consumeCoolant = true;
public float crashDamageMultiplier = 2f; 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 absorbEffect = Fx.absorb;
public Effect shieldBreakEffect = Fx.shieldBreak; public Effect shieldBreakEffect = Fx.shieldBreak;
public @Load("@-top") TextureRegion topRegion; public @Load("@-top") TextureRegion topRegion;
@ -49,12 +53,16 @@ public class ForceProjector extends Block{
//TODO json support //TODO json support
public @Nullable Consume itemConsumer, coolantConsumer; public @Nullable Consume itemConsumer, coolantConsumer;
//lambdas need to be static to prevent GC
protected static ForceProjector paramBlock;
protected static ForceBuild paramEntity; protected static ForceBuild paramEntity;
protected static Effect paramEffect;
protected static final Cons<Bullet> shieldConsumer = bullet -> { 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(); 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.hit = 1f;
paramEntity.buildup += bullet.type.shieldDamage(bullet); paramEntity.buildup += bullet.type.shieldDamage(bullet);
} }
@ -233,6 +241,7 @@ public class ForceProjector extends Block{
broken = true; broken = true;
buildup = shieldHealth; buildup = shieldHealth;
shieldBreakEffect.at(x, y, realRadius(), team.color); shieldBreakEffect.at(x, y, realRadius(), team.color);
breakSound.at(x, y);
if(team != state.rules.defaultTeam){ if(team != state.rules.defaultTeam){
Events.fire(Trigger.forceProjectorBreak); Events.fire(Trigger.forceProjectorBreak);
} }
@ -249,8 +258,8 @@ public class ForceProjector extends Block{
float realRadius = realRadius(); float realRadius = realRadius();
if(realRadius > 0 && !broken){ if(realRadius > 0 && !broken){
paramBlock = ForceProjector.this;
paramEntity = this; paramEntity = this;
paramEffect = absorbEffect;
Groups.bullet.intersect(x - realRadius, y - realRadius, realRadius * 2f, realRadius * 2f, shieldConsumer); 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; public float shake = 2f;
//checking for bullets every frame is costly, so only do it at intervals even when ready. //checking for bullets every frame is costly, so only do it at intervals even when ready.
public float checkInterval = 8f; 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 Color waveColor = Pal.accent, heatColor = Pal.turretHeat, shapeColor = Color.valueOf("f29c83");
public float cooldownMultiplier = 1f; public float cooldownMultiplier = 1f;
public Effect hitEffect = Fx.hitSquaresColor; public Effect hitEffect = Fx.hitSquaresColor;
@ -82,7 +82,7 @@ public class ShockwaveTower extends Block{
heat = 1f; heat = 1f;
reloadCounter = 0f; reloadCounter = 0f;
waveEffect.at(x, y, range, waveColor); waveEffect.at(x, y, range, waveColor);
shootSound.at(this); shootSound.at(x, y, 1f + Mathf.range(0.15f), 1f);
Effect.shake(shake, shake, this); Effect.shake(shake, shake, this);
float waveDamage = Math.min(bulletDamage, bulletDamage * falloffCount / targets.size); float waveDamage = Math.min(bulletDamage, bulletDamage * falloffCount / targets.size);