diff --git a/LightlessSync/Services/LightlessNotificationService.cs b/LightlessSync/Services/LightlessNotificationService.cs
index c926d34..1afd9a5 100644
--- a/LightlessSync/Services/LightlessNotificationService.cs
+++ b/LightlessSync/Services/LightlessNotificationService.cs
@@ -1,4 +1,5 @@
using Dalamud.Interface;
+using Dalamud.Plugin.Services;
using LightlessSync.LightlessConfiguration;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.Services.Mediator;
@@ -6,6 +7,8 @@ using LightlessSync.UI;
using LightlessSync.UI.Models;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using FFXIVClientStructs.FFXIV.Client.UI;
+
namespace LightlessSync.Services;
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
{
@@ -48,7 +51,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
SoundEffectId = soundEffectId ?? NotificationSounds.GetDefaultSound(type)
};
- // Play sound effect if specified
if (notification.SoundEffectId.HasValue)
{
PlayNotificationSound(notification.SoundEffectId.Value);
@@ -100,7 +102,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
}
};
- // Play sound effect
if (notification.SoundEffectId.HasValue)
{
PlayNotificationSound(notification.SoundEffectId.Value);
@@ -140,7 +141,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
SoundEffectId = NotificationSounds.DownloadComplete
};
- // Play sound effect
if (notification.SoundEffectId.HasValue)
{
PlayNotificationSound(notification.SoundEffectId.Value);
@@ -188,7 +188,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
SoundEffectId = NotificationSounds.Error
};
- // Play sound effect
if (notification.SoundEffectId.HasValue)
{
PlayNotificationSound(notification.SoundEffectId.Value);
@@ -198,7 +197,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
}
public void ShowPairDownloadNotification(List<(string playerName, float progress, string status)> downloadStatus, int queueWaiting = 0)
{
- // Filter out queue status from user downloads
var userDownloads = downloadStatus.Where(x => x.playerName != "Pair Queue").ToList();
var totalProgress = userDownloads.Count > 0 ? userDownloads.Average(x => x.progress) : 0f;
@@ -207,13 +205,11 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
var message = "";
- // Add queue status at the top if there are waiting items
if (queueWaiting > 0)
{
message = $"Queue: {queueWaiting} waiting";
}
- // Add download progress if there are downloads
if (totalCount > 0)
{
var progressMessage = $"Progress: {completedCount}/{totalCount} completed";
@@ -240,7 +236,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
message += string.IsNullOrEmpty(message) ? downloadLines : $"\n{downloadLines}";
}
- // Check if all downloads are completed
var allDownloadsCompleted = userDownloads.All(x => x.progress >= 1.0f) && userDownloads.Any();
var notification = new LightlessNotification
@@ -259,6 +254,7 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
DismissPairDownloadNotification();
}
}
+
public void DismissPairDownloadNotification()
{
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
@@ -268,15 +264,15 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
{
try
{
- // TODO: Implement proper sound playback
- // The ChatGui.PlaySoundEffect method doesn't exist in the current Dalamud API
- // For now, just log what sound would be played
- _logger.LogDebug("Would play notification sound effect {SoundId}", soundEffectId);
-
- // Future implementation options:
- // 1. Use UIModule->PlaySound() with proper unsafe interop
- // 2. Use game's sound system through SigScanner
- // 3. Wait for official Dalamud sound API
+ try
+ {
+ UIGlobals.PlayChatSoundEffect(soundEffectId);
+ _logger.LogDebug("Played notification sound effect {SoundId} via ChatGui", soundEffectId);
+ }
+ catch (Exception chatEx)
+ {
+ _logger.LogWarning(chatEx, "Failed to play sound via ChatGui for ID {SoundId}", soundEffectId);
+ }
}
catch (Exception ex)
{
diff --git a/LightlessSync/UI/Models/NotificationSounds.cs b/LightlessSync/UI/Models/NotificationSounds.cs
index 962263a..8b60532 100644
--- a/LightlessSync/UI/Models/NotificationSounds.cs
+++ b/LightlessSync/UI/Models/NotificationSounds.cs
@@ -1,42 +1,64 @@
-using LightlessSync.LightlessConfiguration.Models;
+using LightlessSync.LightlessConfiguration.Models;
namespace LightlessSync.UI.Models;
///
-/// Common FFXIV sound effect IDs for notifications
+/// Common FFXIV sound effect IDs for notifications.
+/// These correspond to the same sound IDs used in macros (1–16).
///
public static class NotificationSounds
{
+ // ─────────────────────────────────────────────
+ // Base IDs (1–16)
+ // https://ffxiv.consolegameswiki.com/wiki/Macros#Sound_Effects
+ // ─────────────────────────────────────────────
+ public const uint Se1 = 1; // Soft chime
+ public const uint Se2 = 2; // Higher chime
+ public const uint Se3 = 3; // Bell tone
+ public const uint Se4 = 4; // Harp tone
+ public const uint Se5 = 5; // Drum / percussion
+ public const uint Se6 = 6; // Mechanical click
+ public const uint Se7 = 7; // Metallic chime
+ public const uint Se8 = 8; // Wooden tone
+ public const uint Se9 = 9; // Wind / flute tone
+ public const uint Se10 = 10; // Magical sparkle
+ public const uint Se11 = 11; // Metallic ring
+ public const uint Se12 = 12; // Deep thud
+ public const uint Se13 = 13; // "Tell received" ping
+ public const uint Se14 = 14; // Success fanfare short
+ public const uint Se15 = 15; // System warning
+ public const uint Se16 = 16; // Error / failure──────────────────────────────────────────
+
///
- /// General notification sound (quest complete)
+ /// General notification sound ()
///
- public const uint Info = 37;
-
+ public const uint Info = Se2;
+
///
- /// Warning/alert sound (system error)
+ /// Warning/alert sound ()
///
- public const uint Warning = 15;
-
+ public const uint Warning = Se15;
+
///
- /// Error sound (action failed)
+ /// Error sound ()
///
- public const uint Error = 16;
-
+ public const uint Error = Se16;
+
///
- /// Success sound (level up)
+ /// Success sound ()
///
- public const uint Success = 25;
-
+ public const uint Success = Se14;
+
///
- /// Pair request sound (tell received)
+ /// Pair request sound (, same as tell notification)
///
- public const uint PairRequest = 13;
-
+ public const uint PairRequest = Se13;
+
///
- /// Download complete sound (item obtained)
+ /// Download complete sound (, a clean sparkle tone)
///
- public const uint DownloadComplete = 30;
-
+ public const uint DownloadComplete = Se10;
+
///
/// Get default sound for notification type
///