From 9eafcff5552c75d716976a5ae5ac923e5409fdb9 Mon Sep 17 00:00:00 2001 From: EvolutionX Date: Wed, 21 Sep 2022 11:04:49 +0530 Subject: [PATCH] feat: rps --- src/commands/games/rps.ts | 144 ++++++++++++++++++++++++++++++++++++++ src/index.ts | 11 ++- 2 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 src/commands/games/rps.ts diff --git a/src/commands/games/rps.ts b/src/commands/games/rps.ts new file mode 100644 index 0000000..093c692 --- /dev/null +++ b/src/commands/games/rps.ts @@ -0,0 +1,144 @@ +import { commandModule, CommandType } from "@sern/handler"; +import { + ActionRowBuilder, + ApplicationCommandOptionType, + ButtonBuilder, + ButtonInteraction, + ButtonStyle, + ComponentType, + User, +} from "discord.js"; +import { publish } from "../../plugins/publish.js"; +export default commandModule({ + type: CommandType.Slash, + plugins: [publish()], + description: "wanna win in rps?", + options: [ + { + name: "user", + description: "user you wanna play with", + type: ApplicationCommandOptionType.User, + required: false, + }, + ], + execute: async (context) => { + const opponent = + context.interaction.options.getUser("user") ?? context.client.user!; + + if (opponent.id === context.user.id) + return context.reply(`Can't play with yourself dumb dumb`); + + const buttons = ["🪨|Rock", "📄|Paper", "✂|Scissors"].map((s) => { + const [emoji, label] = s.split("|"); + return new ButtonBuilder() + .setCustomId(label.toLowerCase()) + .setEmoji(emoji) + .setLabel(label) + .setStyle(ButtonStyle.Secondary); + }); + + const row = new ActionRowBuilder(); + + let content = `${context.user} vs ${opponent}`; + + if (!opponent.bot) { + content += `\n\n> Waiting for ${context.user.username}\n> Waiting for ${opponent.username}`; + } + + const sent = await context.reply({ + content, + components: [row.setComponents(buttons)], + }); + + const collector = sent.createMessageComponentCollector({ + componentType: ComponentType.Button, + filter: (i) => [context.user.id, opponent.id].includes(i.user.id), + time: 60_000, + }); + + collector.on("ignore", async (i) => { + await i.reply({ + content: `Couldn't ignore you less`, + ephemeral: true, + }); + }); + + let opponentChoice: Choice; + let userChoice: Choice; + + const getResponses = (i: ButtonInteraction) => { + opponentChoice ??= ( + opponent.bot + ? ["rock", "paper", "scissors"][(3 * Math.random()) | 0] + : i.user.id === opponent.id + ? i.customId + : undefined + ) as Choice; + + userChoice ??= ( + i.user.id === context.user.id ? i.customId : undefined + ) as Choice; + return [userChoice, opponentChoice]; + }; + + const computeResults = () => { + content = + content.split("\n")[0] + + `\n\n> ${context.user.username} chose ${emoji[userChoice]}!` + + `\n> ${opponent.username} chose ${emoji[opponentChoice]}!\n\nResults: `; + + const win = (user: User) => (content += `${user} wins! GG 🥳`); + + switch (`${userChoice}-${opponentChoice}` as Possibilities) { + case "paper-rock": + case "rock-scissors": + case "scissors-paper": + return win(context.user); + case "paper-scissors": + case "scissors-rock": + case "rock-paper": + return win(opponent); + default: + return (content += `oof! There was a tie!`); + } + }; + + buttons.forEach((b) => b.setDisabled()); + + collector.on("collect", async (i) => { + collector.resetTimer(); + const choices = getResponses(i).filter(Boolean); + + if (!opponent.bot && choices.length !== 2) { + content = content.replace( + RegExp(`.+${i.user.username}`), + `> ${i.user.username} has chosen!` + ); + return void i.update(content); + } + collector.stop("finished"); + await i.update({ + content: computeResults(), + components: [row.setComponents(buttons)], + }); + }); + + collector.on("end", async (_, r) => { + if (r === "finished") return; + await context.interaction.editReply({ + content: "Time up!", + components: [row.setComponents(buttons)], + }); + }); + }, +}); + +type Choice = "rock" | "paper" | "scissors"; + +type Possibilities = `${Choice}-${Choice}`; + +const emoji: Record = { + rock: "🪨", + paper: "📄", + scissors: "✂", +}; diff --git a/src/index.ts b/src/index.ts index afce2b3..cfddf72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,13 +11,12 @@ const client = new Client({ GatewayIntentBits.MessageContent, ], partials: [Partials.GuildMember, Partials.GuildMember, Partials.Message], - sweepers : { - messages : { - interval : 43200, - lifetime: 21600 - } + sweepers: { + messages: { + interval: 43200, + lifetime: 21600, + }, }, - }); Sern.addExternal(process);