diff --git a/src/main/java/dev/dubhe/anvilcraft/api/sound/ISoundEventListener.java b/src/main/java/dev/dubhe/anvilcraft/api/sound/ISoundEventListener.java index d02a8bbe1d..a99c8d021b 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/sound/ISoundEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/sound/ISoundEventListener.java @@ -7,5 +7,5 @@ * 声音事件监听器 */ public interface ISoundEventListener { - boolean shouldPlay(ResourceLocation sound, Vec3 pos); + boolean shouldMute(ResourceLocation sound, Vec3 pos); } diff --git a/src/main/java/dev/dubhe/anvilcraft/api/sound/SoundHelper.java b/src/main/java/dev/dubhe/anvilcraft/api/sound/SoundHelper.java index 191f067534..5eda66e6c2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/sound/SoundHelper.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/sound/SoundHelper.java @@ -1,48 +1,41 @@ package dev.dubhe.anvilcraft.api.sound; import lombok.Getter; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; +import javax.annotation.Nullable; @Getter public class SoundHelper { - public static SoundHelper INSTANCE = new SoundHelper(); + public static final SoundHelper INSTANCE = new SoundHelper(); - private final Map> eventListeners = new HashMap<>(); + private final Map, List> eventListeners = new HashMap<>(); - public boolean shouldPlay(ResourceLocation sound, Vec3 pos) { - ClientLevel level = Minecraft.getInstance().level; - if (level == null) return true; - return eventListeners.computeIfAbsent(level, k -> new CopyOnWriteArrayList<>()) + public boolean shouldMute(@Nullable Level level, ResourceLocation sound, Vec3 pos) { + if (level == null) return false; + return this.eventListeners.computeIfAbsent(level.dimension(), k -> new CopyOnWriteArrayList<>()) .stream() - .allMatch(it -> it.shouldPlay(sound, pos)); + .allMatch(it -> it.shouldMute(sound, pos)); } - public void register(ISoundEventListener eventListener) { - ClientLevel level = Minecraft.getInstance().level; - if (level == null) return; - eventListeners.computeIfAbsent(level, k -> new CopyOnWriteArrayList<>()) + public void register(Level level, ISoundEventListener eventListener) { + this.eventListeners.computeIfAbsent(level.dimension(), k -> new CopyOnWriteArrayList<>()) .add(eventListener); } - public void unregister(ISoundEventListener eventListener) { - ClientLevel level = Minecraft.getInstance().level; - if (level == null) { - eventListeners.values().forEach(list -> list.remove(eventListener)); - return; - } - eventListeners.computeIfAbsent(level, k -> new CopyOnWriteArrayList<>()) + public void unregister(Level level, ISoundEventListener eventListener) { + this.eventListeners.computeIfAbsent(level.dimension(), k -> new CopyOnWriteArrayList<>()) .remove(eventListener); } public void clear() { - eventListeners.clear(); + this.eventListeners.clear(); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/ActiveSilencerBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/ActiveSilencerBlockEntity.java index 98d5d6da53..573008df9e 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/ActiveSilencerBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/ActiveSilencerBlockEntity.java @@ -93,13 +93,13 @@ public CompoundTag getUpdateTag(HolderLookup.Provider provider) { @Override public void setRemoved() { super.setRemoved(); - DistExecutor.run(Dist.CLIENT, () -> () -> SoundHelper.INSTANCE.unregister(this)); + DistExecutor.run(Dist.CLIENT, () -> () -> SoundHelper.INSTANCE.unregister(this.level, this)); } @Override public void setLevel(Level level) { super.setLevel(level); - DistExecutor.run(Dist.CLIENT, () -> () -> SoundHelper.INSTANCE.register(this)); + DistExecutor.run(Dist.CLIENT, () -> () -> SoundHelper.INSTANCE.register(level, this)); } @Override @@ -128,11 +128,11 @@ public void removeSound(ResourceLocation soundId) { } @Override - public boolean shouldPlay(ResourceLocation sound, Vec3 pos) { + public boolean shouldMute(ResourceLocation sound, Vec3 pos) { if (getBlockState().getValue(ActiveSilencerBlock.POWERED)) return true; boolean inRange = range.contains(pos); boolean inList = mutedSound.contains(sound); - return !inRange || !inList; + return inRange && inList; } public void sync(List sounds) { diff --git a/src/main/java/dev/dubhe/anvilcraft/client/support/InspectionSupport.java b/src/main/java/dev/dubhe/anvilcraft/client/support/InspectionSupport.java index 170d2c5a96..671f1f2d18 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/support/InspectionSupport.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/support/InspectionSupport.java @@ -18,7 +18,9 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.Shapes; @@ -34,8 +36,8 @@ public class InspectionSupport { public static void initializeClient() { INSTANCE.registerActionClient(AnvilCraft.of("silencer"), (p, r, c, d) -> { - Map> map = SoundHelper.INSTANCE.getEventListeners(); - List listeners = map.get(Minecraft.getInstance().level); + Map, List> map = SoundHelper.INSTANCE.getEventListeners(); + List listeners = map.get(Minecraft.getInstance().level.dimension()); MultiBufferSource.BufferSource buf = r.renderBuffers.bufferSource(); VertexConsumer vertex = buf.getBuffer(RenderType.LINES); if (listeners == null || listeners.isEmpty()) return; diff --git a/src/main/java/dev/dubhe/anvilcraft/event/LevelEventListener.java b/src/main/java/dev/dubhe/anvilcraft/event/LevelEventListener.java index 7b59f893a3..b1f9b0f8d5 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/LevelEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/LevelEventListener.java @@ -5,6 +5,7 @@ import dev.dubhe.anvilcraft.api.entity.fakeplayer.AnvilCraftDestroyerFakePlayer; import dev.dubhe.anvilcraft.api.entity.fakeplayer.AnvilCraftFakePlayers; import dev.dubhe.anvilcraft.api.entity.fakeplayer.AnvilCraftKillerFakePlayer; +import dev.dubhe.anvilcraft.api.sound.SoundHelper; import dev.dubhe.anvilcraft.api.world.load.LevelLoadManager; import dev.dubhe.anvilcraft.block.entity.DeflectionRingBlockEntity; import net.minecraft.server.level.ServerLevel; diff --git a/src/main/java/dev/dubhe/anvilcraft/event/ServerLifecycleEventListener.java b/src/main/java/dev/dubhe/anvilcraft/event/ServerLifecycleEventListener.java index e30b2ad036..aaff45819c 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/ServerLifecycleEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/ServerLifecycleEventListener.java @@ -5,6 +5,7 @@ import dev.dubhe.anvilcraft.api.heat.HeaterManager; import dev.dubhe.anvilcraft.api.heat.collector.HeatCollectorManager; import dev.dubhe.anvilcraft.api.power.PowerGrid; +import dev.dubhe.anvilcraft.api.sound.SoundHelper; import dev.dubhe.anvilcraft.api.world.load.LevelLoadManager; import dev.dubhe.anvilcraft.api.world.load.RandomChuckTickLoadManager; import dev.dubhe.anvilcraft.init.ModHammerInits; @@ -38,6 +39,7 @@ public static void onServerStopped(ServerStoppedEvent event) { PowerGrid.isServerClosing = false; PowerGrid.clear(); RecipeCaches.unload(); + SoundHelper.INSTANCE.clear(); } @SubscribeEvent diff --git a/src/main/java/dev/dubhe/anvilcraft/event/SoundEventListener.java b/src/main/java/dev/dubhe/anvilcraft/event/SoundEventListener.java new file mode 100644 index 0000000000..5217d06d97 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/event/SoundEventListener.java @@ -0,0 +1,31 @@ +package dev.dubhe.anvilcraft.event; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.api.sound.SoundHelper; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.PlayLevelSoundEvent; + +@EventBusSubscriber(modid = AnvilCraft.MOD_ID) +public class SoundEventListener { + @SubscribeEvent + public static void onPlaySoundAtEntity(PlayLevelSoundEvent.AtEntity event) { + Entity entity = event.getEntity(); + event.setCanceled(SoundHelper.INSTANCE.shouldMute( + event.getLevel(), + event.getSound().value().getLocation(), + new Vec3(entity.getX(), entity.getY(), entity.getZ()) + )); + } + + @SubscribeEvent + public static void onPlaySoundAtPosition(PlayLevelSoundEvent.AtPosition event) { + event.setCanceled(SoundHelper.INSTANCE.shouldMute( + event.getLevel(), + event.getSound().value().getLocation(), + event.getPosition() + )); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/SoundEngineMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/SoundEngineMixin.java index 26ed8028af..138fb5e527 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/SoundEngineMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/SoundEngineMixin.java @@ -1,6 +1,7 @@ package dev.dubhe.anvilcraft.mixin; import dev.dubhe.anvilcraft.api.sound.SoundHelper; +import net.minecraft.client.Minecraft; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.client.sounds.SoundEngine; import net.minecraft.world.phys.Vec3; @@ -13,7 +14,11 @@ abstract class SoundEngineMixin { @Inject(method = "play", at = @At(value = "HEAD"), cancellable = true) private void onSoundPlay(SoundInstance sound, CallbackInfo ci) { - if (!SoundHelper.INSTANCE.shouldPlay(sound.getLocation(), new Vec3(sound.getX(), sound.getY(), sound.getZ()))) { + if (SoundHelper.INSTANCE.shouldMute( + Minecraft.getInstance().level, + sound.getLocation(), + new Vec3(sound.getX(), sound.getY(), sound.getZ()) + )) { ci.cancel(); } }