Merge pull request #568 from runelite-extended/sounds

Runelite Client Sounds
This commit is contained in:
Tyler Bochard
2019-06-12 21:17:35 -04:00
committed by GitHub
28 changed files with 457 additions and 152 deletions

View File

@@ -317,6 +317,7 @@
<nonFilteredFileExtension>ttf</nonFilteredFileExtension> <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension> <nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension> <nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>wav</nonFilteredFileExtension>
</nonFilteredFileExtensions> </nonFilteredFileExtensions>
</configuration> </configuration>
</plugin> </plugin>

View File

@@ -31,10 +31,10 @@ import net.runelite.api.Constants;
public interface RuneLiteConfig extends Config public interface RuneLiteConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "gameSize", keyName = "gameSize",
name = "Game size", name = "Game size",
description = "The game will resize to this resolution upon starting the client", description = "The game will resize to this resolution upon starting the client",
position = 10 position = 10
) )
default Dimension gameSize() default Dimension gameSize()
{ {
@@ -42,10 +42,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "automaticResizeType", keyName = "automaticResizeType",
name = "Resize type", name = "Resize type",
description = "Choose how the window should resize when opening and closing panels", description = "Choose how the window should resize when opening and closing panels",
position = 11 position = 11
) )
default ExpandResizeType automaticResizeType() default ExpandResizeType automaticResizeType()
{ {
@@ -53,10 +53,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "lockWindowSize", keyName = "lockWindowSize",
name = "Lock window size", name = "Lock window size",
description = "Determines if the window resizing is allowed or not", description = "Determines if the window resizing is allowed or not",
position = 12 position = 12
) )
default boolean lockWindowSize() default boolean lockWindowSize()
{ {
@@ -64,10 +64,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "enablePlugins", keyName = "enablePlugins",
name = "Enable loading of external plugins", name = "Enable loading of external plugins",
description = "Enable loading of external plugins", description = "Enable loading of external plugins",
position = 10 position = 10
) )
default boolean enablePlugins() default boolean enablePlugins()
{ {
@@ -75,10 +75,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "containInScreen", keyName = "containInScreen",
name = "Contain in screen", name = "Contain in screen",
description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.", description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.",
position = 13 position = 13
) )
default boolean containInScreen() default boolean containInScreen()
{ {
@@ -86,10 +86,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "rememberScreenBounds", keyName = "rememberScreenBounds",
name = "Remember client position", name = "Remember client position",
description = "Save the position and size of the client after exiting", description = "Save the position and size of the client after exiting",
position = 14 position = 14
) )
default boolean rememberScreenBounds() default boolean rememberScreenBounds()
{ {
@@ -97,11 +97,11 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "uiEnableCustomChrome", keyName = "uiEnableCustomChrome",
name = "Enable custom window chrome", name = "Enable custom window chrome",
description = "Use Runelite's custom window title and borders.", description = "Use Runelite's custom window title and borders.",
warning = "Please restart your client after changing this setting", warning = "Please restart your client after changing this setting",
position = 15 position = 15
) )
default boolean enableCustomChrome() default boolean enableCustomChrome()
{ {
@@ -109,10 +109,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "gameAlwaysOnTop", keyName = "gameAlwaysOnTop",
name = "Enable client always on top", name = "Enable client always on top",
description = "The game will always be on the top of the screen", description = "The game will always be on the top of the screen",
position = 16 position = 16
) )
default boolean gameAlwaysOnTop() default boolean gameAlwaysOnTop()
{ {
@@ -120,10 +120,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "warningOnExit", keyName = "warningOnExit",
name = "Display warning on exit", name = "Display warning on exit",
description = "Toggles a warning popup when trying to exit the client", description = "Toggles a warning popup when trying to exit the client",
position = 17 position = 17
) )
default WarningOnExit warningOnExit() default WarningOnExit warningOnExit()
{ {
@@ -131,10 +131,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "usernameInTitle", keyName = "usernameInTitle",
name = "Show display name in title", name = "Show display name in title",
description = "Toggles displaying of local player's display name in client title", description = "Toggles displaying of local player's display name in client title",
position = 18 position = 18
) )
default boolean usernameInTitle() default boolean usernameInTitle()
{ {
@@ -142,10 +142,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationTray", keyName = "notificationTray",
name = "Enable tray notifications", name = "Enable tray notifications",
description = "Enables tray notifications", description = "Enables tray notifications",
position = 20 position = 20
) )
default boolean enableTrayNotifications() default boolean enableTrayNotifications()
{ {
@@ -153,10 +153,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationRequestFocus", keyName = "notificationRequestFocus",
name = "Request focus on notification", name = "Request focus on notification",
description = "Toggles window focus request", description = "Toggles window focus request",
position = 21 position = 21
) )
default boolean requestFocusOnNotification() default boolean requestFocusOnNotification()
{ {
@@ -164,10 +164,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationSound", keyName = "notificationSound",
name = "Enable sound on notifications", name = "Enable sound on notifications",
description = "Enables the playing of a beep sound when notifications are displayed", description = "Enables the playing of a beep sound when notifications are displayed",
position = 22 position = 22
) )
default boolean enableNotificationSound() default boolean enableNotificationSound()
{ {
@@ -175,10 +175,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationGameMessage", keyName = "notificationGameMessage",
name = "Enable game message notifications", name = "Enable game message notifications",
description = "Puts a notification message in the chatbox", description = "Puts a notification message in the chatbox",
position = 23 position = 23
) )
default boolean enableGameMessageNotification() default boolean enableGameMessageNotification()
{ {
@@ -186,10 +186,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationFlash", keyName = "notificationFlash",
name = "Enable flash notification", name = "Enable flash notification",
description = "Flashes the game frame as a notification", description = "Flashes the game frame as a notification",
position = 24 position = 24
) )
default boolean enableFlashNotification() default boolean enableFlashNotification()
{ {
@@ -197,10 +197,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "notificationFocused", keyName = "notificationFocused",
name = "Send notifications when focused", name = "Send notifications when focused",
description = "Toggles all notifications for when the client is focused", description = "Toggles all notifications for when the client is focused",
position = 25 position = 25
) )
default boolean sendNotificationsWhenFocused() default boolean sendNotificationsWhenFocused()
{ {
@@ -208,10 +208,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "fontType", keyName = "fontType",
name = "Dynamic Overlay Font", name = "Dynamic Overlay Font",
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.", description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
position = 30 position = 30
) )
default FontType fontType() default FontType fontType()
{ {
@@ -219,10 +219,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "tooltipFontType", keyName = "tooltipFontType",
name = "Tooltip Font", name = "Tooltip Font",
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.", description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
position = 31 position = 31
) )
default FontType tooltipFontType() default FontType tooltipFontType()
{ {
@@ -230,10 +230,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "interfaceFontType", keyName = "interfaceFontType",
name = "Interface Overlay Font", name = "Interface Overlay Font",
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.", description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
position = 32 position = 32
) )
default FontType interfaceFontType() default FontType interfaceFontType()
{ {
@@ -241,10 +241,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "menuEntryShift", keyName = "menuEntryShift",
name = "Require Shift for overlay menu", name = "Require Shift for overlay menu",
description = "Overlay right-click menu will require shift to be added", description = "Overlay right-click menu will require shift to be added",
position = 33 position = 33
) )
default boolean menuEntryShift() default boolean menuEntryShift()
{ {
@@ -252,10 +252,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxVertical", keyName = "infoBoxVertical",
name = "Display infoboxes vertically", name = "Display infoboxes vertically",
description = "Toggles the infoboxes to display vertically", description = "Toggles the infoboxes to display vertically",
position = 40 position = 40
) )
default boolean infoBoxVertical() default boolean infoBoxVertical()
{ {
@@ -263,10 +263,10 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxWrap", keyName = "infoBoxWrap",
name = "Infobox wrap count", name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping", description = "Configures the amount of infoboxes shown before wrapping",
position = 41 position = 41
) )
default int infoBoxWrap() default int infoBoxWrap()
{ {
@@ -274,13 +274,26 @@ public interface RuneLiteConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "infoBoxSize", keyName = "infoBoxSize",
name = "Infobox size (px)", name = "Infobox size (px)",
description = "Configures the size of each infobox in pixels", description = "Configures the size of each infobox in pixels",
position = 42 position = 42
) )
default int infoBoxSize() default int infoBoxSize()
{ {
return 35; return 35;
} }
@Range( max = 100, min = 0 )
@ConfigItem(
keyName = "volume",
name = "Runelite Volume",
description = "Sets the volume of custom Runelite sounds (not the client sounds)",
position = 43
)
default int volume()
{
return 100;
}
} }

