diff --git a/src/main/java/dev/stardust/mixin/PositionedSoundInstanceMixin.java b/src/main/java/dev/stardust/mixin/PositionedSoundInstanceMixin.java deleted file mode 100644 index 8f06335..0000000 --- a/src/main/java/dev/stardust/mixin/PositionedSoundInstanceMixin.java +++ /dev/null @@ -1,53 +0,0 @@ -package dev.stardust.mixin; - -import net.minecraft.sound.SoundEvent; -import dev.stardust.modules.MusicTweaks; -import net.minecraft.sound.SoundCategory; -import org.spongepowered.asm.mixin.Mixin; -import net.minecraft.util.math.random.Random; -import net.minecraft.client.sound.SoundInstance; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import net.minecraft.client.sound.AbstractSoundInstance; -import net.minecraft.client.sound.PositionedSoundInstance; -import meteordevelopment.meteorclient.systems.modules.Modules; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - - -/** - * @author Tas [0xTas] - **/ -@Mixin(PositionedSoundInstance.class) -public class PositionedSoundInstanceMixin extends AbstractSoundInstance { - protected PositionedSoundInstanceMixin(SoundEvent sound, SoundCategory category, Random random) { - super(sound, category, random); - } - - // See MusicTweaks.java - @Inject(method = "music", at = @At("HEAD"), cancellable = true) - private static void mixinMusic(SoundEvent sound, CallbackInfoReturnable cir) { - MusicTweaks tweaks = Modules.get().get(MusicTweaks.class); - if (tweaks == null || !tweaks.isActive()) return; - - float adjustedPitch; - if (tweaks.randomPitch()) { - adjustedPitch = 1.0f + tweaks.getRandomPitch(); - } else { - adjustedPitch = 1.0f + tweaks.getPitchAdjustment(); - } - - if (adjustedPitch == 1.0f) return; - - cir.setReturnValue( - new PositionedSoundInstance( - sound.getId(), - SoundCategory.MUSIC, - 1f, adjustedPitch, - SoundInstance.createRandom(), - false, 0, - AttenuationType.NONE, - 0f, 0f, 0f, true - ) - ); - } -} diff --git a/src/main/java/dev/stardust/mixin/SoundSystemMixin.java b/src/main/java/dev/stardust/mixin/SoundSystemMixin.java index 6d3bf46..c5df1c4 100644 --- a/src/main/java/dev/stardust/mixin/SoundSystemMixin.java +++ b/src/main/java/dev/stardust/mixin/SoundSystemMixin.java @@ -43,15 +43,15 @@ private void mixinTick(CallbackInfo ci) { if (sound == null) continue; String location = sound.getLocation().toString(); - if (!location.startsWith("minecraft:sounds/music/")) continue; + if (!location.startsWith("minecraft:sounds/music/") && !sound.toString().contains("minecraft:records/")) continue; Channel.SourceManager sourceManager = this.sources.get(instance); - songID = location.substring(location.lastIndexOf('/')+1); + songID = location.substring(location.lastIndexOf('/') + 1); - playing = true; if (sourceManager == null) continue; Source source = ((SourceManagerAccessor) sourceManager).getSource(); - if (source == null) continue; + + playing = true; if (tweaks.isActive() && !tweaks.randomPitch()) { this.dirtyPitch = true; source.setPitch(1.0f + tweaks.getPitchAdjustment()); @@ -76,12 +76,14 @@ private void mixinTick(CallbackInfo ci) { this.totalTicksPlaying = 0; } - if (tweaks.isActive() && totalTicksPlaying % 30 == 0 && tweaks.shouldDisplayNowPlaying() && songID != null) { - String songName = tweaks.getSongName(songID); - switch (tweaks.getDisplayMode()) { - case Chat -> tweaks.sendNowPlayingMessage(songName); - // See NarratorManagerMixin.java lol - case Record -> tweaks.getClient().inGameHud.setRecordPlayingOverlay(Text.of(songName)); + if (tweaks.isActive() && this.totalTicksPlaying % 30 == 0 && tweaks.shouldDisplayNowPlaying() && songID != null) { + if (this.totalTicksPlaying <= 90 || !tweaks.shouldFadeOut()) { + String songName = tweaks.getSongName(songID); + switch (tweaks.getDisplayMode()) { + case Chat -> tweaks.sendNowPlayingMessage(songName); + // See NarratorManagerMixin.java lol + case Record -> tweaks.getClient().inGameHud.setRecordPlayingOverlay(Text.of(songName)); + } } } } diff --git a/src/main/java/dev/stardust/mixin/WeightedSoundSetMixin.java b/src/main/java/dev/stardust/mixin/WeightedSoundSetMixin.java new file mode 100644 index 0000000..8d62a2e --- /dev/null +++ b/src/main/java/dev/stardust/mixin/WeightedSoundSetMixin.java @@ -0,0 +1,67 @@ +package dev.stardust.mixin; + +import java.util.List; +import dev.stardust.modules.MusicTweaks; +import net.minecraft.client.sound.Sound; +import net.minecraft.sound.SoundCategory; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import io.netty.util.internal.ThreadLocalRandom; +import org.spongepowered.asm.mixin.injection.At; +import net.minecraft.client.sound.SoundContainer; +import net.minecraft.client.sound.WeightedSoundSet; +import org.spongepowered.asm.mixin.injection.Inject; +import meteordevelopment.meteorclient.systems.modules.Modules; +import net.minecraft.util.math.floatprovider.ConstantFloatProvider; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + + +/** + * @author Tas [0xTas] + **/ +@Mixin(WeightedSoundSet.class) +public abstract class WeightedSoundSetMixin implements SoundContainer { + @Shadow + @Final + private List> sounds; + + // See MusicTweaks.java + @Inject(method = "getSound(Lnet/minecraft/util/math/random/Random;)Lnet/minecraft/client/sound/Sound;", at = @At("HEAD"), cancellable = true) + private void mixinGetSound(net.minecraft.util.math.random.Random random, CallbackInfoReturnable cir) { + MusicTweaks tweaks = Modules.get().get(MusicTweaks.class); + if (tweaks == null || !tweaks.isActive()) return; + + boolean overwrite = false; + for (SoundContainer sound : this.sounds) { + String id = sound.getSound(random).toString(); + + if (id.contains("minecraft:music/")) { + overwrite = true; + break; + } + } + + if (!overwrite) return; + List soundIDs = tweaks.getSoundSet(); + if (soundIDs.isEmpty()) return; + + float adjustedPitch; + if (tweaks.randomPitch()) { + adjustedPitch = 1.0f + tweaks.getRandomPitch(); + } else { + adjustedPitch = 1.0f + tweaks.getPitchAdjustment(); + } + float adjustedVolume = tweaks.getClient().options.getSoundVolume(SoundCategory.MUSIC) + tweaks.getVolumeAdjustment(); + + cir.setReturnValue( + new Sound( + soundIDs.get(ThreadLocalRandom.current().nextInt(soundIDs.size())), + ConstantFloatProvider.create(adjustedVolume), + ConstantFloatProvider.create(adjustedPitch), + this.getWeight(), Sound.RegistrationType.SOUND_EVENT, + true, true, 16 + ) + ); + } +} diff --git a/src/main/java/dev/stardust/modules/MusicTweaks.java b/src/main/java/dev/stardust/modules/MusicTweaks.java index f0ce313..05ecb7f 100644 --- a/src/main/java/dev/stardust/modules/MusicTweaks.java +++ b/src/main/java/dev/stardust/modules/MusicTweaks.java @@ -27,6 +27,13 @@ public class MusicTweaks extends Module { public MusicTweaks() { super(Stardust.CATEGORY, "MusicTweaks", "Allows you to fuck with the background music."); this.runInMainMenu = true; + this.sgOverworldSoundtrack.sectionExpanded = false; + this.sgCreativeSoundtrack.sectionExpanded = false; + this.sgUnderwaterSoundtrack.sectionExpanded = false; + this.sgNetherSoundtrack.sectionExpanded = false; + this.sgEndSoundtrack.sectionExpanded = false; + this.sgRecordsSoundtrack.sectionExpanded = false; + this.sgMenuSoundtrack.sectionExpanded = false; } public enum DisplayType { @@ -36,73 +43,24 @@ public enum DisplayType { private final SettingGroup sgPitch = settings.createGroup("Pitch"); private final SettingGroup sgVolume = settings.createGroup("Volume"); private final SettingGroup sgCooldown = settings.createGroup("Cooldown"); - private final SettingGroup sgTypes = settings.createGroup("Soundtracks"); private final SettingGroup sgNowPlaying = settings.createGroup("Now Playing"); + private final SettingGroup sgOverworldSoundtrack = settings.createGroup("Overworld Soundtrack"); + private final SettingGroup sgCreativeSoundtrack = settings.createGroup("Creative Soundtrack"); + private final SettingGroup sgUnderwaterSoundtrack = settings.createGroup("Underwater Soundtrack"); + private final SettingGroup sgNetherSoundtrack = settings.createGroup("Nether Soundtrack"); + private final SettingGroup sgEndSoundtrack = settings.createGroup("End Soundtrack"); + private final SettingGroup sgRecordsSoundtrack = settings.createGroup("Music Discs"); + private final SettingGroup sgMenuSoundtrack = settings.createGroup("Menu Soundtrack"); - private final Setting gameMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Survival") - .description("Plays songs from the overworld survival gamemode soundtrack.") - .defaultValue(true) - .build() - ); - private final Setting creativeMusic = sgTypes.add( + private final Setting startOnEnable = sgNowPlaying.add( new BoolSetting.Builder() - .name("Creative") - .description("Plays songs from the creative gamemode soundtrack.") + .name("Start on Enable") + .description("Start playing music when enabling the module. Won't overwrite a currently-playing song.") .defaultValue(true) .build() ); - private final Setting underwaterMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Underwater") - .description("Plays songs from the underwater soundtrack.") - .defaultValue(true) - .build() - ); - - private final Setting netherMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Nether") - .description("Plays songs from the Nether dimension soundtrack.") - .defaultValue(false) - .build() - ); - - private final Setting endMusic = sgTypes.add( - new BoolSetting.Builder() - .name("End") - .description("Plays the End Dimension soundtrack.") - .defaultValue(false) - .build() - ); - - private final Setting bossMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Dragon") - .description("Plays the End Dragon boss soundtrack.") - .defaultValue(false) - .build() - ); - - private final Setting creditsMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Credits") - .description("Plays the end credits soundtrack.") - .defaultValue(false) - .build() - ); - - private final Setting menuMusic = sgTypes.add( - new BoolSetting.Builder() - .name("Menu") - .description("Plays songs from the main menu soundtrack.") - .defaultValue(false) - .build() - ); - private final Setting stopOnDisable = sgNowPlaying.add( new BoolSetting.Builder() .name("Stop on Disable") @@ -119,6 +77,15 @@ public enum DisplayType { .build() ); + private final Setting fadeOut = sgNowPlaying.add( + new BoolSetting.Builder() + .name("Fade Out Display") + .description("Fade out the display instead of keeping it active for the duration of the song.") + .visible(displayNowPlaying::get) + .defaultValue(false) + .build() + ); + private final Setting displayTypeSetting = sgNowPlaying.add( new EnumSetting.Builder() .name("Display Mode") @@ -140,7 +107,7 @@ public enum DisplayType { .name("Song Delay Seconds") .description("Desired cooldown between songs. Will apply after next song if not currently playing (or module toggle.)") .range(0, 10000) - .sliderRange(0, 600) + .sliderRange(0, 2400) .defaultValue(300) .visible(overrideDelayMode::get) .build() @@ -152,7 +119,7 @@ public enum DisplayType { .description("Minimum desired cooldown between songs (in seconds.)") .range(0, 10000) .sliderRange(0, 1200) - .defaultValue(420) + .defaultValue(600) .visible(() -> !overrideDelayMode.get()) .build() ); @@ -187,8 +154,8 @@ public enum DisplayType { private final Setting pitchAdjustment = sgPitch.add( new IntSetting.Builder() - .name("Song Pitch % Adjustment") - .description("Desired pitch adjustment %.") + .name("Song Pitch Adjustment") + .description("Desired pitch adjustment.") .range(-500, 500) .sliderRange(-250, 250) .defaultValue(0) @@ -236,7 +203,479 @@ public enum DisplayType { ); - // See MusicTrackerMixin.java && SoundSystemMixin.java && PositionedSoundInstanceMixin.java + // Soundtracks + private final Setting minecraft = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Minecraft") + .description("calm1.ogg") + .defaultValue(true) + .build() + ); + private final Setting clark = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Clark") + .description("calm2.ogg") + .defaultValue(true) + .build() + ); + private final Setting sweden = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Sweden") + .description("calm3.ogg") + .defaultValue(true) + .build() + ); + private final Setting subwooferLullaby = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Subwoofer Lullaby") + .description("hal1.ogg") + .defaultValue(true) + .build() + ); + private final Setting livingMice = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Living Mice") + .description("hal2.ogg") + .defaultValue(true) + .build() + ); + private final Setting haggstrom = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Haggstrom") + .description("hal3.ogg") + .defaultValue(true) + .build() + ); + private final Setting danny = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Danny") + .description("hal4.ogg") + .defaultValue(true) + .build() + ); + private final Setting key = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Key") + .description("nuance1.ogg") + .defaultValue(true) + .build() + ); + private final Setting oxygene = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Oxygene") + .description("nuance2.ogg") + .defaultValue(true) + .build() + ); + private final Setting dryHands = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Dry Hands") + .description("piano1.ogg") + .defaultValue(true) + .build() + ); + private final Setting wetHands = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Wet Hands") + .description("piano2.ogg") + .defaultValue(true) + .build() + ); + private final Setting miceOnVenus = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Mice on Venus") + .description("piano3.ogg") + .defaultValue(true) + .build() + ); + private final Setting aerie = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Aerie") + .description("aerie.ogg") + .defaultValue(false) + .build() + ); + private final Setting ancestry = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Ancestry") + .description("ancestry.ogg") + .defaultValue(false) + .build() + ); + private final Setting aFamiliarRoom = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Aaron Cherof / A Familiar Room") + .description("a_familiar_room.ogg") + .defaultValue(false) + .build() + ); + private final Setting anOrdinaryDay = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Kumi Tanioka / An Ordinary Day") + .description("an_ordinary_day.ogg") + .defaultValue(false) + .build() + ); + private final Setting bromeliad = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Aaron Cherof / Bromeliad") + .description("bromeliad.ogg") + .defaultValue(true) + .build() + ); + private final Setting comfortingMemories = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Kumi Tanioka / Comforting Memories") + .description("comforting_memories.ogg") + .defaultValue(false) + .build() + ); + private final Setting crescentDunes = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Aaron Cherof / Crescent Dunes") + .description("crescent_dunes.ogg") + .defaultValue(false) + .build() + ); + private final Setting echoInTheWind = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Aaron Cherof / Echo in the Wind") + .description("echo_in_the_wind.ogg") + .defaultValue(false) + .build() + ); + private final Setting firebugs = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Firebugs") + .description("firebugs.ogg") + .defaultValue(true) + .build() + ); + private final Setting floatingDream = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Kumi Tanioka / Floating Dream") + .description("floating_dream.ogg") + .defaultValue(false) + .build() + ); + private final Setting infiniteAmethyst = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Infinite Amethyst") + .description("infinite_amethyst.ogg") + .defaultValue(false) + .build() + ); + private final Setting labyrinthine = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Labyrinthine") + .description("labyrinthine.ogg") + .defaultValue(false) + .build() + ); + private final Setting leftToBloom = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Left to Bloom") + .description("left_to_bloom.ogg") + .defaultValue(false) + .build() + ); + private final Setting oneMoreDay = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / One More Day") + .description("one_more_day.ogg") + .defaultValue(false) + .build() + ); + private final Setting standTall = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Stand Tall") + .description("stand_tall.ogg") + .defaultValue(false) + .build() + ); + private final Setting wending = sgOverworldSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Wending") + .description("wending.ogg") + .defaultValue(true) + .build() + ); + private final Setting biomeFest = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Biome Fest") + .description("creative1.ogg") + .defaultValue(false) + .build() + ); + private final Setting blindSpots = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Blind Spots") + .description("creative2.ogg") + .defaultValue(true) + .build() + ); + private final Setting hauntMuskie = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Haunt Muskie") + .description("creative3.ogg") + .defaultValue(true) + .build() + ); + private final Setting ariaMath = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Aria Math") + .description("creative4.ogg") + .defaultValue(true) + .build() + ); + private final Setting dreiton = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Dreiton") + .description("creative5.ogg") + .defaultValue(false) + .build() + ); + private final Setting tasWell = sgCreativeSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Taswell") + .description("creative6.ogg") + .defaultValue(true) + .build() + ); + private final Setting axolotl = sgUnderwaterSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Axolotl") + .description("axolotl.ogg") + .defaultValue(true) + .build() + ); + private final Setting dragonFish = sgUnderwaterSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Dragon Fish") + .description("dragon_fish.ogg") + .defaultValue(true) + .build() + ); + private final Setting shuniji = sgUnderwaterSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Shuniji") + .description("shuniji.ogg") + .defaultValue(true) + .build() + ); + private final Setting concreteHalls = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Concrete Halls") + .description("nether1.ogg") + .defaultValue(false) + .build() + ); + private final Setting deadVoxel = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Dead Voxel") + .description("nether2.ogg") + .defaultValue(false) + .build() + ); + private final Setting warmth = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Warmth") + .description("nether3.ogg") + .defaultValue(false) + .build() + ); + private final Setting balladOfTheCats = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Ballad of the Cats") + .description("nether4.ogg") + .defaultValue(false) + .build() + ); + private final Setting chrysopoeia = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Chrysopoeia") + .description("chrysopoeia.ogg") + .defaultValue(false) + .build() + ); + private final Setting rubedo = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Rubedo") + .description("rubedo.ogg") + .defaultValue(false) + .build() + ); + private final Setting soBelow = sgNetherSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / So Below") + .description("so_below.ogg") + .defaultValue(false) + .build() + ); + private final Setting theEnd = sgEndSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / The End") + .description("end.ogg") + .defaultValue(false) + .build() + ); + private final Setting boss = sgEndSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Boss") + .description("boss.ogg") + .defaultValue(false) + .build() + ); + private final Setting alpha = sgEndSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Alpha") + .description("credits.ogg") + .defaultValue(false) + .build() + ); + private final Setting record5 = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("Samuel Aberg / 5") + .description("Music Disc: 5") + .defaultValue(false) + .build() + ); + private final Setting record11 = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / 11") + .description("Music Disc: 11") + .defaultValue(false) + .build() + ); + private final Setting record13 = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / 13") + .description("Music Disc: 13") + .defaultValue(false) + .build() + ); + private final Setting recordCat = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Cat") + .description("Music Disc: Cat") + .defaultValue(true) + .build() + ); + private final Setting recordBlocks = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Blocks") + .description("Music Disc: Blocks") + .defaultValue(true) + .build() + ); + private final Setting recordChirp = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Chirp") + .description("Music Disc: Chirp") + .defaultValue(false) + .build() + ); + private final Setting recordFar = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Far") + .description("Music Disc: Far") + .defaultValue(false) + .build() + ); + private final Setting recordMall = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Mall") + .description("Music Disc: Mall") + .defaultValue(true) + .build() + ); + private final Setting recordMellohi = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Mellohi") + .description("Music Disc: Mellohi") + .defaultValue(false) + .build() + ); + private final Setting recordStal = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Stal") + .description("Music Disc: Stal") + .defaultValue(false) + .build() + ); + private final Setting recordStrad = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Strad") + .description("Music Disc: Strad") + .defaultValue(false) + .build() + ); + private final Setting recordWard = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Ward") + .description("Music Disc: Ward") + .defaultValue(false) + .build() + ); + private final Setting recordWait = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Wait") + .description("Music Disc: Wait") + .defaultValue(false) + .build() + ); + private final Setting recordOtherside = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Otherside") + .description("Music Disc: Otherside") + .defaultValue(false) + .build() + ); + private final Setting recordPigstep = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("Lena Raine / Pigstep") + .description("Music Disc: Pigstep") + .defaultValue(false) + .build() + ); + private final Setting recordRelic = sgRecordsSoundtrack.add( + new BoolSetting.Builder() + .name("Aaron Cherof / Relic") + .description("Music Disc: Relic") + .defaultValue(false) + .build() + ); + private final Setting mutation = sgMenuSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Mutation") + .description("menu1.ogg") + .defaultValue(false) + .build() + ); + private final Setting moogCity2 = sgMenuSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Moog City 2") + .description("menu2.ogg") + .defaultValue(false) + .build() + ); + private final Setting beginning2 = sgMenuSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Beginning 2") + .description("menu3.ogg") + .defaultValue(false) + .build() + ); + private final Setting floatingTrees = sgMenuSoundtrack.add( + new BoolSetting.Builder() + .name("C418 / Floating Trees") + .description("menu4.ogg") + .defaultValue(false) + .build() + ); + + + // See MusicTrackerMixin.java && SoundSystemMixin.java && WeightedSoundSetMixin.java // && MinecraftClientMixin.java @Nullable public MusicSound getTypes() { @@ -257,28 +696,63 @@ public MusicSound getTypes() { if (max <= min) max = min + 1; List types = new ArrayList<>(); - if (gameMusic.get()) { + if (minecraft.get() || clark.get() || sweden.get() ||subwooferLullaby.get() || livingMice.get() || haggstrom.get() + || danny.get() || key.get() || oxygene.get() || dryHands.get() || wetHands.get() || miceOnVenus.get()) { types.add(new MusicSound(SoundEvents.MUSIC_GAME, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_FOREST, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_DRIPSTONE_CAVES, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (aerie.get() || firebugs.get() || labyrinthine.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_SWAMP, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (aFamiliarRoom.get() || anOrdinaryDay.get() || echoInTheWind.get() || floatingDream.get() || leftToBloom.get() + || oneMoreDay.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_LUSH_CAVES, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (wending.get() || standTall.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_STONY_PEAKS, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (ancestry.get()) { types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_DEEP_DARK, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_CHERRY_GROVE, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_OLD_GROWTH_TAIGA, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_JAGGED_PEAKS, min, ThreadLocalRandom.current().nextInt(min, max), false)); } - if (netherMusic.get()) { + if (infiniteAmethyst.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_GROVE, min, ThreadLocalRandom.current().nextInt(min, max), false)); + types.add(new MusicSound(SoundEvents.MUSIC_OVERWORLD_DRIPSTONE_CAVES, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (axolotl.get() || dragonFish.get() || shuniji.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_UNDER_WATER, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (concreteHalls.get() || deadVoxel.get() || warmth.get() || balladOfTheCats.get()) { types.add(new MusicSound(SoundEvents.MUSIC_NETHER_BASALT_DELTAS, min, ThreadLocalRandom.current().nextInt(min, max), false)); types.add(new MusicSound(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST, min, ThreadLocalRandom.current().nextInt(min, max), false)); types.add(new MusicSound(SoundEvents.MUSIC_NETHER_NETHER_WASTES, min, ThreadLocalRandom.current().nextInt(min, max), false)); - types.add(new MusicSound(SoundEvents.MUSIC_NETHER_WARPED_FOREST, min, ThreadLocalRandom.current().nextInt(min, max), false)); types.add(new MusicSound(SoundEvents.MUSIC_NETHER_SOUL_SAND_VALLEY, min, ThreadLocalRandom.current().nextInt(min, max), false)); } - if (creativeMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_CREATIVE, min, ThreadLocalRandom.current().nextInt(min, max), false)); - if (underwaterMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_UNDER_WATER, min, ThreadLocalRandom.current().nextInt(min, max), false)); - if (endMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_END, min, ThreadLocalRandom.current().nextInt(min, max), false)); - if (menuMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_MENU, min, ThreadLocalRandom.current().nextInt(min, max), false)); - if (creditsMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_CREDITS, min, ThreadLocalRandom.current().nextInt(min, max), false)); - if (bossMusic.get()) types.add(new MusicSound(SoundEvents.MUSIC_DRAGON, min, ThreadLocalRandom.current().nextInt(min, max), false)); + if (chrysopoeia.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (rubedo.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_NETHER_NETHER_WASTES, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (soBelow.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_NETHER_BASALT_DELTAS, min, ThreadLocalRandom.current().nextInt(min, max), false)); + types.add(new MusicSound(SoundEvents.MUSIC_NETHER_SOUL_SAND_VALLEY, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (bromeliad.get() || crescentDunes.get() || mutation.get() || moogCity2.get() || beginning2.get() || floatingTrees.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_MENU, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (alpha.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_CREDITS, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (theEnd.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_END, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (boss.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_DRAGON, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } + if (record5.get() || record11.get() || record13.get() || recordCat.get() || recordChirp.get() || recordBlocks.get() + || recordFar.get() || recordMall.get() || recordMellohi.get() || recordStal.get() || recordStrad.get() + || recordWard.get() || recordWait.get() || recordOtherside.get() || recordPigstep.get() || recordRelic.get()) { + types.add(new MusicSound(SoundEvents.MUSIC_GAME, min, ThreadLocalRandom.current().nextInt(min, max), false)); + } MusicSound type; if (!types.isEmpty()) { @@ -349,12 +823,101 @@ public String getSongName(String songID) { case "menu3.ogg" -> songName = "C418 - Beginning 2"; case "menu4.ogg" -> songName = "C418 - Floating Trees"; case "credits.ogg" -> songName = "C418 - Alpha"; + case "5.ogg" -> songName = "Samuel Aberg - 5"; + case "11.ogg" -> songName = "C418 - 11"; + case "13.ogg" -> songName = "C418 - 13"; + case "cat.ogg" -> songName = "C418 - Cat"; + case "blocks.ogg" -> songName = "C418 - Blocks"; + case "chirp.ogg" -> songName = "C418 - Chirp"; + case "far.ogg" -> songName = "C418 - Far"; + case "mall.ogg" -> songName = "C418 - Mall"; + case "mellohi.ogg" -> songName = "C418 - Mellohi"; + case "stal.ogg" -> songName = "C418 - Stal"; + case "strad.ogg" -> songName = "C418 - Strad"; + case "ward.ogg" -> songName = "C418 - Ward"; + case "wait.ogg" -> songName = "C418 - Wait"; + case "otherside.ogg" -> songName = "Lena Raine - Otherside"; + case "pigstep.ogg" -> songName = "Lena Raine - Pigstep"; + case "relic.ogg" -> songName = "Aaron Cherof - Relic"; default -> songName = "Unknown Track"; } return songName; } + public List getSoundSet() { + List ids = new ArrayList<>(); + if (minecraft.get()) ids.add("minecraft:music/game/calm1"); + if (clark.get()) ids.add("minecraft:music/game/calm2"); + if (sweden.get()) ids.add("minecraft:music/game/calm3"); + if (biomeFest.get()) ids.add("minecraft:music/game/creative/creative1"); + if (blindSpots.get()) ids.add("minecraft:music/game/creative/creative2"); + if (hauntMuskie.get()) ids.add("minecraft:music/game/creative/creative3"); + if (ariaMath.get()) ids.add("minecraft:music/game/creative/creative4"); + if (dreiton.get()) ids.add("minecraft:music/game/creative/creative5"); + if (tasWell.get()) ids.add("minecraft:music/game/creative/creative6"); + if (subwooferLullaby.get()) ids.add("minecraft:music/game/hal1"); + if (livingMice.get()) ids.add("minecraft:music/game/hal2"); + if (haggstrom.get()) ids.add("minecraft:music/game/hal3"); + if (danny.get()) ids.add("minecraft:music/game/hal4"); + if (key.get()) ids.add("minecraft:music/game/nuance1"); + if (oxygene.get()) ids.add("minecraft:music/game/nuance2"); + if (dryHands.get()) ids.add("minecraft:music/game/piano1"); + if (wetHands.get()) ids.add("minecraft:music/game/piano2"); + if (miceOnVenus.get()) ids.add("minecraft:music/game/piano3"); + if (aerie.get()) ids.add("minecraft:music/game/swamp/aerie"); + if (bromeliad.get()) ids.add("minecraft:music/game/bromeliad"); + if (firebugs.get()) ids.add("minecraft:music/game/swamp/firebugs"); + if (leftToBloom.get()) ids.add("minecraft:music/game/left_to_bloom"); + if (axolotl.get()) ids.add("minecraft:music/game/water/axolotl"); + if (dragonFish.get()) ids.add("minecraft:music/game/water/dragon_fish"); + if (shuniji.get()) ids.add("minecraft:music/game/water/shuniji"); + if (labyrinthine.get()) ids.add("minecraft:music/game/swamp/labyrinthine"); + if (echoInTheWind.get()) ids.add("minecraft:music/game/echo_in_the_wind"); + if (standTall.get()) ids.add("minecraft:music/game/stand_tall"); + if (ancestry.get()) ids.add("minecraft:music/game/ancestry"); + if (aFamiliarRoom.get()) ids.add("minecraft:music/game/a_familiar_room"); + if (oneMoreDay.get()) ids.add("minecraft:music/game/one_more_day"); + if (wending.get()) ids.add("minecraft:music/game/wending"); + if (infiniteAmethyst.get()) ids.add("minecraft:music/game/infinite_amethyst"); + if (anOrdinaryDay.get()) ids.add("minecraft:music/game/an_ordinary_day"); + if (crescentDunes.get()) ids.add("minecraft:music/game/crescent_dunes"); + if (floatingDream.get()) ids.add("minecraft:music/game/floating_dream"); + if (comfortingMemories.get()) ids.add("minecraft:music/game/comforting_memories"); + if (mutation.get()) ids.add("minecraft:music/menu/menu1"); + if (moogCity2.get()) ids.add("minecraft:music/menu/menu2"); + if (beginning2.get()) ids.add("minecraft:music/menu/menu3"); + if (floatingTrees.get()) ids.add("minecraft:music/menu/menu4"); + if (alpha.get()) ids.add("minecraft:music/game/end/credits"); + if (theEnd.get()) ids.add("minecraft:music/game/end/end"); + if (boss.get()) ids.add("minecraft:music/game/end/boss"); + if (soBelow.get()) ids.add("minecraft:music/game/nether/soulsand_valley/so_below"); + if (rubedo.get()) ids.add("minecraft:music/game/nether/nether_wastes/rubedo"); + if (chrysopoeia.get()) ids.add("minecraft:music/game/nether/crimson_forest/chrysopoeia"); + if (concreteHalls.get()) ids.add("minecraft:music/game/nether/nether1"); + if (deadVoxel.get()) ids.add("minecraft:music/game/nether/nether2"); + if (warmth.get()) ids.add("minecraft:music/game/nether/nether3"); + if (balladOfTheCats.get()) ids.add("minecraft:music/game/nether/nether4"); + if (record5.get()) ids.add("minecraft:records/5"); + if (record11.get()) ids.add("minecraft:records/11"); + if (record13.get()) ids.add("minecraft:records/13"); + if (recordCat.get()) ids.add("minecraft:records/cat"); + if (recordBlocks.get()) ids.add("minecraft:records/blocks"); + if (recordChirp.get()) ids.add("minecraft:records/chirp"); + if (recordFar.get()) ids.add("minecraft:records/far"); + if (recordMall.get()) ids.add("minecraft:records/mall"); + if (recordMellohi.get()) ids.add("minecraft:records/mellohi"); + if (recordStal.get()) ids.add("minecraft:records/stal"); + if (recordStrad.get()) ids.add("minecraft:records/strad"); + if (recordWard.get()) ids.add("minecraft:records/ward"); + if (recordWait.get()) ids.add("minecraft:records/wait"); + if (recordOtherside.get()) ids.add("minecraft:records/otherside"); + if (recordPigstep.get()) ids.add("minecraft:records/pigstep"); + if (recordRelic.get()) ids.add("minecraft:records/relic"); + + return ids; + } + public float getNextPitchStep(float currentPitch) { if (this.lastDirection == null) { this.lastDirection = PitchDirection.Descending; @@ -393,12 +956,20 @@ public float getNextPitchStep(float currentPitch) { public void sendNowPlayingMessage(String songName) { if (mc.player == null) return; - ((IChatHud) mc.inGameHud.getChatHud()).meteor$add(Text.of("§8<"+ StardustUtil.rCC()+"§o✨§r§8> §2§oNow Playing§r§7: §5§o"+songName+"§r§7."), songName.hashCode()); + String[] pieces = songName.split(" - "); + ((IChatHud) mc.inGameHud.getChatHud()).meteor$add( + Text.of("§8<"+this.rcc+"§o✨§r§8> §2§oNow Playing§r§8: §7§o"+pieces[0]+" §8- "+this.rcc+"§o"+pieces[1]+"§r§8."), + songName.hashCode() + ); } + public void nullifyCurrentType() { + this.currentType = null; + this.rcc = StardustUtil.rCC(); + } public MinecraftClient getClient() { return this.mc; } + public boolean shouldFadeOut() { return fadeOut.get(); } public boolean randomPitch() { return randomPitch.get(); } - public void nullifyCurrentType() { this.currentType = null; } public boolean trippyPitch() { return trippyPitchSetting.get(); } public float getVolumeAdjustment() { return volume.get() / 100f; } public boolean overrideDelay() { return overrideDelayMode.get(); } @@ -417,18 +988,20 @@ private enum PitchDirection { @Nullable private PitchDirection lastDirection = null; + private String rcc = StardustUtil.rCC(); + @Override public void onActivate() { MusicSound type = this.getTypes(); - if (type == null) return; + if (type == null || !startOnEnable.get()) return; if (((MusicTrackerAccessor) mc.getMusicTracker()).getCurrent() == null) mc.getMusicTracker().play(type); } @Override public void onDeactivate() { if (stopOnDisable.get()) mc.getMusicTracker().stop(); - this.currentType = null; + this.nullifyCurrentType(); } @EventHandler diff --git a/src/main/resources/stardust.mixins.json b/src/main/resources/stardust.mixins.json index de54ad7..74d17d0 100644 --- a/src/main/resources/stardust.mixins.json +++ b/src/main/resources/stardust.mixins.json @@ -15,9 +15,9 @@ "MusicTrackerAccessor", "MusicTrackerMixin", "NarratorManagerMixin", - "PositionedSoundInstanceMixin", "SoundSystemMixin", "SourceManagerAccessor", + "WeightedSoundSetMixin", "WrittenBookContentsAccessor" ], "injectors": {