From 3c9060b662a193c0501d4d818c045e1bccb66958 Mon Sep 17 00:00:00 2001 From: Dragon Fire Date: Thu, 11 Jun 2020 17:49:03 -0400 Subject: [PATCH] Island Command --- README.md | 3 +- commands/games-mp/island.js | 111 ++++++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 commands/games-mp/island.js diff --git a/README.md b/README.md index 98324c1b..e1dc63a2 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ in the appropriate channel's topic to use it. ## Commands -Total: 473 +Total: 474 ### Utility: @@ -508,6 +508,7 @@ Total: 473 * **hangman:** Prevent a man from being hanged by guessing a word as fast as you can. * **horse-race:** Bet on the fastest horse in a 6-horse race. * **hunger-games:** Simulate a Hunger Games match with up to 24 tributes. +* **island:** Who will be the final two left on the island after a series of vote-kicks? * **jeopardy:** Answer a Jeopardy question. * **lottery:** Attempt to win the lottery with 6 numbers. * **mad-libs:** Choose words that fill in the blanks to create a crazy story! diff --git a/commands/games-mp/island.js b/commands/games-mp/island.js new file mode 100644 index 00000000..1f2a5d6f --- /dev/null +++ b/commands/games-mp/island.js @@ -0,0 +1,111 @@ +const Command = require('../../structures/Command'); +const { stripIndents } = require('common-tags'); +const Collection = require('@discordjs/collection'); +const { delay, awaitPlayers } = require('../../util/Util'); +const { SUCCESS_EMOJI_ID } = process.env; + +module.exports = class IslandCommand extends Command { + constructor(client) { + super(client, { + name: 'island', + group: 'games-mp', + memberName: 'island', + description: 'Who will be the final two left on the island after a series of vote-kicks?', + guildOnly: true, + args: [ + { + key: 'playersCount', + label: 'players', + prompt: 'How many players are you expecting to have?', + type: 'integer', + min: 3, + max: 20 + } + ] + }); + } + + async run(msg, { playersCount }) { + 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, { name: this.name }); + try { + const awaitedPlayers = await awaitPlayers(msg, playersCount, 3); + if (!awaitedPlayers) { + this.client.games.delete(msg.channel.id); + return msg.say('Game could not be started...'); + } + let turn = 0; + const players = new Collection(); + for (const player of awaitedPlayers) { + players.set(player, { + id: player, + user: await this.client.users.fetch(player) + }); + } + let lastTurnTimeout = false; + const playersLeft = new Set(...players.map(p => p.id)); + while (playersLeft.size > 2) { + ++turn; + await msg.say(stripIndents` + **Day ${turn}.** Who should be kicked off the island? + + You have **2 minutes** to make a decision before voting starts. + `); + await delay(120000);c + const choices = players.filter(player => playersLeft.has(player.id)); + const ids = choices.map(player => player.id); + await msg.say(stripIndents` + Alright, who do you want to kick off the island? You have 1 minute to vote. + + _Type the number of the player you want to kick._ + ${choices.map((player, i) => `**${i + 1}.** ${player.user.tag}`).join('\n')} + `); + const votes = new Collection(); + const voteFilter = res => { + if (!playersLeft.has(res.author.id)) return false; + const int = Number.parseInt(res.content, 10); + if (int >= 1 && int <= playersLeft.size) { + const currentVotes = votes.get(choices[int - 1]); + votes.set(ids[int - 1], { + votes: currentVotes ? currentVotes + 1 : 1, + id: ids[int - 1] + }); + res.react(SUCCESS_EMOJI_ID || '✅').catch(() => null); + return true; + } + return false; + }; + const vote = await msg.channel.awaitMessages(voteFilter, { + max: playersLeft.size, + time: 60000 + }); + if (!vote.size) { + if (lastTurnTimeout) { + await msg.say('Game ended due to inactivity.'); + break; + } else { + await msg.say('Come on guys, get in the game!'); + lastTurnTimeout = true; + continue; + } + } + const kicked = players.get(votes.sort((a, b) => b.votes - a.votes).first().id); + playersLeft.delete(kicked.id); + await msg.say(stripIndents` + **${kicked.user.tag}** will be kicked off the island. + + ${playersLeft.size > 2 ? '_Next round starts in 30 seconds.' : ''} + `); + if (playersLeft.size > 2) await delay(30000); + else break; + } + this.client.games.delete(msg.channel.id); + const winners = players.filter(player => playersLeft.has(player.id)); + return msg.say(`Congrats, ${winners.map(player => player.user.tag).join(' and ')}!`); + } catch (err) { + this.client.games.delete(msg.channel.id); + throw err; + } + } +}; diff --git a/package.json b/package.json index f9768c08..77f7a745 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "116.16.2", + "version": "116.17.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {