初步实现移动音源功能

This commit is contained in:
Atsuishio 2025-05-06 04:28:10 +08:00 committed by Light_Quanta
parent 5f554adc7c
commit 7205d158cc
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
15 changed files with 137 additions and 54 deletions

View file

@ -1,19 +0,0 @@
package com.atsuishio.superbwarfare;
import com.atsuishio.superbwarfare.client.VehicleSoundInstance;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import net.minecraft.client.Minecraft;
public class ModClient {
public static void init() {
initEntities();
}
public static void initEntities() {
MobileVehicleEntity.engineSound = mobileVehicle -> {
var client = Minecraft.getInstance();
client.getSoundManager().play(new VehicleSoundInstance.EngineSound(client, mobileVehicle));
};
}
}

View file

@ -0,0 +1,37 @@
package com.atsuishio.superbwarfare.client;
import com.atsuishio.superbwarfare.entity.vehicle.Tom6Entity;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
public class PlayerSoundInstance extends AbstractTickableSoundInstance {
private final LocalPlayer player;
public PlayerSoundInstance(LocalPlayer pPlayer) {
super(SoundEvents.ELYTRA_FLYING, SoundSource.PLAYERS, SoundInstance.createUnseededRandom());
this.player = pPlayer;
this.looping = true;
this.delay = 0;
this.volume = 0.1F;
}
public void tick() {
if (!this.player.isRemoved() && (this.player.getVehicle() instanceof Tom6Entity tom6Entity)) {
this.x = player.getX();
this.y = player.getY();
this.z = player.getZ();
float $$0 = (float)tom6Entity.getDeltaMovement().lengthSqr();
if ((double)$$0 >= 1.0E-7) {
this.volume = Mth.clamp($$0 / 4.0F, 0.0F, 1.0F);
} else {
this.volume = 0.0F;
}
} else {
this.stop();
}
}
}

View file

@ -5,13 +5,12 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import org.joml.Math;
public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance { public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance {
private final Minecraft client; private final Minecraft client;
private final MobileVehicleEntity mobileVehicle; private final MobileVehicleEntity mobileVehicle;
private double lastDistance; private double lastDistance;
private int fade = 0; private int fade = 0;
private boolean die = false; private boolean die = false;
@ -28,6 +27,7 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
protected abstract float getPitch(MobileVehicleEntity mobileVehicle); protected abstract float getPitch(MobileVehicleEntity mobileVehicle);
protected abstract float getVolume(MobileVehicleEntity mobileVehicle); protected abstract float getVolume(MobileVehicleEntity mobileVehicle);
protected abstract float getRadius(MobileVehicleEntity mobileVehicle);
@Override @Override
public void tick() { public void tick() {
@ -48,7 +48,10 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
} else if (this.fade < 3) { } else if (this.fade < 3) {
this.fade++; this.fade++;
} }
this.volume = this.getVolume(this.mobileVehicle) * (float)fade / 3;
float distanceReduce = Math.max((1 - player.distanceTo(mobileVehicle) / getRadius(mobileVehicle)), 0);
this.volume = this.getVolume(this.mobileVehicle) * fade * distanceReduce * distanceReduce;
this.x = this.mobileVehicle.getX(); this.x = this.mobileVehicle.getX();
this.y = this.mobileVehicle.getY(); this.y = this.mobileVehicle.getY();
@ -58,7 +61,7 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
if (player.getVehicle() != this.mobileVehicle) { if (player.getVehicle() != this.mobileVehicle) {
double distance = this.mobileVehicle.position().subtract(player.position()).length(); double distance = this.mobileVehicle.position().subtract(player.position()).length();
this.pitch += (float) (0.36 * Math.atan(lastDistance - distance)); this.pitch += (float) (0.16 * java.lang.Math.atan(lastDistance - distance));
this.lastDistance = distance; this.lastDistance = distance;
} else { } else {
@ -66,9 +69,14 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
} }
} }
@Override
public Attenuation getAttenuation() {
return Attenuation.NONE;
}
public static class EngineSound extends VehicleSoundInstance { public static class EngineSound extends VehicleSoundInstance {
public EngineSound(Minecraft client, MobileVehicleEntity mobileVehicle) { public EngineSound(MobileVehicleEntity mobileVehicle, SoundEvent soundEvent) {
super(mobileVehicle.getEngineSound(), client, mobileVehicle); super(soundEvent, Minecraft.getInstance(), mobileVehicle);
} }
@Override @Override
@ -83,7 +91,12 @@ public abstract class VehicleSoundInstance extends AbstractTickableSoundInstance
@Override @Override
protected float getVolume(MobileVehicleEntity mobileVehicle) { protected float getVolume(MobileVehicleEntity mobileVehicle) {
return 1; return mobileVehicle.getEngineSoundVolume();
}
@Override
protected float getRadius(MobileVehicleEntity mobileVehicle) {
return mobileVehicle.getEngineSoundRadius();
} }
} }
} }