View File

@@ -0,0 +1,41 @@
package net.runelite.client.game;
public enum Sound
{
FIFTEEN_SECONDS(1, "net/runelite/client/game/sounds/15seconds.wav"),
FIVE_SECONDS(2, "net/runelite/client/game/sounds/5seconds.wav"),
ATTACK_WITH_MAGIC(3, "net/runelite/client/game/sounds/attackmagic.wav"),
ATTACK_WITH_MELEE(4, "net/runelite/client/game/sounds/attackmelee.wav"),
ATTACK_WITH_RANGED(5, "net/runelite/client/game/sounds/attackranged.wav"),
INCOMING(6, "net/runelite/client/game/sounds/incoming.wav"),
MOVE(7, "net/runelite/client/game/sounds/move.wav"),
PRAY_MAGIC(8, "net/runelite/client/game/sounds/praymagic.wav"),
PRAY_MELEE(9, "net/runelite/client/game/sounds/praymelee.wav"),
PRAY_RANGED(10, "net/runelite/client/game/sounds/prayranged.wav"),
REENABLE_PRAYER(11, "net/runelite/client/game/sounds/reenableprayer.wav"),
RUNAWAY(12, "net/runelite/client/game/sounds/runaway.wav"),
LOW_HEATLH(13, "net/runelite/client/game/sounds/lowhealth.wav"),
LOW_PRAYER(14, "net/runelite/client/game/sounds/lowprayer.wav"),
OUT_OF_COMBAT(15, "net/runelite/client/game/sounds/outofcombat.wav"),
RESTORED_SPECIAL_ATTACK(16, "net/runelite/client/game/sounds/restorespec.wav"),
IDLE(17, "net/runelite/client/game/sounds/idle.wav");
private String filePath;
private int id;
private Sound(int id, String filePath)
{
this.id = id;
this.filePath = filePath;
}
public String getFilePath()
{
return this.filePath;
}
public int getId()
{
return this.id;
}
}

