diff --git a/src/Client/ConfigWindow.java b/src/Client/ConfigWindow.java index f14aab37..3ac92aad 100644 --- a/src/Client/ConfigWindow.java +++ b/src/Client/ConfigWindow.java @@ -371,6 +371,7 @@ public class ConfigWindow { private JRadioButton audioPanelOverrideAudioSettingOffButton; private JCheckBox audioPanelFixSpiderWebDummySoundCheckbox; private JCheckBox audioPanelFixSfxDelayCheckbox; + private JSlider audioPanelNotifVolumeSlider; private JCheckBox soundEffectAdvanceCheckbox; private JCheckBox soundEffectAnvilCheckbox; private JCheckBox soundEffectChiselCheckbox; @@ -3210,6 +3211,43 @@ public void actionPerformed(ActionEvent e) { "Fixes a bug where sound effects were delayed by a significant amount."); SearchUtils.addSearchMetadata(audioPanelFixSfxDelayCheckbox, CommonMetadata.SFX.getText()); + JPanel audioPanelNotifVolumePanel = new JPanel(); + audioPanel.add(audioPanelNotifVolumePanel); + audioPanelNotifVolumePanel.setLayout( + new BoxLayout(audioPanelNotifVolumePanel, BoxLayout.Y_AXIS)); + audioPanelNotifVolumePanel.setAlignmentX(Component.LEFT_ALIGNMENT); + audioPanelNotifVolumePanel.setBorder(BorderFactory.createEmptyBorder(0, 0, osScaleMul(10), 0)); + + JLabel audioPanelNotifVolumeLabel = + new JLabel(Launcher.binaryPrefix + "RSC+ notifications volume"); + audioPanelNotifVolumeLabel.setToolTipText( + "Sets the volume for the " + Launcher.binaryPrefix + "RSC+ notification sounds"); + audioPanelNotifVolumePanel.add(audioPanelNotifVolumeLabel); + audioPanelNotifVolumeLabel.setAlignmentY(1.0f); + SearchUtils.addSearchMetadata(audioPanelNotifVolumeLabel, CommonMetadata.ALERT.getText()); + + audioPanelNotifVolumePanel.add(Box.createRigidArea(osScaleMul(new Dimension(0, 5)))); + + audioPanelNotifVolumeSlider = new JSlider(); + + audioPanelNotifVolumePanel.add(audioPanelNotifVolumeSlider); + audioPanelNotifVolumeSlider.setAlignmentX(Component.LEFT_ALIGNMENT); + audioPanelNotifVolumeSlider.setMaximumSize(osScaleMul(new Dimension(350, 55))); + audioPanelNotifVolumeSlider.setMinorTickSpacing(5); + audioPanelNotifVolumeSlider.setMajorTickSpacing(10); + audioPanelNotifVolumeSlider.setMinimum(0); + audioPanelNotifVolumeSlider.setMaximum(100); + audioPanelNotifVolumeSlider.setPaintTicks(true); + + Hashtable audioPanelNotifVolumeTable = new Hashtable(); + audioPanelNotifVolumeTable.put(new Integer(0), new JLabel("0")); + audioPanelNotifVolumeTable.put(new Integer(25), new JLabel("25")); + audioPanelNotifVolumeTable.put(new Integer(50), new JLabel("50")); + audioPanelNotifVolumeTable.put(new Integer(75), new JLabel("75")); + audioPanelNotifVolumeTable.put(new Integer(100), new JLabel("100")); + audioPanelNotifVolumeSlider.setLabelTable(audioPanelNotifVolumeTable); + audioPanelNotifVolumeSlider.setPaintLabels(true); + addSettingsHeader(audioPanel, "Toggle individual sound effects"); JPanel audioPanelEnableAllSfxPanel = new JPanel(); @@ -3768,8 +3806,12 @@ public void actionPerformed(ActionEvent e) { notificationPanelNotifSoundsPanel.setLayout( new BoxLayout(notificationPanelNotifSoundsPanel, BoxLayout.Y_AXIS)); notificationPanelNotifSoundsPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + SearchUtils.addSearchMetadata( + notificationPanelNotifSoundsPanel, CommonMetadata.ALERT.getText()); notificationPanelNotifSoundsCheckbox = - addCheckbox("Enable notification sounds", notificationPanelNotifSoundsPanel); + addCheckbox( + "Enable notification sounds (adjust volume in Audio settings)", + notificationPanelNotifSoundsPanel); notificationPanelNotifSoundsCheckbox.setBorder( BorderFactory.createEmptyBorder(0, 0, osScaleMul(7), 0)); notificationPanelNotifSoundsCheckbox.setToolTipText( @@ -3995,6 +4037,8 @@ public void actionPerformed(ActionEvent e) { addCheckbox("Mute the alert sound even if it's an important message", notificationPanel); notificationPanelMuteImportantMessageSoundsCheckbox.setToolTipText( "Muting for Important Messages (defined in text fields above)"); + SearchUtils.addSearchMetadata( + notificationPanelMuteImportantMessageSoundsCheckbox, CommonMetadata.ALERT.getText()); addPanelBottomGlue(notificationPanel); @@ -5330,7 +5374,8 @@ private enum CommonMetadata { COLOUR("colours", "colors", "coloured", "colored"), PVP("pvp", "pk"), PM("private", "messages", "pms", "dms", "msgs"), - DIR("folders", "dirs", "directory", "directories", "files"); + DIR("folders", "dirs", "directory", "directories", "files"), + ALERT("alerts", "dings", "notifications"); public final String text; @@ -6487,6 +6532,7 @@ private void executeSynchronizeGuiValues() { audioPanelFixSpiderWebDummySoundCheckbox.setSelected( Settings.SOUND_EFFECT_COMBAT1.get(Settings.currentProfile)); audioPanelFixSfxDelayCheckbox.setSelected(Settings.FIX_SFX_DELAY.get(Settings.currentProfile)); + audioPanelNotifVolumeSlider.setValue(Settings.NOTIF_VOLUME.get(Settings.currentProfile)); soundEffectAdvanceCheckbox.setSelected( Settings.SOUND_EFFECT_ADVANCE.get(Settings.currentProfile)); soundEffectAnvilCheckbox.setSelected(Settings.SOUND_EFFECT_ANVIL.get(Settings.currentProfile)); @@ -6960,6 +7006,7 @@ private void saveSettings() { Settings.SOUND_EFFECT_COMBAT1.put( Settings.currentProfile, audioPanelFixSpiderWebDummySoundCheckbox.isSelected()); Settings.FIX_SFX_DELAY.put(Settings.currentProfile, audioPanelFixSfxDelayCheckbox.isSelected()); + Settings.NOTIF_VOLUME.put(Settings.currentProfile, audioPanelNotifVolumeSlider.getValue()); Settings.SOUND_EFFECT_ADVANCE.put( Settings.currentProfile, soundEffectAdvanceCheckbox.isSelected()); Settings.SOUND_EFFECT_ANVIL.put(Settings.currentProfile, soundEffectAnvilCheckbox.isSelected()); @@ -7278,6 +7325,7 @@ private void applySettings() { Item.patchItemCommands(); GameApplet.syncFontSetting(); SoundEffects.adjustMudClientSfxVolume(); + SoundEffects.adjustNotificationsVolume(); }); } diff --git a/src/Client/NotificationsHandler.java b/src/Client/NotificationsHandler.java index 0363fa36..0368644d 100644 --- a/src/Client/NotificationsHandler.java +++ b/src/Client/NotificationsHandler.java @@ -655,6 +655,14 @@ public void run() { private static Clip notificationSoundClip; private static Clip sadNotificationSoundClip; + public static Clip getNotificationSoundClip() { + return notificationSoundClip; + } + + public static Clip getSadNotificationSoundClip() { + return sadNotificationSoundClip; + } + public static void loadNotificationSound() { try { notificationAudioIn = diff --git a/src/Client/Settings.java b/src/Client/Settings.java index f5bbdd0c..5650a3cc 100644 --- a/src/Client/Settings.java +++ b/src/Client/Settings.java @@ -187,6 +187,7 @@ public class Settings { public static HashMap OVERRIDE_AUDIO_SETTING_SETTING_ON = new HashMap(); public static HashMap FIX_SFX_DELAY = new HashMap(); + public static HashMap NOTIF_VOLUME = new HashMap(); public static HashMap SOUND_EFFECT_COMBAT1 = new HashMap(); public static HashMap SOUND_EFFECT_ADVANCE = new HashMap(); public static HashMap SOUND_EFFECT_ANVIL = new HashMap(); @@ -1230,6 +1231,15 @@ public static void definePresets(Properties props) { FIX_SFX_DELAY.put( "custom", getPropBoolean(props, "fix_sfx_delay", FIX_SFX_DELAY.get("default"))); + NOTIF_VOLUME.put("vanilla", 100); + NOTIF_VOLUME.put("vanilla_resizable", 100); + NOTIF_VOLUME.put("lite", 100); + NOTIF_VOLUME.put("default", 100); + NOTIF_VOLUME.put("heavy", 100); + NOTIF_VOLUME.put("all", 100); + NOTIF_VOLUME.put("custom", 100); + NOTIF_VOLUME.put("custom", getPropInt(props, "notif_volume", NOTIF_VOLUME.get("default"))); + SOUND_EFFECT_ADVANCE.put("vanilla", true); SOUND_EFFECT_ADVANCE.put("vanilla_resizable", true); SOUND_EFFECT_ADVANCE.put("lite", true); @@ -2648,6 +2658,14 @@ public static void sanitizeSettings() { foundInvalidSetting = true; } + if (NOTIF_VOLUME.get("custom") < 0) { + NOTIF_VOLUME.put("custom", 0); + foundInvalidSetting = true; + } else if (NOTIF_VOLUME.get("custom") > 100) { + NOTIF_VOLUME.put("custom", 100); + foundInvalidSetting = true; + } + if (VIEW_DISTANCE.get("custom") < 2300) { VIEW_DISTANCE.put("custom", 2300); foundInvalidSetting = true; @@ -3795,6 +3813,7 @@ public static synchronized void save(String preset) { Boolean.toString(OVERRIDE_AUDIO_SETTING_SETTING_ON.get(preset))); props.setProperty("sound_effect_combat1", Boolean.toString(SOUND_EFFECT_COMBAT1.get(preset))); props.setProperty("fix_sfx_delay", Boolean.toString(FIX_SFX_DELAY.get(preset))); + props.setProperty("notif_volume", Integer.toString(NOTIF_VOLUME.get(preset))); props.setProperty("sound_effect_advance", Boolean.toString(SOUND_EFFECT_ADVANCE.get(preset))); props.setProperty("sound_effect_anvil", Boolean.toString(SOUND_EFFECT_ANVIL.get(preset))); props.setProperty("sound_effect_chisel", Boolean.toString(SOUND_EFFECT_CHISEL.get(preset))); @@ -4887,6 +4906,26 @@ public static void setClientFoV(String fovValue) { } public static void setSfxVolume(String volumeLevel) { + setVolume( + SFX_VOLUME, + volumeLevel, + true, + "@cya@Volume of sound effects was changed to " + volumeLevel + "%"); + } + + public static void setNotifVolume(String volumeLevel) { + setVolume( + NOTIF_VOLUME, + volumeLevel, + false, + "@cya@Volume of notifications was changed to " + volumeLevel + "%"); + } + + private static void setVolume( + HashMap volumeSetting, + String volumeLevel, + boolean forMudClient, + String successMessage) { String outOfBoundsMessage = "@whi@Please use an @lre@integer@whi@ between 0 and 100 (default = 100)"; @@ -4899,10 +4938,15 @@ public static void setSfxVolume(String volumeLevel) { return; } - SFX_VOLUME.put(currentProfile, newVolume); - SoundEffects.adjustMudClientSfxVolume(); - Client.displayMessage( - "@cya@Volume of sound effects was changed to " + volumeLevel + "%", Client.CHAT_NONE); + volumeSetting.put(currentProfile, newVolume); + + if (forMudClient) { + SoundEffects.adjustMudClientSfxVolume(); + } else { + SoundEffects.adjustNotificationsVolume(); + } + + Client.displayMessage(successMessage, Client.CHAT_NONE); Launcher.getConfigWindow().synchronizeGuiValues(); } catch (Exception e) { diff --git a/src/Game/Client.java b/src/Game/Client.java index ffbfd514..3935eb97 100644 --- a/src/Game/Client.java +++ b/src/Game/Client.java @@ -958,6 +958,7 @@ public static void update() { // Set the mudclient volume if (!customSfxVolumeSet) { SoundEffects.adjustMudClientSfxVolume(); + SoundEffects.adjustNotificationsVolume(); customSfxVolumeSet = true; } @@ -2183,6 +2184,11 @@ private static String processClientCommand(String line) { Settings.setSfxVolume(commandArray[1]); } break; + case "notif_volume": + if (commandArray.length > 1) { + Settings.setNotifVolume(commandArray[1]); + } + break; case "overlayfont": if (commandArray.length > 1) { Settings.setOverlayFontStyle(commandArray[1]); diff --git a/src/Game/SoundEffects.java b/src/Game/SoundEffects.java index 46131d72..e3574eba 100644 --- a/src/Game/SoundEffects.java +++ b/src/Game/SoundEffects.java @@ -2,9 +2,11 @@ import Client.Launcher; import Client.Logger; +import Client.NotificationsHandler; import Client.Settings; import java.io.BufferedInputStream; import java.io.IOException; +import javax.sound.sampled.Clip; import javax.sound.sampled.FloatControl; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; @@ -219,4 +221,32 @@ public static void adjustSfxVolume(SourceDataLine sourceDataLine) { e.printStackTrace(); } } + + public static void adjustNotificationsVolume() { + Clip notifClip = NotificationsHandler.getNotificationSoundClip(); + Clip sadNotifClip = NotificationsHandler.getSadNotificationSoundClip(); + + if (notifClip == null || sadNotifClip == null) { + return; + } + + FloatControl notifControl = (FloatControl) notifClip.getControl(FloatControl.Type.MASTER_GAIN); + FloatControl sadNotifControl = + (FloatControl) sadNotifClip.getControl(FloatControl.Type.MASTER_GAIN); + + adjustClipVolume(notifControl); + adjustClipVolume(sadNotifControl); + } + + private static void adjustClipVolume(FloatControl gainControl) { + try { + float volumePercent = Settings.NOTIF_VOLUME.get(Settings.currentProfile); + float volumeInDecibels = 20f * (float) Math.log10(volumePercent / 100f); + + gainControl.setValue(volumeInDecibels); + } catch (Exception e) { + Logger.Error("Error adjusting the notifications volume"); + e.printStackTrace(); + } + } }