implemened game sound effects for notifs
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
using LightlessSync.LightlessConfiguration;
|
using LightlessSync.LightlessConfiguration;
|
||||||
using LightlessSync.LightlessConfiguration.Models;
|
using LightlessSync.LightlessConfiguration.Models;
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
@@ -6,6 +7,8 @@ using LightlessSync.UI;
|
|||||||
using LightlessSync.UI.Models;
|
using LightlessSync.UI.Models;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
||||||
namespace LightlessSync.Services;
|
namespace LightlessSync.Services;
|
||||||
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
|
public class LightlessNotificationService : DisposableMediatorSubscriberBase, IHostedService
|
||||||
{
|
{
|
||||||
@@ -48,7 +51,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
SoundEffectId = soundEffectId ?? NotificationSounds.GetDefaultSound(type)
|
SoundEffectId = soundEffectId ?? NotificationSounds.GetDefaultSound(type)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Play sound effect if specified
|
|
||||||
if (notification.SoundEffectId.HasValue)
|
if (notification.SoundEffectId.HasValue)
|
||||||
{
|
{
|
||||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
@@ -100,7 +102,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Play sound effect
|
|
||||||
if (notification.SoundEffectId.HasValue)
|
if (notification.SoundEffectId.HasValue)
|
||||||
{
|
{
|
||||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
@@ -140,7 +141,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
SoundEffectId = NotificationSounds.DownloadComplete
|
SoundEffectId = NotificationSounds.DownloadComplete
|
||||||
};
|
};
|
||||||
|
|
||||||
// Play sound effect
|
|
||||||
if (notification.SoundEffectId.HasValue)
|
if (notification.SoundEffectId.HasValue)
|
||||||
{
|
{
|
||||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
PlayNotificationSound(notification.SoundEffectId.Value);
|
||||||
@@ -188,7 +188,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
SoundEffectId = NotificationSounds.Error
|
SoundEffectId = NotificationSounds.Error
|
||||||
};
|
};
|
||||||
|
|
||||||
// Play sound effect
|
|
||||||
if (notification.SoundEffectId.HasValue)
|
if (notification.SoundEffectId.HasValue)
|
||||||
{
|
{
|
||||||
PlayNotificationSound(notification.SoundEffectId.Value);
|
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)
|
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 userDownloads = downloadStatus.Where(x => x.playerName != "Pair Queue").ToList();
|
||||||
|
|
||||||
var totalProgress = userDownloads.Count > 0 ? userDownloads.Average(x => x.progress) : 0f;
|
var totalProgress = userDownloads.Count > 0 ? userDownloads.Average(x => x.progress) : 0f;
|
||||||
@@ -207,13 +205,11 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
|
|
||||||
var message = "";
|
var message = "";
|
||||||
|
|
||||||
// Add queue status at the top if there are waiting items
|
|
||||||
if (queueWaiting > 0)
|
if (queueWaiting > 0)
|
||||||
{
|
{
|
||||||
message = $"Queue: {queueWaiting} waiting";
|
message = $"Queue: {queueWaiting} waiting";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add download progress if there are downloads
|
|
||||||
if (totalCount > 0)
|
if (totalCount > 0)
|
||||||
{
|
{
|
||||||
var progressMessage = $"Progress: {completedCount}/{totalCount} completed";
|
var progressMessage = $"Progress: {completedCount}/{totalCount} completed";
|
||||||
@@ -240,7 +236,6 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
message += string.IsNullOrEmpty(message) ? downloadLines : $"\n{downloadLines}";
|
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 allDownloadsCompleted = userDownloads.All(x => x.progress >= 1.0f) && userDownloads.Any();
|
||||||
|
|
||||||
var notification = new LightlessNotification
|
var notification = new LightlessNotification
|
||||||
@@ -259,6 +254,7 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
DismissPairDownloadNotification();
|
DismissPairDownloadNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DismissPairDownloadNotification()
|
public void DismissPairDownloadNotification()
|
||||||
{
|
{
|
||||||
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
|
Mediator.Publish(new LightlessNotificationDismissMessage("pair_download_progress"));
|
||||||
@@ -268,15 +264,15 @@ public class LightlessNotificationService : DisposableMediatorSubscriberBase, IH
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO: Implement proper sound playback
|
try
|
||||||
// The ChatGui.PlaySoundEffect method doesn't exist in the current Dalamud API
|
{
|
||||||
// For now, just log what sound would be played
|
UIGlobals.PlayChatSoundEffect(soundEffectId);
|
||||||
_logger.LogDebug("Would play notification sound effect {SoundId}", soundEffectId);
|
_logger.LogDebug("Played notification sound effect {SoundId} via ChatGui", soundEffectId);
|
||||||
|
}
|
||||||
// Future implementation options:
|
catch (Exception chatEx)
|
||||||
// 1. Use UIModule->PlaySound() with proper unsafe interop
|
{
|
||||||
// 2. Use game's sound system through SigScanner
|
_logger.LogWarning(chatEx, "Failed to play sound via ChatGui for ID {SoundId}", soundEffectId);
|
||||||
// 3. Wait for official Dalamud sound API
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,41 +1,63 @@
|
|||||||
using LightlessSync.LightlessConfiguration.Models;
|
using LightlessSync.LightlessConfiguration.Models;
|
||||||
|
|
||||||
namespace LightlessSync.UI.Models;
|
namespace LightlessSync.UI.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Common FFXIV sound effect IDs for notifications
|
/// Common FFXIV <se.#> sound effect IDs for notifications.
|
||||||
|
/// These correspond to the same sound IDs used in macros (1–16).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class NotificationSounds
|
public static class NotificationSounds
|
||||||
{
|
{
|
||||||
/// <summary>
|
// ─────────────────────────────────────────────
|
||||||
/// General notification sound (quest complete)
|
// Base <se.#> IDs (1–16)
|
||||||
/// </summary>
|
// https://ffxiv.consolegameswiki.com/wiki/Macros#Sound_Effects
|
||||||
public const uint Info = 37;
|
// ─────────────────────────────────────────────
|
||||||
|
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──────────────────────────────────────────
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Warning/alert sound (system error)
|
/// General notification sound (<se.2>)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Warning = 15;
|
public const uint Info = Se2;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error sound (action failed)
|
/// Warning/alert sound (<se.15>)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Error = 16;
|
public const uint Warning = Se15;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Success sound (level up)
|
/// Error sound (<se.16>)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Success = 25;
|
public const uint Error = Se16;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pair request sound (tell received)
|
/// Success sound (<se.14>)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint PairRequest = 13;
|
public const uint Success = Se14;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Download complete sound (item obtained)
|
/// Pair request sound (<se.13>, same as tell notification)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint DownloadComplete = 30;
|
public const uint PairRequest = Se13;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download complete sound (<se.10>, a clean sparkle tone)
|
||||||
|
/// </summary>
|
||||||
|
public const uint DownloadComplete = Se10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get default sound for notification type
|
/// Get default sound for notification type
|
||||||
|
|||||||
Reference in New Issue
Block a user