View File

@@ -0,0 +1,95 @@
package net.runelite.client.game;
import com.google.inject.Inject;
import java.io.IOException;
import javax.inject.Singleton;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import net.runelite.client.config.RuneLiteConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class SoundManager
{
private static final Logger log = LoggerFactory.getLogger(SoundManager.class);
private final RuneLiteConfig runeliteConfig;
@Inject
private SoundManager(RuneLiteConfig runeLiteConfig)
{
this.runeliteConfig = runeLiteConfig;
}
public void playSound(final Sound sound)
{
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
AudioInputStream in = AudioSystem.getAudioInputStream(this.getClass().getClassLoader().getResource(sound.getFilePath()));
AudioFormat outFormat = SoundManager.this.getOutFormat(in.getFormat());
DataLine.Info info = new DataLine.Info(SourceDataLine.class, outFormat);
SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
if (line != null)
{
line.open(outFormat, 2200);
if (line.isControlSupported(FloatControl.Type.MASTER_GAIN))
{
int volume = SoundManager.this.runeliteConfig.volume();
FloatControl gainControl = (FloatControl)line.getControl(FloatControl.Type.MASTER_GAIN);
BooleanControl muteControl = (BooleanControl)line.getControl(BooleanControl.Type.MUTE);
if (volume == 0)
{
muteControl.setValue(true);
}
else
{
muteControl.setValue(false);
gainControl.setValue((float)(Math.log((double)volume / 100.0) / Math.log(10.0) * 20.0));
}
}
line.start();
SoundManager.this.stream(AudioSystem.getAudioInputStream(outFormat, in), line);
line.drain();
line.stop();
}
}
catch (IOException | LineUnavailableException | UnsupportedAudioFileException e)
{
throw new IllegalStateException(e);
}
}
}).start();
}
private AudioFormat getOutFormat(AudioFormat inFormat)
{
int ch = inFormat.getChannels();
float rate = inFormat.getSampleRate();
return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
}
private void stream(AudioInputStream in, SourceDataLine line) throws IOException
{
byte[] buffer = new byte[2200];
int n = 0;
while (n != -1)
{
line.write(buffer, 0, n);
n = in.read(buffer, 0, buffer.length);
}
}
}

