[Raid] Move format code to another class
This commit is contained in:
8
Cocotte/Modules/Raids/PlayerRole.cs
Normal file
8
Cocotte/Modules/Raids/PlayerRole.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Cocotte.Modules.Raids;
|
||||||
|
|
||||||
|
public enum PlayerRole
|
||||||
|
{
|
||||||
|
Dps,
|
||||||
|
Healer,
|
||||||
|
Tank
|
||||||
|
}
|
||||||
59
Cocotte/Modules/Raids/RaidFormatter.cs
Normal file
59
Cocotte/Modules/Raids/RaidFormatter.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using Cocotte.Options;
|
||||||
|
using Cocotte.Utils;
|
||||||
|
using Discord;
|
||||||
|
|
||||||
|
namespace Cocotte.Modules.Raids;
|
||||||
|
|
||||||
|
public class RaidFormatter
|
||||||
|
{
|
||||||
|
private readonly RolesOptions _rolesOptions;
|
||||||
|
|
||||||
|
public RaidFormatter(RolesOptions rolesOptions)
|
||||||
|
{
|
||||||
|
_rolesOptions = rolesOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string RoleToEmote(PlayerRole role) => role switch
|
||||||
|
{
|
||||||
|
PlayerRole.Dps => _rolesOptions.DpsEmote,
|
||||||
|
PlayerRole.Tank => _rolesOptions.TankEmote,
|
||||||
|
PlayerRole.Healer => _rolesOptions.HealerEmote,
|
||||||
|
_ => ":question:"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string FcFormat(int fc) => fc switch
|
||||||
|
{
|
||||||
|
< 1_000 => $"{fc}",
|
||||||
|
_ => $"{fc/1000}k"
|
||||||
|
};
|
||||||
|
|
||||||
|
public string FormatRosterPlayer(RosterPlayer player) => player.Substitue switch
|
||||||
|
{
|
||||||
|
false => $"{RoleToEmote(player.Role)} {player.Name} ({FcFormat(player.Fc)} FC)",
|
||||||
|
true => $"*{RoleToEmote(player.Role)} {player.Name} ({FcFormat(player.Fc)} FC)*"
|
||||||
|
};
|
||||||
|
|
||||||
|
public EmbedBuilder RaidEmbed(Raid raid)
|
||||||
|
{
|
||||||
|
EmbedFieldBuilder RosterEmbed(int rosterNumber, IEnumerable<RosterPlayer> players)
|
||||||
|
{
|
||||||
|
var rosterPlayers = players.ToList();
|
||||||
|
var nonSubstitute = rosterPlayers.Where(p => !p.Substitue);
|
||||||
|
var substitute = rosterPlayers.Where(p => p.Substitue);
|
||||||
|
|
||||||
|
var separatorLength = Math.Max(nonSubstitute.Select(p => p.Name.Length).Max(), substitute.Select(p => p.Name.Length).Max());
|
||||||
|
separatorLength = (int) ((separatorLength + 13) * 0.49); // Don't ask why, it just works
|
||||||
|
|
||||||
|
return new EmbedFieldBuilder()
|
||||||
|
.WithName($"Roster {rosterNumber}")
|
||||||
|
.WithValue($"{string.Join("\n", nonSubstitute.Select(FormatRosterPlayer))}\n{new string('━', separatorLength)}\n{string.Join("\n", substitute.Select(FormatRosterPlayer))}")
|
||||||
|
.WithIsInline(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EmbedBuilder()
|
||||||
|
.WithColor(Colors.CocotteBlue)
|
||||||
|
.WithTitle(":crossed_swords: Raid")
|
||||||
|
.WithDescription($"**Date:** {TimestampTag.FromDateTime(raid.DateTime, TimestampTagStyles.LongDateTime)}")
|
||||||
|
.WithFields(raid.Rosters.Select(r => RosterEmbed(r.Key, r)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Cocotte.Options;
|
||||||
using Cocotte.Utils;
|
using Cocotte.Utils;
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Interactions;
|
using Discord.Interactions;
|
||||||
@@ -14,11 +15,13 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
{
|
{
|
||||||
private readonly ILogger<RaidModule> _logger;
|
private readonly ILogger<RaidModule> _logger;
|
||||||
private readonly IRaidsRepository _raidsRepository;
|
private readonly IRaidsRepository _raidsRepository;
|
||||||
|
private readonly RaidFormatter _raidFormatter;
|
||||||
|
|
||||||
public RaidModule(ILogger<RaidModule> logger, IRaidsRepository raidsRepository)
|
public RaidModule(ILogger<RaidModule> logger, IRaidsRepository raidsRepository, RaidFormatter raidFormatter)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_raidsRepository = raidsRepository;
|
_raidsRepository = raidsRepository;
|
||||||
|
_raidFormatter = raidFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
[EnabledInDm(false)]
|
[EnabledInDm(false)]
|
||||||
@@ -48,14 +51,14 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
|
|
||||||
// Build the raid message
|
// Build the raid message
|
||||||
var raid = _raidsRepository[raidId];
|
var raid = _raidsRepository[raidId];
|
||||||
var embed = RaidEmbed(raid);
|
|
||||||
var components = RaidComponents(raidId);
|
var components = RaidComponents(raidId);
|
||||||
|
var embed = _raidFormatter.RaidEmbed(raid);
|
||||||
|
|
||||||
await ModifyOriginalResponseAsync(m =>
|
await ModifyOriginalResponseAsync(m =>
|
||||||
{
|
{
|
||||||
m.Content = "";
|
m.Content = "";
|
||||||
m.Embed = embed.Build();
|
|
||||||
m.Components = components.Build();
|
m.Components = components.Build();
|
||||||
|
m.Embed = embed.Build();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
if (!_raidsRepository.TryGetRaid(raidId, out var raid))
|
if (!_raidsRepository.TryGetRaid(raidId, out var raid))
|
||||||
{
|
{
|
||||||
await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build());
|
await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +77,10 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
if (!raid.AddPlayer(user.Id, user.DisplayName, PlayerRole.Dps, 10000))
|
if (!raid.AddPlayer(user.Id, user.DisplayName, PlayerRole.Dps, 10000))
|
||||||
{
|
{
|
||||||
await RespondAsync(ephemeral: true, embed: EmbedUtils.InfoEmbed("You're already registered for this raid").Build());
|
await RespondAsync(ephemeral: true, embed: EmbedUtils.InfoEmbed("You're already registered for this raid").Build());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("User {User} joined raid {Raid}", Context.User.Username, raid);
|
_logger.LogInformation("User {User} joined raid {Raid}", Context.User.Username, raid);
|
||||||
|
|
||||||
await UpdateRaidRosterEmbed(raid);
|
await UpdateRaidRosterEmbed(raid);
|
||||||
@@ -90,7 +93,7 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
if (!_raidsRepository.TryGetRaid(raidId, out var raid))
|
if (!_raidsRepository.TryGetRaid(raidId, out var raid))
|
||||||
{
|
{
|
||||||
await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build());
|
await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,10 +101,10 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
if (!raid.RemovePlayer(user.Id))
|
if (!raid.RemovePlayer(user.Id))
|
||||||
{
|
{
|
||||||
await RespondAsync(ephemeral: true, embed: EmbedUtils.WarningEmbed("You're not registered for this raid").Build());
|
await RespondAsync(ephemeral: true, embed: EmbedUtils.WarningEmbed("You're not registered for this raid").Build());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await UpdateRaidRosterEmbed(raid);
|
await UpdateRaidRosterEmbed(raid);
|
||||||
await RespondAsync(ephemeral: true, embed: EmbedUtils.SuccessEmbed("Successfully left the raid").Build());
|
await RespondAsync(ephemeral: true, embed: EmbedUtils.SuccessEmbed("Successfully left the raid").Build());
|
||||||
}
|
}
|
||||||
@@ -112,34 +115,10 @@ public class RaidModule : InteractionModuleBase<SocketInteractionContext>
|
|||||||
|
|
||||||
if (message is SocketUserMessage userMessage)
|
if (message is SocketUserMessage userMessage)
|
||||||
{
|
{
|
||||||
await userMessage.ModifyAsync(m => m.Embed = RaidEmbed(raid).Build());
|
await userMessage.ModifyAsync(m => m.Embed = _raidFormatter.RaidEmbed(raid).Build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EmbedBuilder RaidEmbed(Raid raid)
|
|
||||||
{
|
|
||||||
EmbedFieldBuilder RosterEmbed(int rosterNumber, IEnumerable<RosterPlayer> players)
|
|
||||||
{
|
|
||||||
var rosterPlayers = players.ToList();
|
|
||||||
var nonSubstitute = rosterPlayers.Where(p => !p.Substitue);
|
|
||||||
var substitute = rosterPlayers.Where(p => p.Substitue);
|
|
||||||
|
|
||||||
var separatorLength = Math.Max(nonSubstitute.Select(p => p.Name.Length).Max(), substitute.Select(p => p.Name.Length).Max());
|
|
||||||
separatorLength = (int) ((separatorLength + 13) * 0.49); // Don't ask why, it just works
|
|
||||||
|
|
||||||
return new EmbedFieldBuilder()
|
|
||||||
.WithName($"Roster {rosterNumber}")
|
|
||||||
.WithValue($"{string.Join("\n", nonSubstitute)}\n{new string('━', separatorLength)}\n{string.Join("\n", substitute)}")
|
|
||||||
.WithIsInline(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EmbedBuilder()
|
|
||||||
.WithColor(Colors.CocotteBlue)
|
|
||||||
.WithTitle(":crossed_swords: Raid")
|
|
||||||
.WithDescription($"**Date:** {TimestampTag.FromDateTime(raid.DateTime, TimestampTagStyles.LongDateTime)}")
|
|
||||||
.WithFields(raid.Rosters.Select(r => RosterEmbed(r.Key, r)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComponentBuilder RaidComponents(ulong raidId)
|
private ComponentBuilder RaidComponents(ulong raidId)
|
||||||
{
|
{
|
||||||
return new ComponentBuilder()
|
return new ComponentBuilder()
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
namespace Cocotte.Modules.Raids;
|
using Cocotte.Options;
|
||||||
|
|
||||||
|
namespace Cocotte.Modules.Raids;
|
||||||
|
|
||||||
public record RosterPlayer(ulong Id, string Name, PlayerRole Role, int Fc, bool Substitue = false)
|
public record RosterPlayer(ulong Id, string Name, PlayerRole Role, int Fc, bool Substitue = false)
|
||||||
{
|
{
|
||||||
public int RosterNumber { get; set; }
|
public int RosterNumber { get; set; }
|
||||||
|
|
||||||
private static string RoleToEmote(PlayerRole role) => role switch
|
|
||||||
{
|
|
||||||
PlayerRole.Dps => ":red_circle:",
|
|
||||||
PlayerRole.Tank => ":yellow_circle:",
|
|
||||||
PlayerRole.Healer => ":green_circle:",
|
|
||||||
_ => ":question:"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string FcFormat(int fc) => fc switch
|
|
||||||
{
|
|
||||||
< 1_000 => $"{fc}",
|
|
||||||
_ => $"{fc/1000}k"
|
|
||||||
};
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return (int) (Id % int.MaxValue);
|
return (int) (Id % int.MaxValue);
|
||||||
@@ -27,17 +15,4 @@ public record RosterPlayer(ulong Id, string Name, PlayerRole Role, int Fc, bool
|
|||||||
{
|
{
|
||||||
return other is not null && other.Id == Id;
|
return other is not null && other.Id == Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => Substitue switch
|
|
||||||
{
|
|
||||||
false => $"{RoleToEmote(Role)} {Name} ({FcFormat(Fc)} FC)",
|
|
||||||
true => $"*{RoleToEmote(Role)} {Name} ({FcFormat(Fc)} FC)*"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PlayerRole
|
|
||||||
{
|
|
||||||
Dps,
|
|
||||||
Healer,
|
|
||||||
Tank
|
|
||||||
}
|
}
|
||||||
8
Cocotte/Options/RolesOptions.cs
Normal file
8
Cocotte/Options/RolesOptions.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Cocotte.Options;
|
||||||
|
|
||||||
|
public class RolesOptions
|
||||||
|
{
|
||||||
|
public string DpsEmote { get; set; } = ":red_circle:";
|
||||||
|
public string TankEmote { get; set; } = ":yellow_circle:";
|
||||||
|
public string HealerEmote { get; set; } = ":green_circle:";
|
||||||
|
}
|
||||||
@@ -34,6 +34,10 @@ IHost host = Host.CreateDefaultBuilder(args)
|
|||||||
|
|
||||||
// Data
|
// Data
|
||||||
services.AddSingleton<IRaidsRepository, MemoryRaidRepository>();
|
services.AddSingleton<IRaidsRepository, MemoryRaidRepository>();
|
||||||
|
services.AddSingleton<RolesOptions>();
|
||||||
|
|
||||||
|
// Raids
|
||||||
|
services.AddSingleton<RaidFormatter>();
|
||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
services.AddSingleton<SharedCounter>();
|
services.AddSingleton<SharedCounter>();
|
||||||
|
|||||||
Reference in New Issue
Block a user