Files
nadekobot/src/NadekoBot/Modules/Games/HangmanCommands.cs
2021-09-06 21:34:53 +02:00

145 lines
5.9 KiB
C#

using Discord.Commands;
using NadekoBot.Extensions;
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Games.Common.Hangman;
using NadekoBot.Modules.Games.Services;
using NadekoBot.Modules.Games.Common.Hangman.Exceptions;
namespace NadekoBot.Modules.Games
{
public partial class Games
{
[Group]
public class HangmanCommands : NadekoSubmodule<GamesService>
{
private readonly DiscordSocketClient _client;
public HangmanCommands(DiscordSocketClient client)
{
_client = client;
}
[NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Hangmanlist()
{
await SendConfirmAsync(Format.Code(GetText(strs.hangman_types(Prefix)) + "\n" + string.Join("\n", _service.TermPool.Data.Keys)));
}
[NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Hangman([Leftover]string type = "random")
{
Hangman hm;
try
{
hm = new Hangman(type, _service.TermPool);
}
catch (TermNotFoundException)
{
return;
}
if (!_service.HangmanGames.TryAdd(ctx.Channel.Id, hm))
{
hm.Dispose();
await ReplyErrorLocalizedAsync(strs.hangman_running).ConfigureAwait(false);
return;
}
hm.OnGameEnded += Hm_OnGameEnded;
hm.OnGuessFailed += Hm_OnGuessFailed;
hm.OnGuessSucceeded += Hm_OnGuessSucceeded;
hm.OnLetterAlreadyUsed += Hm_OnLetterAlreadyUsed;
_client.MessageReceived += _client_MessageReceived;
try
{
await SendConfirmAsync(GetText(strs.hangman_game_started) + $" ({hm.TermType})",
hm.ScrambledWord + "\n" + hm.GetHangman())
.ConfigureAwait(false);
}
catch { }
await hm.EndedTask.ConfigureAwait(false);
_client.MessageReceived -= _client_MessageReceived;
_service.HangmanGames.TryRemove(ctx.Channel.Id, out _);
hm.Dispose();
Task _client_MessageReceived(SocketMessage msg)
{
var _ = Task.Run(() =>
{
if (ctx.Channel.Id == msg.Channel.Id && !msg.Author.IsBot)
return hm.Input(msg.Author.Id, msg.Author.ToString(), msg.Content);
else
return Task.CompletedTask;
});
return Task.CompletedTask;
}
}
Task Hm_OnGameEnded(Hangman game, string winner)
{
if (winner is null)
{
var loseEmbed = _eb.Create().WithTitle($"Hangman Game ({game.TermType}) - Ended")
.WithDescription(Format.Bold("You lose."))
.AddField("It was", game.Term.GetWord())
.WithFooter(string.Join(" ", game.PreviousGuesses))
.WithErrorColor();
if (Uri.IsWellFormedUriString(game.Term.ImageUrl, UriKind.Absolute))
loseEmbed.WithImageUrl(game.Term.ImageUrl);
return ctx.Channel.EmbedAsync(loseEmbed);
}
var winEmbed = _eb.Create().WithTitle($"Hangman Game ({game.TermType}) - Ended")
.WithDescription(Format.Bold($"{winner} Won."))
.AddField("It was", game.Term.GetWord())
.WithFooter(string.Join(" ", game.PreviousGuesses))
.WithOkColor();
if (Uri.IsWellFormedUriString(game.Term.ImageUrl, UriKind.Absolute))
winEmbed.WithImageUrl(game.Term.ImageUrl);
return ctx.Channel.EmbedAsync(winEmbed);
}
private Task Hm_OnLetterAlreadyUsed(Hangman game, string user, char guess)
{
return SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` has already been used. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
footer: string.Join(" ", game.PreviousGuesses));
}
private Task Hm_OnGuessSucceeded(Hangman game, string user, char guess)
{
return SendConfirmAsync($"Hangman Game ({game.TermType})", $"{user} guessed a letter `{guess}`!\n" + game.ScrambledWord + "\n" + game.GetHangman(),
footer: string.Join(" ", game.PreviousGuesses));
}
private Task Hm_OnGuessFailed(Hangman game, string user, char guess)
{
return SendErrorAsync($"Hangman Game ({game.TermType})", $"{user} Letter `{guess}` does not exist. You can guess again in 3 seconds.\n" + game.ScrambledWord + "\n" + game.GetHangman(),
footer: string.Join(" ", game.PreviousGuesses));
}
[NadekoCommand, Aliases]
[RequireContext(ContextType.Guild)]
public async Task HangmanStop()
{
if (_service.HangmanGames.TryRemove(ctx.Channel.Id, out var removed))
{
await removed.Stop().ConfigureAwait(false);
await ReplyConfirmLocalizedAsync(strs.hangman_stopped).ConfigureAwait(false);
}
}
}
}
}