feat: rps (#18)

This commit is contained in:
Jacob Nguyen
2022-09-21 01:59:14 -05:00
committed by GitHub
2 changed files with 149 additions and 6 deletions

144
src/commands/games/rps.ts Normal file
View File

@@ -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<ButtonBuilder>();
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<Choice, string> = {
rock: "🪨",
paper: "📄",
scissors: "✂",
};

View File

@@ -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);