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>png</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>wav</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>

View File

@@ -31,10 +31,10 @@ import net.runelite.api.Constants;
public interface RuneLiteConfig extends Config
{
@ConfigItem(
keyName = "gameSize",
name = "Game size",
description = "The game will resize to this resolution upon starting the client",
position = 10
keyName = "gameSize",
name = "Game size",
description = "The game will resize to this resolution upon starting the client",
position = 10
)
default Dimension gameSize()
{
@@ -42,10 +42,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "automaticResizeType",
name = "Resize type",
description = "Choose how the window should resize when opening and closing panels",
position = 11
keyName = "automaticResizeType",
name = "Resize type",
description = "Choose how the window should resize when opening and closing panels",
position = 11
)
default ExpandResizeType automaticResizeType()
{
@@ -53,10 +53,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "lockWindowSize",
name = "Lock window size",
description = "Determines if the window resizing is allowed or not",
position = 12
keyName = "lockWindowSize",
name = "Lock window size",
description = "Determines if the window resizing is allowed or not",
position = 12
)
default boolean lockWindowSize()
{
@@ -64,10 +64,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "enablePlugins",
name = "Enable loading of external plugins",
description = "Enable loading of external plugins",
position = 10
keyName = "enablePlugins",
name = "Enable loading of external plugins",
description = "Enable loading of external plugins",
position = 10
)
default boolean enablePlugins()
{
@@ -75,10 +75,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "containInScreen",
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.",
position = 13
keyName = "containInScreen",
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.",
position = 13
)
default boolean containInScreen()
{
@@ -86,10 +86,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "rememberScreenBounds",
name = "Remember client position",
description = "Save the position and size of the client after exiting",
position = 14
keyName = "rememberScreenBounds",
name = "Remember client position",
description = "Save the position and size of the client after exiting",
position = 14
)
default boolean rememberScreenBounds()
{
@@ -97,11 +97,11 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "uiEnableCustomChrome",
name = "Enable custom window chrome",
description = "Use Runelite's custom window title and borders.",
warning = "Please restart your client after changing this setting",
position = 15
keyName = "uiEnableCustomChrome",
name = "Enable custom window chrome",
description = "Use Runelite's custom window title and borders.",
warning = "Please restart your client after changing this setting",
position = 15
)
default boolean enableCustomChrome()
{
@@ -109,10 +109,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "gameAlwaysOnTop",
name = "Enable client always on top",
description = "The game will always be on the top of the screen",
position = 16
keyName = "gameAlwaysOnTop",
name = "Enable client always on top",
description = "The game will always be on the top of the screen",
position = 16
)
default boolean gameAlwaysOnTop()
{
@@ -120,10 +120,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "warningOnExit",
name = "Display warning on exit",
description = "Toggles a warning popup when trying to exit the client",
position = 17
keyName = "warningOnExit",
name = "Display warning on exit",
description = "Toggles a warning popup when trying to exit the client",
position = 17
)
default WarningOnExit warningOnExit()
{
@@ -131,10 +131,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "usernameInTitle",
name = "Show display name in title",
description = "Toggles displaying of local player's display name in client title",
position = 18
keyName = "usernameInTitle",
name = "Show display name in title",
description = "Toggles displaying of local player's display name in client title",
position = 18
)
default boolean usernameInTitle()
{
@@ -142,10 +142,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationTray",
name = "Enable tray notifications",
description = "Enables tray notifications",
position = 20
keyName = "notificationTray",
name = "Enable tray notifications",
description = "Enables tray notifications",
position = 20
)
default boolean enableTrayNotifications()
{
@@ -153,10 +153,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationRequestFocus",
name = "Request focus on notification",
description = "Toggles window focus request",
position = 21
keyName = "notificationRequestFocus",
name = "Request focus on notification",
description = "Toggles window focus request",
position = 21
)
default boolean requestFocusOnNotification()
{
@@ -164,10 +164,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationSound",
name = "Enable sound on notifications",
description = "Enables the playing of a beep sound when notifications are displayed",
position = 22
keyName = "notificationSound",
name = "Enable sound on notifications",
description = "Enables the playing of a beep sound when notifications are displayed",
position = 22
)
default boolean enableNotificationSound()
{
@@ -175,10 +175,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationGameMessage",
name = "Enable game message notifications",
description = "Puts a notification message in the chatbox",
position = 23
keyName = "notificationGameMessage",
name = "Enable game message notifications",
description = "Puts a notification message in the chatbox",
position = 23
)
default boolean enableGameMessageNotification()
{
@@ -186,10 +186,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationFlash",
name = "Enable flash notification",
description = "Flashes the game frame as a notification",
position = 24
keyName = "notificationFlash",
name = "Enable flash notification",
description = "Flashes the game frame as a notification",
position = 24
)
default boolean enableFlashNotification()
{
@@ -197,10 +197,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "notificationFocused",
name = "Send notifications when focused",
description = "Toggles all notifications for when the client is focused",
position = 25
keyName = "notificationFocused",
name = "Send notifications when focused",
description = "Toggles all notifications for when the client is focused",
position = 25
)
default boolean sendNotificationsWhenFocused()
{
@@ -208,10 +208,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "fontType",
name = "Dynamic Overlay Font",
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
position = 30
keyName = "fontType",
name = "Dynamic Overlay Font",
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
position = 30
)
default FontType fontType()
{
@@ -219,10 +219,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "tooltipFontType",
name = "Tooltip Font",
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
position = 31
keyName = "tooltipFontType",
name = "Tooltip Font",
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
position = 31
)
default FontType tooltipFontType()
{
@@ -230,10 +230,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "interfaceFontType",
name = "Interface Overlay Font",
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
position = 32
keyName = "interfaceFontType",
name = "Interface Overlay Font",
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
position = 32
)
default FontType interfaceFontType()
{
@@ -241,10 +241,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "menuEntryShift",
name = "Require Shift for overlay menu",
description = "Overlay right-click menu will require shift to be added",
position = 33
keyName = "menuEntryShift",
name = "Require Shift for overlay menu",
description = "Overlay right-click menu will require shift to be added",
position = 33
)
default boolean menuEntryShift()
{
@@ -252,10 +252,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "infoBoxVertical",
name = "Display infoboxes vertically",
description = "Toggles the infoboxes to display vertically",
position = 40
keyName = "infoBoxVertical",
name = "Display infoboxes vertically",
description = "Toggles the infoboxes to display vertically",
position = 40
)
default boolean infoBoxVertical()
{
@@ -263,10 +263,10 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "infoBoxWrap",
name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping",
position = 41
keyName = "infoBoxWrap",
name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping",
position = 41
)
default int infoBoxWrap()
{
@@ -274,13 +274,26 @@ public interface RuneLiteConfig extends Config
}
@ConfigItem(
keyName = "infoBoxSize",
name = "Infobox size (px)",
description = "Configures the size of each infobox in pixels",
position = 42
keyName = "infoBoxSize",
name = "Infobox size (px)",
description = "Configures the size of each infobox in pixels",
position = 42
)
default int infoBoxSize()
{
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
{
@ConfigItem(
keyName = "animationidle",
name = "Idle Animation Notifications",
description = "Configures if idle animation notifications are enabled",
position = 1
keyName = "animationidle",
name = "Idle Animation Notifications",
description = "Configures if idle animation notifications are enabled",
position = 1
)
default boolean animationIdle()
{
@@ -43,10 +43,21 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "interactionidle",
name = "Idle Interaction Notifications",
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing",
position = 2
keyName = "animationidlesound",
name = "Idle Animation Sound",
description = "Plays a custom sound accompanying Idle Animation notifications",
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()
{
@@ -54,10 +65,21 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "logoutidle",
name = "Idle Logout Notifications",
description = "Configures if the idle logout notifications are enabled",
position = 3
keyName = "interactionidlesound",
name = "Idle Interaction Sound",
description = "Plays a custom sound accompanying Idle Interaction notifications",
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()
{
@@ -65,10 +87,21 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
position = 4,
keyName = "skullNotification",
name = "Skull Notification",
description = "Receive a notification when you skull."
keyName = "outofcombatsound",
name = "Out of Combat Sound",
description = "Plays a custom sound whenever you leave combat",
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()
{
@@ -76,10 +109,10 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
position = 5,
keyName = "unskullNotification",
name = "Unskull Notification",
description = "Receive a notification when you unskull."
position = 8,
keyName = "unskullNotification",
name = "Unskull Notification",
description = "Receive a notification when you unskull."
)
default boolean showUnskullNotification()
{
@@ -87,10 +120,10 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "timeout",
name = "Idle Notification Delay (ms)",
description = "The notification delay after the player is idle",
position = 6
keyName = "timeout",
name = "Idle Notification Delay (ms)",
description = "The notification delay after the player is idle",
position = 9
)
default int getIdleNotificationDelay()
{
@@ -98,10 +131,10 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "hitpoints",
name = "Hitpoints Notification Threshold",
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
position = 7
keyName = "hitpoints",
name = "Hitpoints Notification Threshold",
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
position = 10
)
default int getHitpointsThreshold()
{
@@ -109,10 +142,21 @@ public interface IdleNotifierConfig extends Config
}
@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 = 8
keyName = "playHealthSound",
name = "Play sound for Low Health",
description = "Will play a sound for every Low Health notification sent",
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()
{
@@ -120,10 +164,21 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "oxygen",
name = "Oxygen Notification Threshold",
position = 9,
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
keyName = "playPrayerSound",
name = "Play sound for Low Prayer",
description = "Will play a sound for every Low Prayer notification sent",
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()
{
@@ -131,10 +186,10 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "spec",
name = "Special Attack Energy Notification Threshold",
position = 10,
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
keyName = "spec",
name = "Special Attack Energy Notification Threshold",
position = 15,
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
)
default int getSpecEnergyThreshold()
{
@@ -142,12 +197,34 @@ public interface IdleNotifierConfig extends Config
}
@ConfigItem(
keyName = "pkers",
name = "PKer Notifier",
position = 9,
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."
keyName = "specSound",
name = "Special Attack Energy Sound",
description = "Plays a custom sound accompanying Special Attack energy notifications",
position = 16
)
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()
{

View File

@@ -27,12 +27,18 @@ package net.runelite.client.plugins.idlenotifier;
import com.google.inject.Provides;
import java.awt.TrayIcon;
//import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
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.AnimationID;
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.config.ConfigManager;
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.PluginDescriptor;
import net.runelite.client.util.PvPUtil;
@@ -156,6 +164,8 @@ import net.runelite.client.util.PvPUtil;
)
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
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
@@ -173,6 +183,9 @@ public class IdleNotifierPlugin extends Plugin
@Inject
private Client client;
@Inject
private SoundManager soundManager;
@Inject
private IdleNotifierConfig config;
@@ -509,28 +522,47 @@ public class IdleNotifierPlugin extends Plugin
if (config.animationIdle() && checkAnimationIdle(waitDuration, local))
{
notifier.notify("[" + local.getName() + "] is now idle!");
if (config.animationIdleSound())
{
soundManager.playSound(Sound.IDLE);
}
}
if (config.interactionIdle() && checkInteractionIdle(waitDuration, local))
{
if (lastInteractWasCombat)
{
notifier.notify("[" + local.getName() + "] is now out of combat!");
if (config.outOfCombatSound())
{
soundManager.playSound(Sound.OUT_OF_COMBAT);
}
}
else
{
notifier.notify("[" + local.getName() + "] is now idle!");
if (config.interactionIdleSound())
{
soundManager.playSound(Sound.IDLE);
}
}
}
if (checkLowHitpoints())
{
notifier.notify("[" + local.getName() + "] has low hitpoints!");
if (config.getPlayHealthSound())
{
soundManager.playSound(Sound.LOW_HEATLH);
}
}
if (checkLowPrayer())
{
notifier.notify("[" + local.getName() + "] has low prayer!");
if (config.getPlayPrayerSound())
{
soundManager.playSound(Sound.LOW_PRAYER);
}
}
if (checkLowOxygen())
@@ -541,6 +573,10 @@ public class IdleNotifierPlugin extends Plugin
if (checkFullSpecEnergy())
{
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
// regen was small enough.
boolean notify = lastSpecEnergy < threshold && currentSpecEnergy >= threshold
&& currentSpecEnergy - lastSpecEnergy <= 100;
boolean notify = lastSpecEnergy < threshold && currentSpecEnergy >= threshold && currentSpecEnergy - lastSpecEnergy <= 100;
notify = (notify) || ((config.getOverSpecEnergy()) && (currentSpecEnergy >= threshold) && (currentSpecEnergy != lastSpecEnergy) && (currentSpecEnergy - lastSpecEnergy <= 100));
lastSpecEnergy = currentSpecEnergy;
return notify;
}
@@ -794,4 +832,4 @@ public class IdleNotifierPlugin extends Plugin
lastTickSkull = currentTickSkull;
}
}
}
}

View File

@@ -44,4 +44,14 @@ public interface ZulrahConfig extends Config
{
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 javax.inject.Inject;
//import javax.sound.sampled.LineUnavailableException;
//import javax.sound.sampled.UnsupportedAudioFileException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
@@ -38,6 +41,8 @@ import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.config.ConfigManager;
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.PluginDescriptor;
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.ZulrahPatternD;
import net.runelite.client.plugins.zulrah.phase.ZulrahPhase;
import net.runelite.client.plugins.zulrah.phase.ZulrahType;
import net.runelite.client.ui.overlay.OverlayManager;
//import java.io.IOException;
@PluginDescriptor(
name = "Zulrah Helper",
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
private OverlayManager overlayManager;
@Inject
private SoundManager soundManager;
@Inject
private ZulrahCurrentPhaseOverlay currentPhaseOverlay;
@@ -108,6 +119,8 @@ public class ZulrahPlugin extends Plugin
private ZulrahInstance instance;
private ZulrahPhase phase;
@Override
protected void startUp() throws Exception
{
@@ -126,6 +139,7 @@ public class ZulrahPlugin extends Plugin
overlayManager.remove(zulrahOverlay);
zulrah = null;
instance = null;
phase = null;
}
@Subscribe
@@ -153,6 +167,22 @@ public class ZulrahPlugin extends Plugin
}
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)
{
instance.setPhase(currentPhase);

View File

@@ -74,4 +74,4 @@ public abstract class ZulrahPattern
{
return index >= pattern.size();
}
}
}

View File

@@ -53,4 +53,4 @@ public class ZulrahPatternC extends ZulrahPattern
{
return "Pattern C";
}
}
}

View File

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