View file

@ -132,7 +132,7 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
super.baseTick(); super.baseTick();
float f; float f;
f = (float) Mth.clamp(Math.max((onGround() ? 0.785f : 0.79f) - 0.01 * getDeltaMovement().length(), 0.5) + 0.031f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90, 0.01, 0.99); f = (float) Mth.clamp(Math.max((onGround() ? 0.785f : 0.79f) - 0.013 * getDeltaMovement().length(), 0.5) + 0.031f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90, 0.01, 0.99);
boolean forward = Mth.abs((float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) < 90; boolean forward = Mth.abs((float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) < 90;
@ -311,6 +311,16 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
return ModSounds.A_10_ENGINE.get(); return ModSounds.A_10_ENGINE.get();
} }
@Override
public int getEngineSoundRadius() {
return 192;
}
@Override
public float getEngineSoundVolume() {
return entityData.get(POWER) * 1.5f;
}
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {
float f = Mth.wrapDegrees(entity.getXRot() - this.getXRot()); float f = Mth.wrapDegrees(entity.getXRot() - this.getXRot());
float f1 = Mth.clamp(f, -85.0F, 60F); float f1 = Mth.clamp(f, -85.0F, 60F);

View file

@ -362,6 +362,16 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
return ModSounds.HELICOPTER_ENGINE.get(); return ModSounds.HELICOPTER_ENGINE.get();
} }
@Override
public int getEngineSoundRadius() {
return 192;
}
@Override
public float getEngineSoundVolume() {
return entityData.get(PROPELLER_ROT) * 1.5f;
}
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {
if (entity == getNthEntity(0) || entity == getNthEntity(1)) { if (entity == getNthEntity(0) || entity == getNthEntity(1)) {
float f = Mth.wrapDegrees(entity.getXRot()); float f = Mth.wrapDegrees(entity.getXRot());

View file

@ -87,7 +87,7 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
@Override @Override
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
protected void playStepSound(BlockPos pPos, BlockState pState) { protected void playStepSound(BlockPos pPos, BlockState pState) {
this.playSound(ModSounds.WHEEL_STEP.get(), (float) (getDeltaMovement().length() * 0.5), random.nextFloat() * 0.1f + 1f); this.playSound(ModSounds.WHEEL_STEP.get(), (float) (getDeltaMovement().length() * 0.3), random.nextFloat() * 0.1f + 1f);
} }
@Override @Override
@ -234,7 +234,17 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
@Override @Override
public SoundEvent getEngineSound() { public SoundEvent getEngineSound() {
return SoundEvents.ELYTRA_FLYING; return SoundEvents.EMPTY;
}
@Override
public int getEngineSoundRadius() {
return 64;
}
@Override
public float getEngineSoundVolume() {
return entityData.get(POWER);
} }
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {

View file

@ -86,7 +86,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity {
@Override @Override
protected void playStepSound(@NotNull BlockPos pPos, @NotNull BlockState pState) { protected void playStepSound(@NotNull BlockPos pPos, @NotNull BlockState pState) {
this.playSound(ModSounds.WHEEL_STEP.get(), (float) (getDeltaMovement().length() * 0.5), random.nextFloat() * 0.15f + 1); this.playSound(ModSounds.WHEEL_STEP.get(), (float) (getDeltaMovement().length() * 0.3), random.nextFloat() * 0.15f + 1);
} }
@Override @Override
@ -148,9 +148,6 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity {
this.forwardInputDown = false; this.forwardInputDown = false;
this.backInputDown = false; this.backInputDown = false;
} else if (passenger instanceof Player) { } else if (passenger instanceof Player) {
if (level().isClientSide && this.getEnergy() > 0) {
level().playLocalSound(this.getX(), this.getY() + this.getBbHeight() * 0.5, this.getZ(), this.getEngineSound(), this.getSoundSource(), Math.min((this.forwardInputDown || this.backInputDown ? 7.5f : 5f) * 2 * Mth.abs(this.entityData.get(POWER)), 0.25f), (random.nextFloat() * 0.1f + 1f), false);
}
diffY = Math.clamp(-90f, 90f, Mth.wrapDegrees(passenger.getYHeadRot() - this.getYRot())); diffY = Math.clamp(-90f, 90f, Mth.wrapDegrees(passenger.getYHeadRot() - this.getYRot()));
this.setYRot(this.getYRot() + Mth.clamp(0.4f * diffY, -5f, 5f)); this.setYRot(this.getYRot() + Mth.clamp(0.4f * diffY, -5f, 5f));
@ -226,6 +223,11 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity {
return ModSounds.WHEEL_CHAIR_ENGINE.get(); return ModSounds.WHEEL_CHAIR_ENGINE.get();
} }
@Override
public float getEngineSoundVolume() {
return entityData.get(POWER);
}
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {
entity.setYBodyRot(this.getYRot()); entity.setYBodyRot(this.getYRot());
float f2 = Mth.wrapDegrees(entity.getYRot() - this.getYRot()); float f2 = Mth.wrapDegrees(entity.getYRot() - this.getYRot());

View file

@ -692,6 +692,13 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
public SoundEvent getEngineSound() { public SoundEvent getEngineSound() {
return SoundEvents.EMPTY; return SoundEvents.EMPTY;
} }
public int getEngineSoundRadius() {
return 32;
}
public float getEngineSoundVolume() {
return (float) Mth.lerp(Mth.clamp(getDeltaMovement().length(), 0F, 0.5F), 0.0F, 0.7F);
}
public double getVelocity() { public double getVelocity() {
return this.velocity; return this.velocity;

View file

@ -1,6 +1,6 @@
package com.atsuishio.superbwarfare.event; package com.atsuishio.superbwarfare.event;
import com.atsuishio.superbwarfare.ModClient; import com.atsuishio.superbwarfare.client.VehicleSoundInstance;
import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity; import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.*; import com.atsuishio.superbwarfare.entity.vehicle.*;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
@ -19,13 +19,12 @@ import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import org.joml.Math; import org.joml.Math;
import java.util.List; import java.util.List;
import static com.atsuishio.superbwarfare.entity.vehicle.Ah6Entity.PROPELLER_ROT;
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.DELTA_ROT; import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.DELTA_ROT;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.POWER; import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.POWER;
@ -33,8 +32,14 @@ import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntit
public class ClientSoundHandler { public class ClientSoundHandler {
@SubscribeEvent @SubscribeEvent
public static void initClient(FMLClientSetupEvent setup) { public static void handleJoinLevelEvent(EntityJoinLevelEvent event) {
ModClient.init(); if (event.getLevel().isClientSide) {
com.atsuishio.superbwarfare.Mod.queueClientWork(5, () -> {
if (event.getEntity() instanceof MobileVehicleEntity mobileVehicle) {
Minecraft.getInstance().getSoundManager().play(new VehicleSoundInstance.EngineSound(mobileVehicle, mobileVehicle.getEngineSound()));
}
});
}
} }
@SubscribeEvent @SubscribeEvent
@ -55,14 +60,14 @@ public class ClientSoundHandler {
var engineSoundPos = new Vec3(listener.x + toVec.x, listener.y + toVec.y, listener.z + toVec.z); var engineSoundPos = new Vec3(listener.x + toVec.x, listener.y + toVec.y, listener.z + toVec.z);
SoundEvent engineSound = mobileVehicle.getEngineSound(); SoundEvent engineSound = mobileVehicle.getEngineSound();
float distanceReduce; float distanceReduce;
if (e instanceof Ah6Entity ah6Entity) { // if (e instanceof Ah6Entity ah6Entity) {
distanceReduce = (float) Math.max((1 - distance / 128), 0); // distanceReduce = (float) Math.max((1 - distance / 128), 0);
if (player.getVehicle() == ah6Entity) { // if (player.getVehicle() == ah6Entity) {
player.playSound(ModSounds.HELICOPTER_ENGINE_1P.get(), 2 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f), (float) ((2 * Math.random() - 1) * 0.1f + 1.0f)); // player.playSound(ModSounds.HELICOPTER_ENGINE_1P.get(), 2 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f), (float) ((2 * Math.random() - 1) * 0.1f + 1.0f));
} else { // } else {
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false); // player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (mobileVehicle.getEntityData().get(PROPELLER_ROT) - 0.012f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
} // }
} // }
if (e instanceof Lav150Entity lav150) { if (e instanceof Lav150Entity lav150) {
distanceReduce = (float) Math.max((1 - distance / 64), 0); distanceReduce = (float) Math.max((1 - distance / 64), 0);
if (player.getVehicle() == lav150) { if (player.getVehicle() == lav150) {
@ -105,14 +110,14 @@ public class ClientSoundHandler {
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), e.onGround() ? 0 : distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.002f + 1.05), false); player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), e.onGround() ? 0 : distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.002f + 1.05), false);
} }
} }
if (e instanceof A10Entity a10Entity) { // if (e instanceof A10Entity a10Entity) {
distanceReduce = (float) Math.max((1 - distance / 128), 0); // distanceReduce = (float) Math.max((1 - distance / 128), 0);
if (player.getVehicle() == a10Entity) { // if (player.getVehicle() == a10Entity) {
player.playSound(ModSounds.A_10_ENGINE_1P.get(), 2 * (mobileVehicle.getEntityData().get(POWER) - 0.012f), (float) ((2 * Math.random() - 1) * 0.1f + 1.0f)); // player.playSound(ModSounds.A_10_ENGINE_1P.get(), 2 * (mobileVehicle.getEntityData().get(POWER) - 0.012f), (float) ((2 * Math.random() - 1) * 0.1f + 1.0f));
} else { // } else {
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (mobileVehicle.getEntityData().get(POWER) - 0.012f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false); // player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (mobileVehicle.getEntityData().get(POWER) - 0.012f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
} // }
} // }
} }
} }

