From 0141bdb7cd12111719c6eb3d46c1f18766cef286 Mon Sep 17 00:00:00 2001 From: Semmieboy YT Date: Wed, 24 Apr 2024 11:00:19 +0200 Subject: [PATCH] Finish omnidirectional note block sounds feature --- .../java/semmiedev/disc_jockey/Config.java | 2 +- ...java => OmnidirectionalSoundInstance.java} | 8 ++--- .../java/semmiedev/disc_jockey/Previewer.java | 4 ++- .../disc_jockey/mixin/ClientWorldMixin.java | 8 ++--- .../disc_jockey/mixin/SoundSystemMixin.java | 32 +++++++++++++++++++ .../assets/disc_jockey/lang/en_us.json | 6 ++-- src/main/resources/disc_jockey.mixins.json | 3 +- 7 files changed, 49 insertions(+), 14 deletions(-) rename src/main/java/semmiedev/disc_jockey/{MonoSoundInstance.java => OmnidirectionalSoundInstance.java} (71%) create mode 100644 src/main/java/semmiedev/disc_jockey/mixin/SoundSystemMixin.java diff --git a/src/main/java/semmiedev/disc_jockey/Config.java b/src/main/java/semmiedev/disc_jockey/Config.java index c5b094c..73713c7 100644 --- a/src/main/java/semmiedev/disc_jockey/Config.java +++ b/src/main/java/semmiedev/disc_jockey/Config.java @@ -10,7 +10,7 @@ import java.util.ArrayList; public class Config implements ConfigData { public boolean hideWarning; @ConfigEntry.Gui.Tooltip(count = 2) public boolean disableAsyncPlayback; - @ConfigEntry.Gui.Excluded @ConfigEntry.Gui.Tooltip(count = 2) public boolean monoNoteBlocks; + @ConfigEntry.Gui.Tooltip(count = 2) public boolean omnidirectionalNoteBlockSounds; @ConfigEntry.Gui.Excluded public ArrayList favorites = new ArrayList<>(); diff --git a/src/main/java/semmiedev/disc_jockey/MonoSoundInstance.java b/src/main/java/semmiedev/disc_jockey/OmnidirectionalSoundInstance.java similarity index 71% rename from src/main/java/semmiedev/disc_jockey/MonoSoundInstance.java rename to src/main/java/semmiedev/disc_jockey/OmnidirectionalSoundInstance.java index 12b52c4..7df6e7d 100644 --- a/src/main/java/semmiedev/disc_jockey/MonoSoundInstance.java +++ b/src/main/java/semmiedev/disc_jockey/OmnidirectionalSoundInstance.java @@ -8,14 +8,14 @@ import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; -// TODO: 6/1/2022 Make it actually mono -public class MonoSoundInstance extends AbstractSoundInstance { +public class OmnidirectionalSoundInstance extends AbstractSoundInstance { private final Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); - public MonoSoundInstance(SoundEvent sound, SoundCategory category, float volume, float pitch, Random random) { + public OmnidirectionalSoundInstance(SoundEvent sound, SoundCategory category, float volume, float pitch, Random random) { super(sound, category, random); this.volume = volume; this.pitch = pitch; + this.attenuationType = AttenuationType.NONE; } @Override @@ -34,6 +34,6 @@ public class MonoSoundInstance extends AbstractSoundInstance { } private Vec3d getPos() { - return camera.getPos().add(Vec3d.fromPolar(camera.getPitch(), camera.getYaw()).multiply(0, 0, 1)); + return camera.getPos(); } } diff --git a/src/main/java/semmiedev/disc_jockey/Previewer.java b/src/main/java/semmiedev/disc_jockey/Previewer.java index d31c607..572e716 100644 --- a/src/main/java/semmiedev/disc_jockey/Previewer.java +++ b/src/main/java/semmiedev/disc_jockey/Previewer.java @@ -4,6 +4,7 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.minecraft.client.MinecraftClient; import net.minecraft.client.world.ClientWorld; import net.minecraft.sound.SoundCategory; +import net.minecraft.util.math.Vec3d; public class Previewer implements ClientTickEvents.StartWorldTick { public boolean running; @@ -30,7 +31,8 @@ public class Previewer implements ClientTickEvents.StartWorldTick { while (running) { long note = song.notes[i]; if ((short)note == Math.round(tick)) { - world.playSoundFromEntity(MinecraftClient.getInstance().player, MinecraftClient.getInstance().player, Note.INSTRUMENTS[(byte)(note >> Note.INSTRUMENT_SHIFT)].getSound().value(), SoundCategory.RECORDS, 3, (float)Math.pow(2.0, ((byte)(note >> Note.NOTE_SHIFT) - 12) / 12.0)); + Vec3d pos = MinecraftClient.getInstance().gameRenderer.getCamera().getPos(); + world.playSound(pos.x, pos.y, pos.z, Note.INSTRUMENTS[(byte)(note >> Note.INSTRUMENT_SHIFT)].getSound().value(), SoundCategory.RECORDS, 3, (float)Math.pow(2.0, ((byte)(note >> Note.NOTE_SHIFT) - 12) / 12.0), false); i++; if (i >= song.notes.length) { stop(); diff --git a/src/main/java/semmiedev/disc_jockey/mixin/ClientWorldMixin.java b/src/main/java/semmiedev/disc_jockey/mixin/ClientWorldMixin.java index bcc122d..a8d8adc 100644 --- a/src/main/java/semmiedev/disc_jockey/mixin/ClientWorldMixin.java +++ b/src/main/java/semmiedev/disc_jockey/mixin/ClientWorldMixin.java @@ -12,17 +12,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import semmiedev.disc_jockey.Main; -import semmiedev.disc_jockey.MonoSoundInstance; +import semmiedev.disc_jockey.OmnidirectionalSoundInstance; @Mixin(ClientWorld.class) public class ClientWorldMixin { @Shadow @Final private MinecraftClient client; @Inject(method = "playSound(DDDLnet/minecraft/sound/SoundEvent;Lnet/minecraft/sound/SoundCategory;FFZJ)V", at = @At("HEAD"), cancellable = true) - private void makeNoteBlocksMono(double x, double y, double z, SoundEvent event, SoundCategory category, float volume, float pitch, boolean useDistance, long seed, CallbackInfo ci) { - if (Main.config.monoNoteBlocks && Main.SONG_PLAYER.running && event.getId().getPath().startsWith("block.note_block")) { + private void makeNoteBlockSoundsOmnidirectional(double x, double y, double z, SoundEvent event, SoundCategory category, float volume, float pitch, boolean useDistance, long seed, CallbackInfo ci) { + if (((Main.config.omnidirectionalNoteBlockSounds && Main.SONG_PLAYER.running) || Main.PREVIEWER.running) && event.getId().getPath().startsWith("block.note_block")) { ci.cancel(); - client.getSoundManager().play(new MonoSoundInstance(event, category, volume, pitch, Random.create(seed))); + client.getSoundManager().play(new OmnidirectionalSoundInstance(event, category, volume, pitch, Random.create(seed))); } } } diff --git a/src/main/java/semmiedev/disc_jockey/mixin/SoundSystemMixin.java b/src/main/java/semmiedev/disc_jockey/mixin/SoundSystemMixin.java new file mode 100644 index 0000000..0e70d64 --- /dev/null +++ b/src/main/java/semmiedev/disc_jockey/mixin/SoundSystemMixin.java @@ -0,0 +1,32 @@ +package semmiedev.disc_jockey.mixin; + +import net.minecraft.client.render.Camera; +import net.minecraft.client.sound.Channel; +import net.minecraft.client.sound.SoundInstance; +import net.minecraft.client.sound.SoundSystem; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import semmiedev.disc_jockey.OmnidirectionalSoundInstance; + +import java.util.Map; + +@Mixin(SoundSystem.class) +public class SoundSystemMixin { + @Shadow @Final private Map sources; + + @Inject(method = "updateListenerPosition", at = @At("TAIL")) + private void updateOmnidirectionalSoundInstances(Camera camera, CallbackInfo ci) { + Vec3d pos = camera.getPos(); + + sources.forEach((soundInstance, sourceManager) -> { + if (!(soundInstance instanceof OmnidirectionalSoundInstance)) return; + + sourceManager.run(source -> source.setPosition(pos)); + }); + } +} diff --git a/src/main/resources/assets/disc_jockey/lang/en_us.json b/src/main/resources/assets/disc_jockey/lang/en_us.json index 553df6c..720e150 100644 --- a/src/main/resources/assets/disc_jockey/lang/en_us.json +++ b/src/main/resources/assets/disc_jockey/lang/en_us.json @@ -42,7 +42,7 @@ "text.autoconfig.disc_jockey.option.disableAsyncPlayback": "Disable Async Playback", "text.autoconfig.disc_jockey.option.disableAsyncPlayback.@Tooltip[0]": "Will force notes to play synchronously with client ticks instead of in a separate thread.", "text.autoconfig.disc_jockey.option.disableAsyncPlayback.@Tooltip[1]": "This can lead to performance loss, especially when you client has low or inconsistent fps but can fix issues when playback does not happen at all.", - "text.autoconfig.disc_jockey.option.monoNoteBlocks": "Non-Directional Note Block Sounds", - "text.autoconfig.disc_jockey.option.monoNoteBlocks.@Tooltip[0]": "Makes all note block sounds when playing a song non-directional, creating a more pleasurable listening experience (clientside)", - "text.autoconfig.disc_jockey.option.monoNoteBlocks.@Tooltip[1]": "If you don't know what that means, I recommend you just try it and hear the difference" + "text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds": "Omnidirectional Note Block Sounds (clientside)", + "text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[0]": "Makes all note block sounds when playing a song omnidirectional, creating a more pleasing listening experience", + "text.autoconfig.disc_jockey.option.omnidirectionalNoteBlockSounds.@Tooltip[1]": "If you don't know what that means, I recommend you just try it and hear the difference" } \ No newline at end of file diff --git a/src/main/resources/disc_jockey.mixins.json b/src/main/resources/disc_jockey.mixins.json index bc1a23f..21654ea 100644 --- a/src/main/resources/disc_jockey.mixins.json +++ b/src/main/resources/disc_jockey.mixins.json @@ -4,7 +4,8 @@ "package": "semmiedev.disc_jockey.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "ClientWorldMixin" + "ClientWorldMixin", + "SoundSystemMixin" ], "injectors": { "defaultRequire": 1