    001    package net.minecraft.src;
    002
    003    import net.minecraftforge.client.*;
    004    import net.minecraftforge.client.event.sound.*;
    005    import net.minecraftforge.common.MinecraftForge;
    006    import static net.minecraftforge.client.event.sound.SoundEvent.*;
    007    import cpw.mods.fml.common.Side;
    008    import cpw.mods.fml.common.asm.SideOnly;
    009    import java.io.File;
    010    import java.util.HashSet;
    011    import java.util.Iterator;
    012    import java.util.Random;
    013    import java.util.Set;
    014    import paulscode.sound.SoundSystem;
    015    import paulscode.sound.SoundSystemConfig;
    016    import paulscode.sound.codecs.CodecJOrbis;
    017    import paulscode.sound.codecs.CodecWav;
    018    import paulscode.sound.libraries.LibraryLWJGLOpenAL;
    019
    020    @SideOnly(Side.CLIENT)
    021    public class SoundManager
    022    {
    023        /** A reference to the sound system. */
    024        public static SoundSystem sndSystem;
    025
    026        /** Sound pool containing sounds. */
    027        public SoundPool soundPoolSounds = new SoundPool();
    028
    029        /** Sound pool containing streaming audio. */
    030        public SoundPool soundPoolStreaming = new SoundPool();
    031
    032        /** Sound pool containing music. */
    033        public SoundPool soundPoolMusic = new SoundPool();
    034
    035        /**
    036         * The last ID used when a sound is played, passed into SoundSystem to give active sounds a unique ID
    037         */
    038        private int latestSoundID = 0;
    039
    040        /** A reference to the game settings. */
    041        private GameSettings options;
    042        private Set field_82470_g = new HashSet();
    043
    044        /** Set to true when the SoundManager has been initialised. */
    045        private static boolean loaded = false;
    046
    047        /** RNG. */
    048        private Random rand = new Random();
    049        private int ticksBeforeMusic;
    050
    051        public static int MUSIC_INTERVAL = 12000;
    052
    053        public SoundManager()
    054        {
    055            this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL);
    056        }
    057
    058        /**
    059         * Used for loading sound settings from GameSettings
    060         */
    061        public void loadSoundSettings(GameSettings par1GameSettings)
    062        {
    063            this.soundPoolStreaming.isGetRandomSound = false;
    064            this.options = par1GameSettings;
    065
    066            if (!loaded && (par1GameSettings == null || par1GameSettings.soundVolume != 0.0F || par1GameSettings.musicVolume != 0.0F))
    067            {
    068                this.tryToSetLibraryAndCodecs();
    069            }
    070            ModCompatibilityClient.audioModLoad(this);
    071            MinecraftForge.EVENT_BUS.post(new SoundLoadEvent(this));
    072        }
    073
    074        /**
    075         * Tries to add the paulscode library and the relevant codecs. If it fails, the volumes (sound and music) will be
    076         * set to zero in the options file.
    077         */
    078        private void tryToSetLibraryAndCodecs()
    079        {
    080            try
    081            {
    082                float var1 = this.options.soundVolume;
    083                float var2 = this.options.musicVolume;
    084                this.options.soundVolume = 0.0F;
    085                this.options.musicVolume = 0.0F;
    086                this.options.saveOptions();
    087                SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class);
    088                SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
    089                SoundSystemConfig.setCodec("mus", CodecMus.class);
    090                SoundSystemConfig.setCodec("wav", CodecWav.class);
    091                ModCompatibilityClient.audioModAddCodecs();
    092                MinecraftForge.EVENT_BUS.post(new SoundSetupEvent(this));
    093                sndSystem = new SoundSystem();
    094                this.options.soundVolume = var1;
    095                this.options.musicVolume = var2;
    096                this.options.saveOptions();
    097            }
    098            catch (Throwable var3)
    099            {
    100                var3.printStackTrace();
    101                System.err.println("error linking with the LibraryJavaSound plug-in");
    102            }
    103
    104            loaded = true;
    105        }
    106
    107        /**
    108         * Called when one of the sound level options has changed.
    109         */
    110        public void onSoundOptionsChanged()
    111        {
    112            if (!loaded && (this.options.soundVolume != 0.0F || this.options.musicVolume != 0.0F))
    113            {
    114                this.tryToSetLibraryAndCodecs();
    115            }
    116
    117            if (loaded)
    118            {
    119                if (this.options.musicVolume == 0.0F)
    120                {
    121                    sndSystem.stop("BgMusic");
    122                }
    123                else
    124                {
    125                    sndSystem.setVolume("BgMusic", this.options.musicVolume);
    126                }
    127            }
    128        }
    129
    130        /**
    131         * Called when Minecraft is closing down.
    132         */
    133        public void closeMinecraft()
    134        {
    135            if (loaded)
    136            {
    137                sndSystem.cleanup();
    138            }
    139        }
    140
    141        /**
    142         * Adds a sounds with the name from the file. Args: name, file
    143         */
    144        public void addSound(String par1Str, File par2File)
    145        {
    146            this.soundPoolSounds.addSound(par1Str, par2File);
    147        }
    148
    149        /**
    150         * Adds an audio file to the streaming SoundPool.
    151         */
    152        public void addStreaming(String par1Str, File par2File)
    153        {
    154            this.soundPoolStreaming.addSound(par1Str, par2File);
    155        }
    156
    157        /**
    158         * Adds an audio file to the music SoundPool.
    159         */
    160        public void addMusic(String par1Str, File par2File)
    161        {
    162            this.soundPoolMusic.addSound(par1Str, par2File);
    163        }
    164
    165        /**
    166         * If its time to play new music it starts it up.
    167         */
    168        public void playRandomMusicIfReady()
    169        {
    170            if (loaded && this.options.musicVolume != 0.0F)
    171            {
    172                if (!sndSystem.playing("BgMusic") && !sndSystem.playing("streaming"))
    173                {
    174                    if (this.ticksBeforeMusic > 0)
    175                    {
    176                        --this.ticksBeforeMusic;
    177                        return;
    178                    }
    179
    180                    SoundPoolEntry var1 = this.soundPoolMusic.getRandomSound();
    181                    var1 = ModCompatibilityClient.audioModPickBackgroundMusic(this, var1);
    182                    var1 = SoundEvent.getResult(new PlayBackgroundMusicEvent(this, var1));
    183
    184                    if (var1 != null)
    185                    {
    186                        this.ticksBeforeMusic = this.rand.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL;
    187                        sndSystem.backgroundMusic("BgMusic", var1.soundUrl, var1.soundName, false);
    188                        sndSystem.setVolume("BgMusic", this.options.musicVolume);
    189                        sndSystem.play("BgMusic");
    190                    }
    191                }
    192            }
    193        }
    194
    195        /**
    196         * Sets the listener of sounds
    197         */
    198        public void setListener(EntityLiving par1EntityLiving, float par2)
    199        {
    200            if (loaded && this.options.soundVolume != 0.0F)
    201            {
    202                if (par1EntityLiving != null)
    203                {
    204                    float var3 = par1EntityLiving.prevRotationYaw + (par1EntityLiving.rotationYaw - par1EntityLiving.prevRotationYaw) * par2;
    205                    double var4 = par1EntityLiving.prevPosX + (par1EntityLiving.posX - par1EntityLiving.prevPosX) * (double)par2;
    206                    double var6 = par1EntityLiving.prevPosY + (par1EntityLiving.posY - par1EntityLiving.prevPosY) * (double)par2;
    207                    double var8 = par1EntityLiving.prevPosZ + (par1EntityLiving.posZ - par1EntityLiving.prevPosZ) * (double)par2;
    208                    float var10 = MathHelper.cos(-var3 * 0.017453292F - (float)Math.PI);
    209                    float var11 = MathHelper.sin(-var3 * 0.017453292F - (float)Math.PI);
    210                    float var12 = -var11;
    211                    float var13 = 0.0F;
    212                    float var14 = -var10;
    213                    float var15 = 0.0F;
    214                    float var16 = 1.0F;
    215                    float var17 = 0.0F;
    216                    sndSystem.setListenerPosition((float)var4, (float)var6, (float)var8);
    217                    sndSystem.setListenerOrientation(var12, var13, var14, var15, var16, var17);
    218                }
    219            }
    220        }
    221
    222        public void func_82464_d()
    223        {
    224            Iterator var1 = this.field_82470_g.iterator();
    225
    226            while (var1.hasNext())
    227            {
    228                String var2 = (String)var1.next();
    229                sndSystem.stop(var2);
    230            }
    231
    232            this.field_82470_g.clear();
    233        }
    234
    235        public void playStreaming(String par1Str, float par2, float par3, float par4)
    236        {
    237            if (loaded && (this.options.soundVolume != 0.0F || par1Str == null))
    238            {
    239                String var5 = "streaming";
    240
    241                if (sndSystem.playing(var5))
    242                {
    243                    sndSystem.stop(var5);
    244                }
    245
    246                if (par1Str != null)
    247                {
    248                    SoundPoolEntry var6 = this.soundPoolStreaming.getRandomSoundFromSoundPool(par1Str);
    249                    var6 = SoundEvent.getResult(new PlayStreamingEvent(this, var6, par1Str, par2, par3, par4));
    250
    251                    if (var6 != null)
    252                    {
    253                        if (sndSystem.playing("BgMusic"))
    254                        {
    255                            sndSystem.stop("BgMusic");
    256                        }
    257
    258                        float var7 = 16.0F;
    259                        sndSystem.newStreamingSource(true, var5, var6.soundUrl, var6.soundName, false, par2, par3, par4, 2, var7 * 4.0F);
    260                        sndSystem.setVolume(var5, 0.5F * this.options.soundVolume);
    261                        MinecraftForge.EVENT_BUS.post(new PlayStreamingSourceEvent(this, var5, par2, par3, par4));
    262                        sndSystem.play(var5);
    263                    }
    264                }
    265            }
    266        }
    267
    268        public void func_82460_a(Entity par1Entity)
    269        {
    270            this.func_82462_a(par1Entity, par1Entity);
    271        }
    272
    273        public void func_82462_a(Entity par1Entity, Entity par2Entity)
    274        {
    275            String var3 = "entity_" + par1Entity.entityId;
    276
    277            if (this.field_82470_g.contains(var3))
    278            {
    279                if (sndSystem.playing(var3))
    280                {
    281                    sndSystem.setPosition(var3, (float)par2Entity.posX, (float)par2Entity.posY, (float)par2Entity.posZ);
    282                    sndSystem.setVelocity(var3, (float)par2Entity.motionX, (float)par2Entity.motionY, (float)par2Entity.motionZ);
    283                }
    284                else
    285                {
    286                    this.field_82470_g.remove(var3);
    287                }
    288            }
    289        }
    290
    291        public boolean func_82465_b(Entity par1Entity)
    292        {
    293            if (par1Entity != null && loaded && this.options.musicVolume != 0.0F)
    294            {
    295                String var2 = "entity_" + par1Entity.entityId;
    296                return sndSystem.playing(var2);
    297            }
    298            else
    299            {
    300                return false;
    301            }
    302        }
    303
    304        public void func_82469_c(Entity par1Entity)
    305        {
    306            if (par1Entity != null && loaded && this.options.musicVolume != 0.0F)
    307            {
    308                String var2 = "entity_" + par1Entity.entityId;
    309
    310                if (this.field_82470_g.contains(var2))
    311                {
    312                    if (sndSystem.playing(var2))
    313                    {
    314                        sndSystem.stop(var2);
    315                    }
    316
    317                    this.field_82470_g.remove(var2);
    318                }
    319            }
    320        }
    321
    322        public void func_82468_a(Entity par1Entity, float par2)
    323        {
    324            if (par1Entity != null && loaded && this.options.musicVolume != 0.0F)
    325            {
    326                if (loaded && this.options.soundVolume != 0.0F)
    327                {
    328                    String var3 = "entity_" + par1Entity.entityId;
    329
    330                    if (sndSystem.playing(var3))
    331                    {
    332                        sndSystem.setVolume(var3, par2 * this.options.soundVolume);
    333                    }
    334                }
    335            }
    336        }
    337
    338        public void func_82463_b(Entity par1Entity, float par2)
    339        {
    340            if (par1Entity != null && loaded && this.options.musicVolume != 0.0F)
    341            {
    342                if (loaded && this.options.soundVolume != 0.0F)
    343                {
    344                    String var3 = "entity_" + par1Entity.entityId;
    345
    346                    if (sndSystem.playing(var3))
    347                    {
    348                        sndSystem.setPitch(var3, par2);
    349                    }
    350                }
    351            }
    352        }
    353
    354        public void func_82467_a(String par1Str, Entity par2Entity, float par3, float par4, boolean par5)
    355        {
    356            if (par2Entity != null)
    357            {
    358                if (loaded && (this.options.soundVolume != 0.0F || par1Str == null))
    359                {
    360                    String var6 = "entity_" + par2Entity.entityId;
    361
    362                    if (this.field_82470_g.contains(var6))
    363                    {
    364                        this.func_82460_a(par2Entity);
    365                    }
    366                    else
    367                    {
    368                        if (sndSystem.playing(var6))
    369                        {
    370                            sndSystem.stop(var6);
    371                        }
    372
    373                        if (par1Str == null)
    374                        {
    375                            return;
    376                        }
    377
    378                        SoundPoolEntry var7 = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str);
    379
    380                        if (var7 != null && par3 > 0.0F)
    381                        {
    382                            float var8 = 16.0F;
    383
    384                            if (par3 > 1.0F)
    385                            {
    386                                var8 *= par3;
    387                            }
    388
    389                            sndSystem.newSource(par5, var6, var7.soundUrl, var7.soundName, false, (float)par2Entity.posX, (float)par2Entity.posY, (float)par2Entity.posZ, 2, var8);
    390                            sndSystem.setLooping(var6, true);
    391                            sndSystem.setPitch(var6, par4);
    392
    393                            if (par3 > 1.0F)
    394                            {
    395                                par3 = 1.0F;
    396                            }
    397
    398                            sndSystem.setVolume(var6, par3 * this.options.soundVolume);
    399                            sndSystem.setVelocity(var6, (float)par2Entity.motionX, (float)par2Entity.motionY, (float)par2Entity.motionZ);
    400                            sndSystem.play(var6);
    401                            this.field_82470_g.add(var6);
    402                        }
    403                    }
    404                }
    405            }
    406        }
    407
    408        /**
    409         * Plays a sound. Args: soundName, x, y, z, volume, pitch
    410         */
    411        public void playSound(String par1Str, float par2, float par3, float par4, float par5, float par6)
    412        {
    413            if (loaded && this.options.soundVolume != 0.0F)
    414            {
    415                SoundPoolEntry var7 = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str);
    416                var7 = SoundEvent.getResult(new PlaySoundEvent(this, var7, par1Str, par2, par3, par4, par5, par6));
    417
    418                if (var7 != null && par5 > 0.0F)
    419                {
    420                    this.latestSoundID = (this.latestSoundID + 1) % 256;
    421                    String var8 = "sound_" + this.latestSoundID;
    422                    float var9 = 16.0F;
    423
    424                    if (par5 > 1.0F)
    425                    {
    426                        var9 *= par5;
    427                    }
    428
    429                    sndSystem.newSource(par5 > 1.0F, var8, var7.soundUrl, var7.soundName, false, par2, par3, par4, 2, var9);
    430                    sndSystem.setPitch(var8, par6);
    431
    432                    if (par5 > 1.0F)
    433                    {
    434                        par5 = 1.0F;
    435                    }
    436
    437                    sndSystem.setVolume(var8, par5 * this.options.soundVolume);
    438                    MinecraftForge.EVENT_BUS.post(new PlaySoundSourceEvent(this, var8, par2, par3, par4));
    439                    sndSystem.play(var8);
    440                }
    441            }
    442        }
    443
    444        /**
    445         * Plays a sound effect with the volume and pitch of the parameters passed. The sound isn't affected by position of
    446         * the player (full volume and center balanced)
    447         */
    448        public void playSoundFX(String par1Str, float par2, float par3)
    449        {
    450            if (loaded && this.options.soundVolume != 0.0F)
    451            {
    452                SoundPoolEntry var4 = this.soundPoolSounds.getRandomSoundFromSoundPool(par1Str);
    453                var4 = SoundEvent.getResult(new PlaySoundEffectEvent(this, var4, par1Str, par2, par3));
    454
    455                if (var4 != null)
    456                {
    457                    this.latestSoundID = (this.latestSoundID + 1) % 256;
    458                    String var5 = "sound_" + this.latestSoundID;
    459                    sndSystem.newSource(false, var5, var4.soundUrl, var4.soundName, false, 0.0F, 0.0F, 0.0F, 0, 0.0F);
    460
    461                    if (par2 > 1.0F)
    462                    {
    463                        par2 = 1.0F;
    464                    }
    465
    466                    par2 *= 0.25F;
    467                    sndSystem.setPitch(var5, par3);
    468                    sndSystem.setVolume(var5, par2 * this.options.soundVolume);
    469                    MinecraftForge.EVENT_BUS.post(new PlaySoundEffectSourceEvent(this, var5));
    470                    sndSystem.play(var5);
    471                }
    472            }
    473        }
    474
    475        public void func_82466_e()
    476        {
    477            Iterator var1 = this.field_82470_g.iterator();
    478
    479            while (var1.hasNext())
    480            {
    481                String var2 = (String)var1.next();
    482                sndSystem.pause(var2);
    483            }
    484        }
    485
    486        public void func_82461_f()
    487        {
    488            Iterator var1 = this.field_82470_g.iterator();
    489
    490            while (var1.hasNext())
    491            {
    492                String var2 = (String)var1.next();
    493                sndSystem.play(var2);
    494            }
    495        }
    496    }