View File

@@ -32,10 +32,10 @@ import net.runelite.client.config.ConfigItem;
public interface IdleNotifierConfig extends Config public interface IdleNotifierConfig extends Config
{ {
@ConfigItem( @ConfigItem(
keyName = "animationidle", keyName = "animationidle",
name = "Idle Animation Notifications", name = "Idle Animation Notifications",
description = "Configures if idle animation notifications are enabled", description = "Configures if idle animation notifications are enabled",
position = 1 position = 1
) )
default boolean animationIdle() default boolean animationIdle()
{ {
@@ -43,10 +43,21 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "interactionidle", keyName = "animationidlesound",
name = "Idle Interaction Notifications", name = "Idle Animation Sound",
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing", description = "Plays a custom sound accompanying Idle Animation notifications",
position = 2 position = 2
)
default boolean animationIdleSound()
{
return false;
}
@ConfigItem(
keyName = "interactionidle",
name = "Idle Interaction Notifications",
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing",
position = 3
) )
default boolean interactionIdle() default boolean interactionIdle()
{ {
@@ -54,10 +65,21 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "logoutidle", keyName = "interactionidlesound",
name = "Idle Logout Notifications", name = "Idle Interaction Sound",
description = "Configures if the idle logout notifications are enabled", description = "Plays a custom sound accompanying Idle Interaction notifications",
position = 3 position = 4
)
default boolean interactionIdleSound()
{
return false;
}
@ConfigItem(
keyName = "logoutidle",
name = "Idle Logout Notifications",
description = "Configures if the idle logout notifications are enabled",
position = 5
) )
default boolean logoutIdle() default boolean logoutIdle()
{ {
@@ -65,10 +87,21 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 4, keyName = "outofcombatsound",
keyName = "skullNotification", name = "Out of Combat Sound",
name = "Skull Notification", description = "Plays a custom sound whenever you leave combat",
description = "Receive a notification when you skull." position = 6
)
default boolean outOfCombatSound()
{
return false;
}
@ConfigItem(
position = 7,
keyName = "skullNotification",
name = "Skull Notification",
description = "Receive a notification when you skull."
) )
default boolean showSkullNotification() default boolean showSkullNotification()
{ {
@@ -76,10 +109,10 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
position = 5, position = 8,
keyName = "unskullNotification", keyName = "unskullNotification",
name = "Unskull Notification", name = "Unskull Notification",
description = "Receive a notification when you unskull." description = "Receive a notification when you unskull."
) )
default boolean showUnskullNotification() default boolean showUnskullNotification()
{ {
@@ -87,10 +120,10 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "timeout", keyName = "timeout",
name = "Idle Notification Delay (ms)", name = "Idle Notification Delay (ms)",
description = "The notification delay after the player is idle", description = "The notification delay after the player is idle",
position = 6 position = 9
) )
default int getIdleNotificationDelay() default int getIdleNotificationDelay()
{ {
@@ -98,10 +131,10 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "hitpoints", keyName = "hitpoints",
name = "Hitpoints Notification Threshold", name = "Hitpoints Notification Threshold",
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.", description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
position = 7 position = 10
) )
default int getHitpointsThreshold() default int getHitpointsThreshold()
{ {
@@ -109,10 +142,21 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "prayer", keyName = "playHealthSound",
name = "Prayer Notification Threshold", name = "Play sound for Low Health",
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.", description = "Will play a sound for every Low Health notification sent",
position = 8 position = 12
)
default boolean getPlayHealthSound()
{
return false;
}
@ConfigItem(
keyName = "prayer",
name = "Prayer Notification Threshold",
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
position = 12
) )
default int getPrayerThreshold() default int getPrayerThreshold()
{ {
@@ -120,10 +164,21 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "oxygen", keyName = "playPrayerSound",
name = "Oxygen Notification Threshold", name = "Play sound for Low Prayer",
position = 9, description = "Will play a sound for every Low Prayer notification sent",
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." position = 13
)
default boolean getPlayPrayerSound()
{
return false;
}
@ConfigItem(
keyName = "oxygen",
name = "Oxygen Notification Threshold",
position = 14,
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
) )
default int getOxygenThreshold() default int getOxygenThreshold()
{ {
@@ -131,10 +186,10 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "spec", keyName = "spec",
name = "Special Attack Energy Notification Threshold", name = "Special Attack Energy Notification Threshold",
position = 10, position = 15,
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification." description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
) )
default int getSpecEnergyThreshold() default int getSpecEnergyThreshold()
{ {
@@ -142,12 +197,34 @@ public interface IdleNotifierConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "pkers", keyName = "specSound",
name = "PKer Notifier", name = "Special Attack Energy Sound",
position = 9, description = "Plays a custom sound accompanying Special Attack energy notifications",
description = "Notifies if an attackable player based on your level range appears on screen.", position = 16
group = "PvP", )
warning = "This will not notify you if the player is in your cc or is online on your friends list." default boolean getSpecSound()
{
return false;
}
@ConfigItem(
keyName = "overspec",
name = "Over Special Energy Notification",
description = "Will repeat notifications for any value over the special energy threshold",
position = 17
)
default boolean getOverSpecEnergy()
{
return false;
}
@ConfigItem(
keyName = "pkers",
name = "PKer Notifier",
position = 18,
description = "Notifies if an attackable player based on your level range appears on screen.",
group = "PvP",
warning = "This will not notify you if the player is in your cc or is online on your friends list."
) )
default boolean notifyPkers() default boolean notifyPkers()
{ {

View File

@@ -27,12 +27,18 @@ package net.runelite.client.plugins.idlenotifier;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.awt.TrayIcon; import java.awt.TrayIcon;
//import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
//import javax.sound.sampled.LineUnavailableException;
//import javax.sound.sampled.UnsupportedAudioFileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.runelite.api.Actor; import net.runelite.api.Actor;
import net.runelite.api.AnimationID; import net.runelite.api.AnimationID;
import static net.runelite.api.AnimationID.COOKING_FIRE; import static net.runelite.api.AnimationID.COOKING_FIRE;
@@ -145,6 +151,8 @@ import net.runelite.api.events.PlayerSpawned;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.Sound;
import net.runelite.client.game.SoundManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.PvPUtil; import net.runelite.client.util.PvPUtil;
@@ -156,6 +164,8 @@ import net.runelite.client.util.PvPUtil;
) )
public class IdleNotifierPlugin extends Plugin public class IdleNotifierPlugin extends Plugin
{ {
private static final Logger logger = LoggerFactory.getLogger(IdleNotifierPlugin.class);
// This must be more than 500 client ticks (10 seconds) before you get AFK kicked // This must be more than 500 client ticks (10 seconds) before you get AFK kicked
private static final int LOGOUT_WARNING_MILLIS = (4 * 60 + 40) * 1000; // 4 minutes and 40 seconds private static final int LOGOUT_WARNING_MILLIS = (4 * 60 + 40) * 1000; // 4 minutes and 40 seconds
private static final int COMBAT_WARNING_MILLIS = 19 * 60 * 1000; // 19 minutes private static final int COMBAT_WARNING_MILLIS = 19 * 60 * 1000; // 19 minutes
@@ -173,6 +183,9 @@ public class IdleNotifierPlugin extends Plugin
@Inject @Inject
private Client client; private Client client;
@Inject
private SoundManager soundManager;
@Inject @Inject
private IdleNotifierConfig config; private IdleNotifierConfig config;
@@ -509,28 +522,47 @@ public class IdleNotifierPlugin extends Plugin
if (config.animationIdle() && checkAnimationIdle(waitDuration, local)) if (config.animationIdle() && checkAnimationIdle(waitDuration, local))
{ {
notifier.notify("[" + local.getName() + "] is now idle!"); notifier.notify("[" + local.getName() + "] is now idle!");
if (config.animationIdleSound())
{
soundManager.playSound(Sound.IDLE);
}
} }
if (config.interactionIdle() && checkInteractionIdle(waitDuration, local)) if (config.interactionIdle() && checkInteractionIdle(waitDuration, local))
{ {
if (lastInteractWasCombat) if (lastInteractWasCombat)
{ {
notifier.notify("[" + local.getName() + "] is now out of combat!"); notifier.notify("[" + local.getName() + "] is now out of combat!");
if (config.outOfCombatSound())
{
soundManager.playSound(Sound.OUT_OF_COMBAT);
}
} }
else else
{ {
notifier.notify("[" + local.getName() + "] is now idle!"); notifier.notify("[" + local.getName() + "] is now idle!");
if (config.interactionIdleSound())
{
soundManager.playSound(Sound.IDLE);
}
} }
} }
if (checkLowHitpoints()) if (checkLowHitpoints())
{ {
notifier.notify("[" + local.getName() + "] has low hitpoints!"); notifier.notify("[" + local.getName() + "] has low hitpoints!");
if (config.getPlayHealthSound())
{
soundManager.playSound(Sound.LOW_HEATLH);
}
} }
if (checkLowPrayer()) if (checkLowPrayer())
{ {
notifier.notify("[" + local.getName() + "] has low prayer!"); notifier.notify("[" + local.getName() + "] has low prayer!");
if (config.getPlayPrayerSound())
{
soundManager.playSound(Sound.LOW_PRAYER);
}
} }
if (checkLowOxygen()) if (checkLowOxygen())
@@ -541,6 +573,10 @@ public class IdleNotifierPlugin extends Plugin
if (checkFullSpecEnergy()) if (checkFullSpecEnergy())
{ {
notifier.notify("[" + local.getName() + "] has restored spec energy!"); notifier.notify("[" + local.getName() + "] has restored spec energy!");
if (config.getSpecSound())
{
soundManager.playSound(Sound.RESTORED_SPECIAL_ATTACK);
}
} }
} }
@@ -557,8 +593,10 @@ public class IdleNotifierPlugin extends Plugin
// Check if we have regenerated over the threshold, and that the // Check if we have regenerated over the threshold, and that the
// regen was small enough. // regen was small enough.
boolean notify = lastSpecEnergy < threshold && currentSpecEnergy >= threshold boolean notify = lastSpecEnergy < threshold && currentSpecEnergy >= threshold && currentSpecEnergy - lastSpecEnergy <= 100;
&& currentSpecEnergy - lastSpecEnergy <= 100;
notify = (notify) || ((config.getOverSpecEnergy()) && (currentSpecEnergy >= threshold) && (currentSpecEnergy != lastSpecEnergy) && (currentSpecEnergy - lastSpecEnergy <= 100));
lastSpecEnergy = currentSpecEnergy; lastSpecEnergy = currentSpecEnergy;
return notify; return notify;
} }