View file

@ -442,6 +442,7 @@ public class ModSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_FIRE_3P = REGISTRY.register("hpj_11_fire_3p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_fire_3p"))); public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_FIRE_3P = REGISTRY.register("hpj_11_fire_3p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_fire_3p")));
public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_FAR = REGISTRY.register("hpj_11_far", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_far"))); public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_FAR = REGISTRY.register("hpj_11_far", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_far")));
public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_VERYFAR = REGISTRY.register("hpj_11_veryfar", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_veryfar"))); public static final DeferredHolder<SoundEvent, SoundEvent> HPJ_11_VERYFAR = REGISTRY.register("hpj_11_veryfar", () -> SoundEvent.createVariableRangeEvent(Mod.loc("hpj_11_veryfar")));
public static final DeferredHolder<SoundEvent, SoundEvent> WIND_LOOP = REGISTRY.register("wind_loop", () -> SoundEvent.createVariableRangeEvent(Mod.loc("wind_loop")));
public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE = REGISTRY.register("a10_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine"))); public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE = REGISTRY.register("a10_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine")));
public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE_1P = REGISTRY.register("a10_engine_1p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine_1p"))); public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE_1P = REGISTRY.register("a10_engine_1p", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine_1p")));
} }

View file

@ -3068,6 +3068,13 @@
} }
] ]
}, },
"wind_loop": {
"sounds": [
{
"name": "superbwarfare:wind_loop"
}
]
},
"a10_engine": { "a10_engine": {
"sounds": [ "sounds": [
{ {