11package vakiliner .musicpack .fabric .mixin ;
22
3- import java . util . Map ;
4- import org . spongepowered . asm . mixin . Mixin ;
5- import org . spongepowered . asm . mixin . gen . Accessor ;
6- import org . spongepowered . asm . mixin . gen . Invoker ;
3+ import vakiliner . musicpack . base . ModConfig ;
4+ import vakiliner . musicpack . fabric . MusicPack ;
5+ import vakiliner . musicpack . fabric . MusicPackSound ;
6+ import net . minecraft . client . Minecraft ;
77import net .minecraft .client .resources .sounds .SoundInstance ;
8+ import net .minecraft .client .sounds .ChannelAccess ;
89import net .minecraft .client .sounds .SoundEngine ;
9- import net .minecraft .client .sounds .ChannelAccess .ChannelHandle ;
10+ import net .minecraft .client .sounds .SoundManager ;
11+ import net .minecraft .resources .ResourceLocation ;
12+ import net .minecraft .sounds .SoundSource ;
13+ import java .util .Map ;
14+ import org .jetbrains .annotations .Nullable ;
15+ import org .spongepowered .asm .mixin .Mixin ;
16+ import org .spongepowered .asm .mixin .Shadow ;
17+ import org .spongepowered .asm .mixin .injection .At ;
18+ import org .spongepowered .asm .mixin .injection .Inject ;
19+ import org .spongepowered .asm .mixin .injection .callback .CallbackInfo ;
1020
1121@ Mixin (SoundEngine .class )
12- public interface SoundEngineMixin {
13- @ Accessor ("instanceToChannel" )
14- Map <SoundInstance , ChannelHandle > getInstanceToChannel ();
22+ abstract class SoundEngineMixin {
23+ @ Shadow
24+ public Map <SoundInstance , ChannelAccess .ChannelHandle > instanceToChannel ;
25+
26+ @ Shadow
27+ public abstract float calculateVolume (SoundInstance soundInstance );
28+
29+ @ Inject (at = @ At ("HEAD" ), method = "play" , cancellable = true )
30+ void play (SoundInstance soundInstance , CallbackInfo callbackInfo ) {
31+ ModConfig config = MusicPack .getConfig ();
32+ if (config .enabled () && soundInstance .getSource () == SoundSource .MUSIC ) {
33+ switch (soundInstance .getLocation ().getNamespace ()) {
34+ case "minecraft" : {
35+ if (config .disableDefaultMusic ()) callbackInfo .cancel ();
36+ break ;
37+ }
38+ case "music" : {
39+ callbackInfo .cancel ();
40+ String [] path = soundInstance .getLocation ().getPath ().split ("\\ ." );
41+ SoundManager soundManager = Minecraft .getInstance ().getSoundManager ();
42+ if (path .length > 0 ) switch (path [0 ]) {
43+ case "seek" :
44+ if (path .length == 1 ) {
45+ if (config .seekersMusicEnabled ()) soundManager .play (MusicPackSound .seek );
46+ }
47+ break ;
48+ case "hide" :
49+ if (path .length > 2 ) {
50+ short tick = Short .parseShort (path [2 ]);
51+ MusicPackSound sound = MusicPackSound .getSound (path [1 ]);
52+ if (sound != null ) {
53+ if (config .hidersMusicEnabled ()) {
54+ if (tick == 1 ) {
55+ if (!soundManager .isActive (MusicPackSound .hideLvl0 )) soundManager .play (MusicPackSound .hideLvl0 .resetVolume ());
56+ if (!soundManager .isActive (MusicPackSound .hideLvl1 )) soundManager .play (MusicPackSound .hideLvl1 .resetVolume ());
57+ if (!soundManager .isActive (MusicPackSound .hideLvl2 )) soundManager .play (MusicPackSound .hideLvl2 .resetVolume ());
58+ if (!soundManager .isActive (MusicPackSound .hideGlow )) soundManager .play (MusicPackSound .hideGlow .resetVolume ());
59+ }
60+ ChannelAccess .ChannelHandle channelHandle = this .instanceToChannel .get (sound );
61+ if (channelHandle != null ) channelHandle .execute ((channel ) -> channel .setVolume (this .calculateVolume (sound .setVolume (((AbstractSoundInstanceAccessor ) soundInstance ).getVolume ()).tick (tick ))));
62+ } else {
63+ if (soundManager .isActive (MusicPackSound .hideLvl0 )) soundManager .stop (MusicPackSound .hideLvl0 );
64+ if (soundManager .isActive (MusicPackSound .hideLvl1 )) soundManager .stop (MusicPackSound .hideLvl1 );
65+ if (soundManager .isActive (MusicPackSound .hideLvl2 )) soundManager .stop (MusicPackSound .hideLvl2 );
66+ if (soundManager .isActive (MusicPackSound .hideGlow )) soundManager .stop (MusicPackSound .hideGlow );
67+ }
68+ }
69+ }
70+ break ;
71+ }
72+ break ;
73+ }
74+ }
75+ }
76+ }
1577
16- @ Invoker ("calculateVolume" )
17- float calculateVolume (SoundInstance soundInstance );
78+ @ Inject (at = @ At (value = "HEAD" ), method = "stop(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/sounds/SoundSource;)V" , cancellable = true )
79+ void stop (@ Nullable ResourceLocation resourceLocation , @ Nullable SoundSource soundSource , CallbackInfo callbackInfo ) {
80+ ModConfig config = MusicPack .getConfig ();
81+ if (config .enabled () && resourceLocation != null && soundSource == SoundSource .MUSIC && resourceLocation .getNamespace ().equals ("music" )) {
82+ callbackInfo .cancel ();
83+ String [] path = resourceLocation .getPath ().split ("\\ ." );
84+ SoundManager soundManager = Minecraft .getInstance ().getSoundManager ();
85+ if (path .length > 0 ) switch (path [0 ]) {
86+ case "seek" :
87+ if (path .length == 1 ) soundManager .stop (MusicPackSound .seek );
88+ break ;
89+ case "hide" :
90+ if (path .length > 2 ) {
91+ short tick = Short .parseShort (path [2 ]);
92+ MusicPackSound sound = MusicPackSound .getSound (path [1 ]);
93+ if (soundManager .isActive (sound )) {
94+ if (config .hidersMusicEnabled ()) {
95+ ChannelAccess .ChannelHandle channelHandle = this .instanceToChannel .get (sound );
96+ if (channelHandle != null && sound .equalsTick (tick )) new Thread (() -> {
97+ try {
98+ Thread .sleep (5 );
99+ } catch (InterruptedException err ) {
100+ err .printStackTrace ();
101+ }
102+ if (sound .equalsTick (tick )) channelHandle .execute ((channel ) -> channel .setVolume (this .calculateVolume (sound .resetVolume ())));
103+ }).start ();
104+ } else soundManager .stop (sound );
105+ }
106+ }
107+ break ;
108+ }
109+ }
110+ }
18111}
0 commit comments