View File

@@ -44,4 +44,14 @@ public interface ZulrahConfig extends Config
{ {
return true; return true;
} }
@ConfigItem(
keyName = "sounds",
name = "Sounds Enabled",
description = "Configures whether client sounds are enabled for zulrah"
)
default boolean sounds()
{
return true;
}
} }

View File

@@ -28,6 +28,9 @@ package net.runelite.client.plugins.zulrah;
import com.google.inject.Provides; import com.google.inject.Provides;
import javax.inject.Inject; import javax.inject.Inject;
//import javax.sound.sampled.LineUnavailableException;
//import javax.sound.sampled.UnsupportedAudioFileException;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -38,6 +41,8 @@ import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned; import net.runelite.api.events.NpcSpawned;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe; import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.Sound;
import net.runelite.client.game.SoundManager;
import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType; import net.runelite.client.plugins.PluginType;
@@ -51,8 +56,11 @@ import net.runelite.client.plugins.zulrah.patterns.ZulrahPatternB;
import net.runelite.client.plugins.zulrah.patterns.ZulrahPatternC; import net.runelite.client.plugins.zulrah.patterns.ZulrahPatternC;
import net.runelite.client.plugins.zulrah.patterns.ZulrahPatternD; import net.runelite.client.plugins.zulrah.patterns.ZulrahPatternD;
import net.runelite.client.plugins.zulrah.phase.ZulrahPhase; import net.runelite.client.plugins.zulrah.phase.ZulrahPhase;
import net.runelite.client.plugins.zulrah.phase.ZulrahType;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
//import java.io.IOException;
@PluginDescriptor( @PluginDescriptor(
name = "Zulrah Helper", name = "Zulrah Helper",
description = "Shows tiles on where to stand during the phases and what prayer to use.", description = "Shows tiles on where to stand during the phases and what prayer to use.",
@@ -79,6 +87,9 @@ public class ZulrahPlugin extends Plugin
@Inject @Inject
private OverlayManager overlayManager; private OverlayManager overlayManager;
@Inject
private SoundManager soundManager;
@Inject @Inject
private ZulrahCurrentPhaseOverlay currentPhaseOverlay; private ZulrahCurrentPhaseOverlay currentPhaseOverlay;
@@ -108,6 +119,8 @@ public class ZulrahPlugin extends Plugin
private ZulrahInstance instance; private ZulrahInstance instance;
private ZulrahPhase phase;
@Override @Override
protected void startUp() throws Exception protected void startUp() throws Exception
{ {
@@ -126,6 +139,7 @@ public class ZulrahPlugin extends Plugin
overlayManager.remove(zulrahOverlay); overlayManager.remove(zulrahOverlay);
zulrah = null; zulrah = null;
instance = null; instance = null;
phase = null;
} }
@Subscribe @Subscribe
@@ -153,6 +167,22 @@ public class ZulrahPlugin extends Plugin
} }
ZulrahPhase currentPhase = ZulrahPhase.valueOf(zulrah, instance.getStartLocation()); ZulrahPhase currentPhase = ZulrahPhase.valueOf(zulrah, instance.getStartLocation());
ZulrahType type = phase.getType();
if (config.sounds())
{
if (type == ZulrahType.RANGE)
{
soundManager.playSound(Sound.PRAY_RANGED);
}
if (type == ZulrahType.MAGIC)
{
soundManager.playSound(Sound.PRAY_MAGIC);
}
}
if (instance.getPhase() == null) if (instance.getPhase() == null)
{ {
instance.setPhase(currentPhase); instance.setPhase(currentPhase);

View File

@@ -69,12 +69,12 @@ public class ZulrahPhase
public String toString() public String toString()
{ {
return "ZulrahPhase{" + return "ZulrahPhase{" +
"zulrahLocation=" + zulrahLocation + "zulrahLocation=" + zulrahLocation +
", type=" + type + ", type=" + type +
", jad=" + jad + ", jad=" + jad +
", standLocation=" + standLocation + ", standLocation=" + standLocation +
", prayer=" + prayer + ", prayer=" + prayer +
'}'; '}';
} }
// world location // world location