diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 1a36c3be9e..754a6c0b74 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -982,6 +982,15 @@ public interface Client extends GameEngine */ void playSoundEffect(int id, int x, int y, int range, int delay); + /** + * Plays a sound effect, even if the player's sound effect volume is muted. + * + * @param id the ID of the sound effect - {@link SoundEffectID} + * @param volume the volume to play the sound effect at, see {@link SoundEffectVolume} for values used + * in the settings interface. if the sound effect volume is not muted, uses the set volume + */ + void playSoundEffect(int id, int volume); + /** * Gets the clients graphic buffer provider. * diff --git a/runelite-api/src/main/java/net/runelite/api/SoundEffectVolume.java b/runelite-api/src/main/java/net/runelite/api/SoundEffectVolume.java new file mode 100644 index 0000000000..dee7d7c9c1 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/SoundEffectVolume.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +/** + * Volume values for each of the stops on the volume interface + */ +public final class SoundEffectVolume +{ + public static final int MUTED = 0; + public static final int LOW = 32; + public static final int MEDIUM_LOW = 64; + public static final int MEDIUM_HIGH = 96; + public static final int HIGH = 127; +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java index 8effc5a812..c9a3f77ba4 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/SoundEffectMixin.java @@ -24,14 +24,18 @@ */ package net.runelite.mixins; +import net.runelite.api.SoundEffectVolume; import net.runelite.api.events.AreaSoundEffectPlayed; import net.runelite.api.events.SoundEffectPlayed; import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSAudioTaskNode; import net.runelite.rs.api.RSClient; +import net.runelite.rs.api.RSRawAudioNode; import net.runelite.rs.api.RSSoundEffect; +import net.runelite.rs.api.RSTaskDataNode; @Mixin(RSClient.class) public abstract class SoundEffectMixin implements RSClient @@ -78,6 +82,30 @@ public abstract class SoundEffectMixin implements RSClient setQueuedSoundEffectCount(queuedSoundEffectCount + 1); } + @Inject + @Override + public void playSoundEffect(int id, int volume) + { + RSSoundEffect soundEffect = getTrack(getIndexCache4(), id, 0); + if (soundEffect == null) + { + return; + } + + // If the current volume is not muted, use it instead + final int soundEffectVolume = getSoundEffectVolume(); + if (soundEffectVolume != SoundEffectVolume.MUTED) + { + volume = soundEffectVolume; + } + + RSRawAudioNode rawAudioNode = soundEffect.toRawAudioNode().applyResampler(getSoundEffectResampler()); + RSAudioTaskNode audioTaskNode = createSoundEffectAudioTaskNode(rawAudioNode, 100, volume); + audioTaskNode.setNumLoops(1); + + getSoundEffectAudioQueue().queueAudioTaskNode((RSTaskDataNode) audioTaskNode); + } + @FieldHook("queuedSoundEffectCount") @Inject public static void queuedSoundEffectCountChanged(int idx) diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNode.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNode.java new file mode 100644 index 0000000000..9a90fc7883 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNode.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +import net.runelite.mapping.Import; + +public interface RSAudioTaskNode +{ + @Import("setNumLoops") + void setNumLoops(int numLoops); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNodeQueue.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNodeQueue.java new file mode 100644 index 0000000000..2a50e79471 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAudioTaskNodeQueue.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +import net.runelite.mapping.Import; + +public interface RSAudioTaskNodeQueue +{ + @Import("queueAudioTaskNode") + void queueAudioTaskNode(RSTaskDataNode taskDataNode); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index e0a8c5f8d1..c78a360dfc 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -564,6 +564,9 @@ public interface RSClient extends RSGameEngine, Client @Import("queuedSoundEffectCount") void setQueuedSoundEffectCount(int queuedSoundEffectCount); + @Import("queueSoundEffect") + void queueSoundEffect(int id, int numLoops, int delay); + @Import("rasterProvider") @Override RSBufferProvider getBufferProvider(); @@ -986,4 +989,22 @@ public interface RSClient extends RSGameEngine, Client @Import("healthBarSpriteCache") RSNodeCache getHealthBarSpriteCache(); + + @Import("getTrack") + RSSoundEffect getTrack(RSIndexData indexData, int id, int var0); + + @Import("createSoundEffectAudioTaskNode") + RSAudioTaskNode createSoundEffectAudioTaskNode(RSRawAudioNode audioNode, int var0, int volume); + + @Import("soundEffectAudioQueue") + RSAudioTaskNodeQueue getSoundEffectAudioQueue(); + + @Import("indexCache4") + RSIndexData getIndexCache4(); + + @Import("soundEffectResampler") + RSResampler getSoundEffectResampler(); + + @Import("soundEffectVolume") + int getSoundEffectVolume(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRawAudioNode.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRawAudioNode.java new file mode 100644 index 0000000000..5c51c394da --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRawAudioNode.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +import net.runelite.mapping.Import; + +public interface RSRawAudioNode +{ + @Import("applyResampler") + RSRawAudioNode applyResampler(RSResampler resampler); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSResampler.java b/runescape-api/src/main/java/net/runelite/rs/api/RSResampler.java new file mode 100644 index 0000000000..6b75c34f09 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSResampler.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +public interface RSResampler +{ +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSSoundEffect.java b/runescape-api/src/main/java/net/runelite/rs/api/RSSoundEffect.java index 4ced2f19d5..c1f6002bf8 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSSoundEffect.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSSoundEffect.java @@ -24,6 +24,10 @@ */ package net.runelite.rs.api; +import net.runelite.mapping.Import; + public interface RSSoundEffect { + @Import("toRawAudioNode") + RSRawAudioNode toRawAudioNode(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSTaskDataNode.java b/runescape-api/src/main/java/net/runelite/rs/api/RSTaskDataNode.java new file mode 100644 index 0000000000..bcc61f9684 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSTaskDataNode.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, trimbe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.rs.api; + +public interface RSTaskDataNode +{ +}