diff --git a/Cocotte/Modules/Ping/PingModule.cs b/Cocotte/Modules/Ping/PingModule.cs index 2f82eaf..2f60acf 100644 --- a/Cocotte/Modules/Ping/PingModule.cs +++ b/Cocotte/Modules/Ping/PingModule.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; using Cocotte.Services; +using Cocotte.Utils; using Discord; using Discord.Interactions; using Discord.WebSocket; @@ -122,6 +123,32 @@ public class PingModule : InteractionModuleBase } } + [SlashCommand("emote", "Test sending an emote")] + public async Task SendEmote(string emoteText) + { + if (Emote.TryParse(emoteText, out var emote)) + { + await RespondAsync($"{emote}/{emoteText}: `{emoteText}/{emote}`"); + } + else + { + await RespondAsync(embed: EmbedUtils.ErrorEmbed("Couldn't parse the emote").Build()); + } + } + + [SlashCommand("emoji", "Test sending an emoji")] + public async Task SendEmoji(string emojiText) + { + if (Emoji.TryParse(emojiText, out var emoji)) + { + await RespondAsync($"{emoji}/{emojiText}: `{emojiText}/{emoji}`"); + } + else + { + await RespondAsync(embed: EmbedUtils.ErrorEmbed("Couldn't parse the emoji").Build()); + } + } + [SlashCommand("test-button", "Test buttons components")] public async Task TestButton() { diff --git a/Cocotte/Modules/Raids/IPlayerInfosRepository.cs b/Cocotte/Modules/Raids/IPlayerInfosRepository.cs index 4f86b93..a0f5923 100644 --- a/Cocotte/Modules/Raids/IPlayerInfosRepository.cs +++ b/Cocotte/Modules/Raids/IPlayerInfosRepository.cs @@ -5,5 +5,5 @@ namespace Cocotte.Modules.Raids; public interface IPlayerInfosRepository { bool TryGetPlayerInfo(ulong playerId, [MaybeNullWhen(false)] out PlayerInfo playerInfo); - void UpdatePlayerInfo(PlayerInfo playerInfo); + void UpdatePlayerInfo(ulong id, Action updater); } \ No newline at end of file diff --git a/Cocotte/Modules/Raids/MemoryPlayerInfosRepository.cs b/Cocotte/Modules/Raids/MemoryPlayerInfosRepository.cs index 3068ada..1e0f204 100644 --- a/Cocotte/Modules/Raids/MemoryPlayerInfosRepository.cs +++ b/Cocotte/Modules/Raids/MemoryPlayerInfosRepository.cs @@ -16,8 +16,18 @@ public class MemoryPlayerInfosRepository : IPlayerInfosRepository return _playerInfos.TryGetValue(playerId, out playerInfo); } - public void UpdatePlayerInfo(PlayerInfo playerInfo) + public void UpdatePlayerInfo(ulong id, Action updater) { - _playerInfos[playerInfo.Id] = playerInfo; + if (_playerInfos.TryGetValue(id, out var playerInfo)) + { + updater(playerInfo); + } + else + { + playerInfo = new PlayerInfo(id, 0); + updater(playerInfo); + + _playerInfos[playerInfo.Id] = playerInfo; + } } } \ No newline at end of file diff --git a/Cocotte/Modules/Raids/PlayerInfo.cs b/Cocotte/Modules/Raids/PlayerInfo.cs index cd7cb5e..9b20346 100644 --- a/Cocotte/Modules/Raids/PlayerInfo.cs +++ b/Cocotte/Modules/Raids/PlayerInfo.cs @@ -5,12 +5,13 @@ public class PlayerInfo public static TimeSpan FcUpdateInterval { get; } = TimeSpan.FromDays(3); public ulong Id { get; } + public PlayerRole PreferredRole { get; set; } = PlayerRole.Dps; - private readonly uint _fc; + private uint _fc; public uint Fc { get => _fc; - init + set { _fc = value; _lastFcUpdate = DateTime.Today; @@ -19,7 +20,7 @@ public class PlayerInfo public bool IsFcUpdateRequired => DateTime.Today - _lastFcUpdate > FcUpdateInterval; - private readonly DateTime _lastFcUpdate; + private DateTime _lastFcUpdate; public PlayerInfo(ulong id, uint fc) { diff --git a/Cocotte/Modules/Raids/RaidFormatter.cs b/Cocotte/Modules/Raids/RaidFormatter.cs index b53db5c..67a5f47 100644 --- a/Cocotte/Modules/Raids/RaidFormatter.cs +++ b/Cocotte/Modules/Raids/RaidFormatter.cs @@ -13,12 +13,12 @@ public class RaidFormatter _rolesOptions = rolesOptions; } - public string RoleToEmote(PlayerRole role) => role switch + public IEmote RoleToEmote(PlayerRole role) => role switch { - PlayerRole.Dps => _rolesOptions.DpsEmote, - PlayerRole.Tank => _rolesOptions.TankEmote, - PlayerRole.Healer => _rolesOptions.HealerEmote, - _ => ":question:" + PlayerRole.Dps => _rolesOptions.DpsEmote.ToEmote(), + PlayerRole.Tank => _rolesOptions.TankEmote.ToEmote(), + PlayerRole.Healer => _rolesOptions.HealerEmote.ToEmote(), + _ => ":question:".ToEmote() }; public static string FcFormat(uint fc) => fc switch diff --git a/Cocotte/Modules/Raids/RaidModule.cs b/Cocotte/Modules/Raids/RaidModule.cs index 32654c9..b318395 100644 --- a/Cocotte/Modules/Raids/RaidModule.cs +++ b/Cocotte/Modules/Raids/RaidModule.cs @@ -125,7 +125,10 @@ public class RaidModule : InteractionModuleBase if (_registerManager.RegisteringPlayers.TryGetValue((raidId, playerId), out var rosterPlayer)) { - _registerManager.RegisteringPlayers[(raidId, playerId)] = rosterPlayer with {Role = selectedRole}; + _registerManager.RegisteringPlayers[(raidId, playerId)] = rosterPlayer with { Role = selectedRole }; + + // Also update preferred role + _playerInfos.UpdatePlayerInfo(playerId, p => p.PreferredRole = selectedRole); await RespondAsync(); } @@ -210,7 +213,7 @@ public class RaidModule : InteractionModuleBase return; } - _playerInfos.UpdatePlayerInfo(new PlayerInfo(playerId, fc)); + _playerInfos.UpdatePlayerInfo(playerId, p => p.Fc = fc); await RegisterPlayer(raidId, rosterPlayer with { Fc = fc }); } @@ -316,15 +319,17 @@ public class RaidModule : InteractionModuleBase private ComponentBuilder PlayerRoleComponent(Raid raid, IGuildUser user) { var select = new SelectMenuBuilder() - .WithPlaceholder(PlayerRole.Dps.ToString()) .WithCustomId($"raid player_select_role:{raid.Id}:{user.Id}") .WithMinValues(1) .WithMaxValues(1); + // Preselect preferred role + var preferredRole = _playerInfos.TryGetPlayerInfo(user.Id, out var playerInfo) ? playerInfo.PreferredRole : PlayerRole.Dps; + foreach (var role in Enum.GetValues()) { - // TODO add emote - select.AddOption(role.ToString(), role.ToString()); + var roleText = role.ToString(); + select.AddOption(roleText, roleText, emote: _raidFormatter.RoleToEmote(role), isDefault: role == preferredRole); } return new ComponentBuilder() diff --git a/Cocotte/Utils/EmoteUtils.cs b/Cocotte/Utils/EmoteUtils.cs new file mode 100644 index 0000000..83807ea --- /dev/null +++ b/Cocotte/Utils/EmoteUtils.cs @@ -0,0 +1,16 @@ +using Discord; + +namespace Cocotte.Utils; + +public static class EmoteUtils +{ + public static IEmote ToEmote(this string emoteText) + { + if (Emote.TryParse(emoteText, out var emote)) + { + return emote; + } + + return Emoji.Parse(emoteText); + } +} \ No newline at end of file