Files
xiao/commands/games-mp/apples-to-apples.js
T
2021-03-13 13:10:47 -05:00

138 lines
4.6 KiB
JavaScript

const Command = require('../../structures/Command');
const { escapeMarkdown } = require('discord.js');
const { stripIndents } = require('common-tags');
const { shuffle } = require('../../util/Util');
const Game = require('../../structures/cards-against-humanity/Game');
const { greenCards, redCards } = require('../../assets/json/apples-to-apples');
module.exports = class ApplesToApplesCommand extends Command {
constructor(client) {
super(client, {
name: 'apples-to-apples',
aliases: ['a2a'],
group: 'games-mp',
memberName: 'apples-to-apples',
description: 'Compete to see who can come up with the best card to match an adjective.',
guildOnly: true,
clientPermissions: ['ADD_REACTIONS', 'READ_MESSAGE_HISTORY'],
credit: [
{
name: 'Mattel',
url: 'https://www.mattel.com/en-us',
reason: 'Original "Apples to Apples" Game, Card Data',
reasonURL: 'https://www.mattelgames.com/games/en-us/family/apples-apples'
},
{
name: 'JSON Against Humanity',
url: 'https://www.crhallberg.com/cah/',
reason: 'Card Data'
}
],
args: [
{
key: 'maxPts',
label: 'awesome points',
prompt: 'What amount of awesome points should determine the winner?',
type: 'integer',
max: 20,
min: 1
},
{
key: 'bot',
prompt: 'Do you want me to play as well?',
type: 'boolean'
}
]
});
}
async run(msg, { maxPts, bot }) {
const current = this.client.games.get(msg.channel.id);
if (current) return msg.reply(`Please wait until the current game of \`${current.name}\` is finished.`);
this.client.games.set(msg.channel.id,
new Game(this.client, this.name, msg.channel, redCards, greenCards, 'Green'));
const game = this.client.games.get(msg.channel.id);
try {
const awaitedPlayers = await game.awaitPlayers(msg, bot);
if (!awaitedPlayers) {
this.client.games.delete(msg.channel.id);
return msg.say('Game could not be started...');
}
game.createJoinLeaveCollector(msg.channel, game);
while (!game.winner) {
const czar = game.changeCzar();
for (const player of game.players.values()) {
if (player.id === czar.id) continue;
if (player.kickable) game.kick(player);
}
if (game.players.size < 3) {
await msg.say('Oh... It looks like everyone left...');
break;
}
const black = game.blackDeck.draw();
await msg.say(stripIndents`
The card czar will be ${czar.user}!
The Green Card is: **${escapeMarkdown(black.text)}**
Sending DMs...
`);
const chosenCards = [];
const turns = await Promise.all(game.players.map(player => player.turn(black, chosenCards)));
const extra = turns.reduce((a, b) => a + b);
if (!chosenCards.length) {
await msg.say('Hmm... No one even tried.');
continue;
}
const cards = shuffle(chosenCards);
await msg.say(stripIndents`
${czar.user}, which card${black.pick > 1 ? 's' : ''} do you pick?
**Green Card:** ${escapeMarkdown(black.text)}
${cards.map((card, i) => `**${i + 1}.** ${card.cards.join(' | ')}`).join('\n')}
`);
const filter = res => {
if (res.author.id !== czar.user.id) return false;
if (!/^[0-9]+$/g.test(res.content)) return false;
if (!cards[Number.parseInt(res.content, 10) - 1]) return false;
return true;
};
const chosen = await msg.channel.awaitMessages(filter, {
max: 1,
time: 120000
});
if (!chosen.size) {
await msg.say('Hmm... No one wins. Dealing back cards...');
for (const pick of cards) {
for (const card of pick.cards) {
if (!game.players.has(pick.id)) continue;
game.players.get(pick.id).hand.add(card);
}
}
game.czar.strikes++;
continue;
}
const player = game.players.get(cards[Number.parseInt(chosen.first().content, 10) - 1].id);
if (!player) {
await msg.say('Oh no, I think that player left! No awesome points will be awarded...');
continue;
}
player.points += 1 + extra;
if (player.points >= maxPts) {
game.winner = player.user;
} else {
const addS = player.points > 1 ? 's' : '';
await msg.say(`Nice, ${player.user}! You now have **${player.points}** awesome point${addS}!`);
}
}
game.stopJoinLeaveCollector();
this.client.games.delete(msg.channel.id);
if (!game.winner) return msg.say('See you next time!');
return msg.say(`And the winner is... ${game.winner}! Great job!`);
} catch (err) {
game.stopJoinLeaveCollector();
this.client.games.delete(msg.channel.id);
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
};